tape_memory/tape_memory.cpp

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

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