00001
00015 #include <stdlib.h>
00016 #include <stdio.h>
00017 #include <errno.h>
00018 #include <ctype.h>
00019 #include <time.h>
00020
00021 #include "gridlabd.h"
00022 #include "../tape/tape.h"
00023 #include "../tape/histogram.h"
00024 #include "tape_file.h"
00025
00026 int csv_data_only = 0;
00027 int csv_keep_clean = 0;
00028 EXPORT void set_csv_data_only()
00029 {
00030 csv_data_only = 1;
00031 }
00032 EXPORT void set_csv_keep_clean()
00033 {
00034 csv_keep_clean = 1;
00035 }
00036
00037
00038
00039
00040 EXPORT int open_player(struct player *my, char *fname, char *flags)
00041 {
00042
00043 char *ff = fname;
00044
00045
00046 my->fp = (strcmp(fname,"-")==0?stdin:(ff?fopen(ff,flags):NULL));
00047 if (my->fp==NULL)
00048 {
00049 sprintf(my->lasterr, "player file %s: %s", fname, strerror(errno));
00050 my->status = TS_DONE;
00051 return 0;
00052 }
00053 else
00054 {
00055 my->loopnum = my->loop;
00056 my->status=TS_OPEN;
00057 my->type = FT_FILE;
00058 return 1;
00059 }
00060 }
00061
00062 EXPORT char *read_player(struct player *my,char *buffer,unsigned int size)
00063 {
00064 return fgets(buffer,size,my->fp);
00065 }
00066
00067 EXPORT int rewind_player(struct player *my)
00068 {
00069 return fseek(my->fp,SEEK_SET,0);
00070 }
00071
00072 EXPORT void close_player(struct player *my)
00073 {
00074 fclose(my->fp);
00075 my->status = TS_DONE;
00076 }
00077
00078
00079
00080
00081 #define MAPSIZE(N) ((N-1)/8+1)
00082 #define SET(X,B) ((X)[(B)/8]|=(1<<((B)&7)))
00083 #define ISSET(X,B) (((X)[(B)/8]&(1<<((B)&7)))==(1<<((B)&7)))
00084 char *file=NULL;
00085 int linenum=0;
00086 static int setmap(char *spec, unsigned char *map, int size)
00087 {
00088 char *p=spec;
00089 int last=-1;
00090 memset(map,0,MAPSIZE(size));
00091 while (*p!='\0')
00092 {
00093 if (*p=='*')
00094 {
00095 int i;
00096 for (i=0;i<size;i++)
00097 SET(map,i);
00098 p++;
00099 }
00100 else if (isdigit(*p))
00101 {
00102 int i=atoi(p);
00103 if (last<0)
00104
00105 SET(map,i);
00106 else if (i>last)
00107 do {
00108 SET(map,last);
00109 } while (++last<=i);
00110 else
00111 {
00112
00113 do {
00114 SET(map,last);
00115 } while (++last<size);
00116 last=0;
00117 do {
00118 SET(map,last);
00119 } while (++last<=i);
00120 }
00121 last = i;
00122 while (isdigit(*p)) p++;
00123 }
00124 else if (*p=='-')
00125 {
00126 p++;
00127 }
00128 else if (*p==';')
00129 {
00130 last = -1;
00131 p++;
00132 }
00133 else
00134 return 0;
00135 }
00136 return 1;
00137 }
00138 static unsigned char *hourmap(char *spec)
00139 {
00140 static unsigned char hours[MAPSIZE(24)];
00141 if (setmap(spec,hours,24))
00142 return hours;
00143 else
00144 return NULL;
00145 }
00146 static unsigned char *daymap(char *spec)
00147 {
00148 static unsigned char days[MAPSIZE(31)];
00149 if (setmap(spec,days,31))
00150 return days;
00151 else
00152 return NULL;
00153 }
00154 static unsigned char *monthmap(char *spec)
00155 {
00156 static unsigned char months[MAPSIZE(12)];
00157 if (setmap(spec,months,12))
00158 return months;
00159 else
00160 return NULL;
00161 }
00162 static unsigned char *weekdaymap(char *spec)
00163 {
00164 static unsigned char weekdays[MAPSIZE(7)];
00165 if (setmap(spec,weekdays,7))
00166 return weekdays;
00167 else
00168 return NULL;
00169 }
00170
00171 EXPORT int open_shaper(struct shaper *my, char *fname, char *flags)
00172 {
00173 char line[1024], group[256]="(unnamed)";
00174 float sum=0, load=0, peak=0;
00175 float scale[12][31][7][24];
00176
00177 char *ff = fname;
00178
00179
00180 memset(scale,0,sizeof(scale));
00181 linenum=0;
00182 file=fname;
00183
00184
00185 my->fp = (strcmp(fname,"-")==0?stdin:(ff?fopen(ff,flags):NULL));
00186 if (my->fp==NULL)
00187 {
00188 sprintf(my->lasterr, "shaper file %s: %s", fname, strerror(errno));
00189 goto Error;
00190 }
00191 my->status=TS_OPEN;
00192 my->type = FT_FILE;
00193
00194 my->step = 3600;
00195 my->interval = 24;
00196 memset(my->shape,0,sizeof(my->shape));
00197
00198 while (fgets(line,sizeof(line),my->fp)!=NULL)
00199 {
00200 unsigned char *hours, *days, *months, *weekdays;
00201 char min[256],hour[256],day[256],month[256],weekday[256],value[32];
00202 char *p=line;
00203 linenum++;
00204 while (isspace(*p)) p++;
00205 if (p[0]=='\0' || p[0]=='#') continue;
00206 if (strcmp(group,"")!=0 && (isdigit(p[0]) || p[0]=='*'))
00207 {
00208 int h, d, m, w;
00209 if (sscanf(line,"%s %s %s %s %[^,],%[^,\n]",min,hour,day,month,weekday,value)<6)
00210 {
00211 sprintf(my->lasterr, "%s(%d) : shape '%s' missing specification '%s'", file, linenum, group, line);
00212 goto Error;
00213 }
00214
00215 if (min[0]!='*')
00216 {
00217 sprintf(my->lasterr, "%s(%d) : minutes are ignored in '%s'", file, linenum, line);
00218 goto Error;
00219 }
00220 hours=hourmap(hour);
00221 if (hours==NULL)
00222 {
00223 sprintf(my->lasterr,"%s(%d): hours in '%s' not valid", file, linenum, line);
00224 goto Error;
00225 }
00226 days=daymap(day);
00227 if (days==NULL)
00228 {
00229 sprintf(my->lasterr,"%s(%d): days in '%s' not valid", file, linenum, line);
00230 goto Error;
00231 }
00232 months=monthmap(month);
00233 if (months==NULL)
00234 {
00235 sprintf(my->lasterr,"%s(%d): months in '%s' not valid", file, linenum, line);
00236 goto Error;
00237 }
00238 weekdays=weekdaymap(weekday);
00239 if (weekdays==NULL)
00240 {
00241 sprintf(my->lasterr,"%s(%d): weekdays in '%s' not valid", file, linenum, line);
00242 goto Error;
00243 }
00244 load = (float)atof(value);
00245 for (m=0; m<12; m++)
00246 {
00247 if (!ISSET(months,m)) continue;
00248 for (w=0; w<7; w++)
00249 {
00250 if (!ISSET(weekdays,w)) continue;
00251 for (d=0; d<31; d++)
00252 {
00253 if (!ISSET(days,d)) continue;
00254 for (h=0; h<24; h++)
00255 {
00256 if (!ISSET(hours,h)) continue;
00257 scale[m][d][w][h] = -load;
00258 }
00259 }
00260 }
00261 }
00262 sum += load;
00263 if (load>peak) peak=load;
00264 }
00265 else if (p[0]=='}')
00266 {
00267 int h, d, m, w;
00268 my->scale = peak/255/sum;
00269
00270 for (m=0; m<12; m++)
00271 {
00272 for (w=0; w<7; w++)
00273 {
00274 for (d=0; d<31; d++)
00275 {
00276 for (h=0; h<24; h++)
00277 {
00278 if (scale[m][d][w][h]<0)
00279 my->shape[m][d][w][h] = (unsigned char)(-scale[m][d][w][h] / peak * 255 +0.5);
00280 }
00281 }
00282 }
00283 }
00284 strcpy(group,"");
00285 }
00286 else if (sscanf(p,"%s {",group)==1)
00287 {
00288 sum=0;
00289 }
00290 else
00291 {
00292
00293 fprintf(stderr, "%s(%d) : shape specification '%s' is not valid", file, linenum, line);
00294 }
00295 }
00296 fclose(my->fp);
00297 my->fp=NULL;
00298 my->status = TS_OPEN;
00299 return 1;
00300 Error:
00301 if (my->fp)
00302 {
00303 fclose(my->fp);
00304 my->fp = NULL;
00305 }
00306 my->status = TS_ERROR;
00307 return 0;
00308 }
00309
00310 EXPORT char *read_shaper(struct shaper *my,char *buffer,unsigned int size)
00311 {
00312 return NULL;
00313 }
00314
00315 EXPORT int rewind_shaper(struct shaper *my)
00316 {
00317 return -1;
00318 }
00319
00320 EXPORT void close_shaper(struct shaper *my)
00321 {
00322 }
00323
00324
00325
00326
00327 EXPORT int open_recorder(struct recorder *my, char *fname, char *flags)
00328 {
00329 time_t now=time(NULL);
00330 OBJECT *obj=OBJECTHDR(my);
00331
00332 my->fp = (strcmp(fname,"-")==0?stdout:fopen(fname,flags));
00333 if (my->fp==NULL)
00334 {
00335
00336 fprintf(stderr, "recorder file %s: %s", fname, strerror(errno));
00337 my->status = TS_DONE;
00338 return 0;
00339 }
00340 my->type = FT_FILE;
00341 my->last.ts = TS_ZERO;
00342 my->status=TS_OPEN;
00343 my->samples=0;
00344
00345 if (!csv_data_only)
00346 {
00347
00348 fprintf(my->fp,"# file...... %s\n", my->file.get_string());
00349 fprintf(my->fp,"# date...... %s", asctime(localtime(&now)));
00350 #ifdef WIN32
00351 fprintf(my->fp,"# user...... %s\n", getenv("USERNAME"));
00352 fprintf(my->fp,"# host...... %s\n", getenv("MACHINENAME"));
00353 #else
00354 fprintf(my->fp,"# user...... %s\n", getenv("USER"));
00355 fprintf(my->fp,"# host...... %s\n", getenv("HOST"));
00356 #endif
00357 if(obj->parent){
00358 fprintf(my->fp,"# target.... %s %d\n", obj->parent->oclass->name, obj->parent->id);
00359 }
00360 fprintf(my->fp,"# trigger... %s\n", my->trigger[0]=='\0'?"(none)":my->trigger.get_string());
00361 fprintf(my->fp,"# interval.. %d\n", my->interval);
00362 fprintf(my->fp,"# limit..... %d\n", my->limit);
00363 fprintf(my->fp,"# timestamp,%s\n", my->property.get_string());
00364 }
00365
00366 return 1;
00367 }
00368
00369 EXPORT int write_recorder(struct recorder *my, char *timestamp, char *value)
00370 {
00371 int count = fprintf(my->fp,"%s,%s\n", timestamp, value);
00372 if (csv_keep_clean) fflush(my->fp);
00373 return count;
00374 }
00375
00376 EXPORT void close_recorder(struct recorder *my)
00377 {
00378 if (my->fp)
00379 {
00380 if (!csv_data_only) fprintf(my->fp,"# end of tape\n");
00381 fclose(my->fp);
00382 my->fp = NULL;
00383
00384 }
00385 }
00386
00387
00388
00389
00390 EXPORT int open_histogram(histogram *my, char *fname, char *flags)
00391 {
00392 time_t now=time(NULL);
00393 OBJECT *obj=OBJECTHDR(my);
00394
00395 my->fp = (strcmp(fname,"-")==0?stdout:fopen(fname,"w"));
00396 if (my->fp==NULL)
00397 {
00398
00399 fprintf(stderr, "histogram file %s: %s", fname, strerror(errno));
00400 return 0;
00401 }
00402 my->type = FT_FILE;
00403 my->t_count = TS_ZERO;
00404 my->t_sample = TS_ZERO;
00405
00406 if (!csv_data_only)
00407 {
00408
00409 fprintf(my->fp,"# file...... %s\n", my->fname.get_string());
00410 fprintf(my->fp,"# date...... %s", asctime(localtime(&now)));
00411 #ifdef WIN32
00412 fprintf(my->fp,"# user...... %s\n", getenv("USERNAME"));
00413 fprintf(my->fp,"# host...... %s\n", getenv("MACHINENAME"));
00414 #else
00415 fprintf(my->fp,"# user...... %s\n", getenv("USER"));
00416 fprintf(my->fp,"# host...... %s\n", getenv("HOST"));
00417 #endif
00418 if(obj->parent != NULL){
00419 fprintf(my->fp,"# target.... %s %d\n", obj->parent->oclass->name, obj->parent->id);
00420 } else {
00421 fprintf(my->fp,"# group.... %s\n", my->group.get_string());
00422 }
00423
00424 fprintf(my->fp,"# counting interval.. %f\n", my->counting_interval);
00425 fprintf(my->fp,"# sampling interval.. %f\n", my->sampling_interval);
00426 fprintf(my->fp,"# limit..... %d\n", my->limit);
00427 if(my->bins[0] != 0){
00428 fprintf(my->fp,"# timestamp,%s\n", my->bins.get_string());
00429 } else {
00430 int i = 0;
00431 for(i = 0; i < my->bin_count; ++i){
00432 fprintf(my->fp,"%s%f..%f%s",(my->bin_list[i].low_inc ? "[" : "("), my->bin_list[i].low_val, my->bin_list[i].high_val, (my->bin_list[i].high_inc ? "]" : ")"));
00433 if(i+1 < my->bin_count){
00434 fprintf(my->fp,",");
00435 }
00436 }
00437 fprintf(my->fp, "\n");
00438 }
00439 }
00440
00441 return 1;
00442 }
00443
00444 EXPORT int write_histogram(histogram *my, char *timestamp, char *value)
00445 {
00446 int count = fprintf(my->fp,"%s,%s\n", timestamp, value);
00447 if (csv_keep_clean) fflush(my->fp);
00448 return count;
00449 }
00450
00451 EXPORT void close_histogram(histogram *my)
00452 {
00453 if (my->fp)
00454 {
00455 fprintf(my->fp,"# end of tape\n");
00456 fclose(my->fp);
00457 my->fp = NULL;
00458
00459
00460
00461 }
00462 }
00463
00464
00465
00466
00467 EXPORT int open_collector(struct collector *my, char *fname, char *flags)
00468 {
00469 unsigned int count=0;
00470 time_t now=time(NULL);
00471
00472 my->fp = (strcmp(fname,"-")==0?stdout:fopen(fname,flags));
00473 if (my->fp==NULL)
00474 {
00475
00476 fprintf(stderr, "collector file %s: %s", fname, strerror(errno));
00477 my->status = TS_DONE;
00478 return 0;
00479 }
00480 my->last.ts = TS_ZERO;
00481 my->status=TS_OPEN;
00482 my->type = FT_FILE;
00483 my->samples=0;
00484
00485 if (!csv_data_only)
00486 {
00487
00488 count += fprintf(my->fp,"# file...... %s\n", my->file.get_string());
00489 count += fprintf(my->fp,"# date...... %s", asctime(localtime(&now)));
00490 #ifdef WIN32
00491 count += fprintf(my->fp,"# user...... %s\n", getenv("USERNAME"));
00492 count += fprintf(my->fp,"# host...... %s\n", getenv("MACHINENAME"));
00493 #else
00494 count += fprintf(my->fp,"# user...... %s\n", getenv("USER"));
00495 count += fprintf(my->fp,"# host...... %s\n", getenv("HOST"));
00496 #endif
00497 count += fprintf(my->fp,"# group..... %s\n", my->group.get_string());
00498 count += fprintf(my->fp,"# trigger... %s\n", my->trigger[0]=='\0'?"(none)":my->trigger.get_string());
00499 count += fprintf(my->fp,"# interval.. %d\n", my->interval);
00500 count += fprintf(my->fp,"# limit..... %d\n", my->limit);
00501 count += fprintf(my->fp,"# property.. timestamp,%s\n", my->property.get_string());
00502 }
00503
00504 return 1;
00505 }
00506
00507 EXPORT int write_collector(struct collector *my, char *timestamp, char *value)
00508 {
00509 int count = fprintf(my->fp,"%s,%s\n", timestamp, value);
00510 if (csv_keep_clean) fflush(my->fp);
00511 return count;
00512 }
00513
00514 EXPORT void close_collector(struct collector *my)
00515 {
00516 if (my->fp)
00517 {
00518 if (!csv_data_only) fprintf(my->fp,"# end of tape\n");
00519 fclose(my->fp);
00520 }
00521 my->fp = 0;
00522 }
00523