tape_file/tape_file.cpp

Go to the documentation of this file.
00001 
00014 #include <stdlib.h>
00015 #include <stdio.h>
00016 #include <errno.h>
00017 #include <ctype.h>
00018 #include <time.h>
00019 
00020 #include "gridlabd.h"
00021 #include "../tape/tape.h"
00022 #include "tape_file.h"
00023 
00024 /*******************************************************************
00025  * players 
00026  */
00027 EXPORT int open_player(struct player *my, char *fname, char *flags)
00028 {
00029     //char *ff = gl_findfile(fname,NULL,FF_READ);
00030     char *ff = fname;
00031 
00032     /* "-" means stdin */
00033     my->fp = (strcmp(fname,"-")==0?stdin:(ff?fopen(ff,flags):NULL));
00034     if (my->fp==NULL)
00035     {
00036         //gl_error(
00037         fprintf(stderr, "player file %s: %s", fname, strerror(errno));
00038         my->status = TS_DONE;
00039         return 0;
00040     }
00041     else
00042     {
00043         my->loopnum = my->loop;
00044         my->status=TS_OPEN;
00045         my->type = FT_FILE;
00046         return 1;
00047     }
00048 }
00049 
00050 EXPORT char *read_player(struct player *my,char *buffer,unsigned int size)
00051 {
00052     return fgets(buffer,size,my->fp);
00053 }
00054 
00055 EXPORT int rewind_player(struct player *my)
00056 {
00057     return fseek(my->fp,SEEK_SET,0);
00058 }
00059 
00060 EXPORT void close_player(struct player *my)
00061 {
00062 }
00063 
00064 /*******************************************************************
00065  * shape generators 
00066  */
00067 #define MAPSIZE(N) ((N-1)/8+1)
00068 #define SET(X,B) ((X)[(B)/8]|=(1<<((B)&7)))
00069 #define ISSET(X,B) (((X)[(B)/8]&(1<<((B)&7)))==(1<<((B)&7)))
00070 char *file=NULL;
00071 int linenum=0;
00072 static void setmap(char *spec, unsigned char *map, int size)
00073 {
00074     char *p=spec;
00075     int last=-1;
00076     memset(map,0,MAPSIZE(size));
00077     while (*p!='\0')
00078     {
00079         if (*p=='*')
00080         {
00081             int i;
00082             for (i=0;i<size;i++) 
00083                 SET(map,i); 
00084             p++;
00085         }
00086         else if (isdigit(*p))
00087         {
00088             int i=atoi(p);
00089             if (last<0)
00090             /* no spanning */
00091                 SET(map,i);
00092             else if (i>last) /* span to i */
00093                 do { 
00094                     SET(map,last); 
00095                 } while (++last<=i);
00096             else
00097             {
00098                 /* span to i w/wrap around */
00099                 do { 
00100                     SET(map,last); 
00101                 } while (++last<size);
00102                 last=0;
00103                 do { 
00104                     SET(map,last); 
00105                 } while (++last<=i);
00106             }
00107             last = i;
00108             while (isdigit(*p)) p++;
00109         }
00110         else if (*p=='-')
00111         {   /* spanning enabled */
00112             p++;
00113         }
00114         else if (*p==';')
00115         {   /* spanning disabled */
00116             last = -1;
00117             p++;
00118         }
00119     }
00120 }
00121 static unsigned char *hourmap(char *spec)
00122 {
00123     static unsigned char hours[MAPSIZE(24)];
00124     setmap(spec,hours,24);
00125     return hours;
00126 }
00127 static unsigned char *daymap(char *spec)
00128 {
00129     static unsigned char days[MAPSIZE(31)];
00130     setmap(spec,days,31);
00131     return days;
00132 }
00133 static unsigned char *monthmap(char *spec)
00134 {
00135     static unsigned char months[MAPSIZE(12)];
00136     setmap(spec,months,12);
00137     return months;
00138 }
00139 static unsigned char *weekdaymap(char *spec)
00140 {
00141     static unsigned char weekdays[MAPSIZE(7)];
00142     setmap(spec,weekdays,7);
00143     return weekdays;
00144 }
00145 
00146 EXPORT int open_shaper(struct shaper *my, char *fname, char *flags)
00147 {
00148     char line[1024], group[256]="(unnamed)";
00149     float sum=0, load=0, peak=0;
00150     float scale[12][31][7][24];
00151     //char *ff = gl_findfile(fname,NULL,FF_READ);
00152     char *ff = fname;
00153 
00154     /* clear everything */
00155     memset(scale,0,sizeof(scale));
00156     linenum=0; 
00157     file=fname;
00158 
00159     /* "-" means stdin */
00160     my->fp = (strcmp(fname,"-")==0?stdin:(ff?fopen(ff,flags):NULL));
00161     if (my->fp==NULL)
00162     {
00163         //gl_error(
00164         fprintf(stderr, "shaper file %s: %s", fname, strerror(errno));
00165         my->status = TS_DONE;
00166         return 0;
00167     }
00168     my->status=TS_OPEN;
00169     my->type = FT_FILE;
00170     /* TODO: these should be read from the shape file, or better yet, inferred from it */
00171     my->step = 3600; /* default interval step is one hour */
00172     my->interval = 24; /* default unint shape integrated over one day */
00173     memset(my->shape,0,sizeof(my->shape));
00174     /* load the file into the shape */
00175     while (fgets(line,sizeof(line),my->fp)!=NULL)
00176     {
00177         unsigned char *hours, *days, *months, *weekdays;
00178         char min[256],hour[256],day[256],month[256],weekday[256],value[32];
00179         char *p=line;
00180         linenum++;
00181         while (isspace(*p)) p++;
00182         if (p[0]=='\0' || p[0]=='#') continue;
00183         if (strcmp(group,"")!=0 && (isdigit(p[0]) || p[0]=='*'))
00184         {   /* shape value */
00185             int h, d, m, w;
00186             if (sscanf(line,"%s %s %s %s %[^,],%[^,\n]",min,hour,day,month,weekday,value)<6)
00187             {
00188                 //gl_error
00189                 fprintf(stderr, "%s(%d) : shape '%s' has specification '%s'", file, linenum, group, line);
00190                 continue;
00191             }
00192             /* minutes are ignored right now */
00193             if (min[0]!='*') //gl_warning
00194                 fprintf(stdout, "%s(%d) : minutes are ignored in '%s'", file, linenum, line);
00195             hours=hourmap(hour);
00196             days=daymap(day);
00197             months=monthmap(month);
00198             weekdays=weekdaymap(weekday);
00199             load = (float)atof(value);
00200             for (m=0; m<12; m++)
00201             {
00202                 if (!ISSET(months,m)) continue;
00203                 for (w=0; w<7; w++)
00204                 {
00205                     if (!ISSET(weekdays,w)) continue;
00206                     for (d=0; d<31; d++)
00207                     {
00208                         if (!ISSET(days,d)) continue;
00209                         for (h=0; h<24; h++)
00210                         {
00211                             if (!ISSET(hours,h)) continue;
00212                             scale[m][d][w][h] = -load; /* negative indicates unscaled value */
00213                         }
00214                     }
00215                 }
00216             }
00217             sum += load; /* integrate over shape */
00218             if (load>peak) peak=load; /* keep the highest load in the shape (that's going to be 255) */
00219         }
00220         else if (p[0]=='}')
00221         {   /* end shape group */
00222             int h, d, m, w;
00223             my->scale = peak/255/sum;
00224             /* rescale group */
00225             for (m=0; m<12; m++)
00226             {
00227                 for (w=0; w<7; w++)
00228                 {
00229                     for (d=0; d<31; d++)
00230                     {
00231                         for (h=0; h<24; h++)
00232                         {
00233                             if (scale[m][d][w][h]<0)
00234                                 my->shape[m][d][w][h] = (unsigned char)(-scale[m][d][w][h] / peak * 255 +0.5); /* negative removes scaled value indicator */
00235                         }
00236                     }
00237                 }
00238             }
00239             strcpy(group,"");
00240         }
00241         else if (sscanf(p,"%s {",group)==1)
00242         {   /* new shape group */
00243             sum=0;
00244         }
00245         else
00246         {   /* syntax error */
00247             //gl_error(
00248             fprintf(stderr, "%s(%d) : shape specification '%s' is not valid", file, linenum, line);
00249         }
00250     }
00251     return 1;
00252 }
00253 
00254 EXPORT char *read_shaper(struct shaper *my,char *buffer,unsigned int size)
00255 {
00256     return fgets(buffer,size,my->fp);
00257 }
00258 
00259 EXPORT int rewind_shaper(struct shaper *my)
00260 {
00261     return fseek(my->fp,SEEK_SET,0);
00262 }
00263 
00264 EXPORT void close_shaper(struct shaper *my)
00265 {
00266 }
00267 
00268 /*******************************************************************
00269  * recorders 
00270  */
00271 EXPORT int open_recorder(struct recorder *my, char *fname, char *flags)
00272 {
00273     time_t now=time(NULL);
00274     OBJECT *obj=OBJECTHDR(my);
00275     
00276     my->fp = (strcmp(fname,"-")==0?stdout:fopen(fname,flags));
00277     if (my->fp==NULL)
00278     {
00279         //gl_error(
00280         fprintf(stderr, "recorder file %s: %s", fname, strerror(errno));
00281         my->status = TS_DONE;
00282         return 0;
00283     }
00284     my->type = FT_FILE;
00285     my->last.ts = TS_ZERO;
00286     my->status=TS_OPEN;
00287     my->samples=0;
00288 
00289     /* put useful header information in file first */
00290     fprintf(my->fp,"# file...... %s\n", my->file);
00291     fprintf(my->fp,"# date...... %s", asctime(localtime(&now)));
00292 #ifdef WIN32
00293     fprintf(my->fp,"# user...... %s\n", getenv("USERNAME"));
00294     fprintf(my->fp,"# host...... %s\n", getenv("MACHINENAME"));
00295 #else
00296     fprintf(my->fp,"# user...... %s\n", getenv("USER"));
00297     fprintf(my->fp,"# host...... %s\n", getenv("HOST"));
00298 #endif
00299     fprintf(my->fp,"# target.... %s %d\n", obj->parent->oclass->name, obj->parent->id);
00300     fprintf(my->fp,"# trigger... %s\n", my->trigger[0]=='\0'?"(none)":my->trigger);
00301     fprintf(my->fp,"# interval.. %d\n", my->interval);
00302     fprintf(my->fp,"# limit..... %d\n", my->limit);
00303     fprintf(my->fp,"# timestamp,%s\n", my->property);
00304 
00305     return 1;
00306 }
00307 
00308 EXPORT int write_recorder(struct recorder *my, char *timestamp, char *value)
00309 { 
00310     return fprintf(my->fp,"%s,%s\n", timestamp, value);
00311 }
00312 
00313 EXPORT void close_recorder(struct recorder *my)
00314 {
00315     fprintf(my->fp,"# end of tape\n");
00316     fclose(my->fp);
00317 }
00318 
00319 /*******************************************************************
00320  * collectors 
00321  */
00322 EXPORT int open_collector(struct collector *my, char *fname, char *flags)
00323 {
00324     unsigned int count=0;
00325     time_t now=time(NULL);
00326 
00327     my->fp = (strcmp(fname,"-")==0?stdout:fopen(fname,flags));
00328     if (my->fp==NULL)
00329     {
00330         //gl_error(
00331         fprintf(stderr, "collector file %s: %s", fname, strerror(errno));
00332         my->status = TS_DONE;
00333         return 0;
00334     }
00335     my->last.ts = TS_ZERO;
00336     my->status=TS_OPEN;
00337     my->type = FT_FILE;
00338     my->samples=0;
00339 
00340     /* put useful header information in file first */
00341     count += fprintf(my->fp,"# file...... %s\n", my->file);
00342     count += fprintf(my->fp,"# date...... %s", asctime(localtime(&now)));
00343 #ifdef WIN32
00344     count += fprintf(my->fp,"# user...... %s\n", getenv("USERNAME"));
00345     count += fprintf(my->fp,"# host...... %s\n", getenv("MACHINENAME"));
00346 #else
00347     count += fprintf(my->fp,"# user...... %s\n", getenv("USER"));
00348     count += fprintf(my->fp,"# host...... %s\n", getenv("HOST"));
00349 #endif
00350     count += fprintf(my->fp,"# group..... %s\n", my->group);
00351     count += fprintf(my->fp,"# trigger... %s\n", my->trigger[0]=='\0'?"(none)":my->trigger);
00352     count += fprintf(my->fp,"# interval.. %d\n", my->interval);
00353     count += fprintf(my->fp,"# limit..... %d\n", my->limit);
00354     count += fprintf(my->fp,"# property.. timestamp,%s\n", my->property);
00355 
00356     return count;
00357 }
00358 
00359 EXPORT int write_collector(struct collector *my, char *timestamp, char *value)
00360 {
00361     return fprintf(my->fp,"%s,%s\n", timestamp, value);
00362 }
00363 
00364 EXPORT void close_collector(struct collector *my)
00365 {
00366     fprintf(my->fp,"# end of tape\n");
00367     fclose(my->fp);
00368 
00369 }
00370 

GridLAB-DTM Version 1.0
An open-source project initiated by the US Department of Energy