00001
00035 #include <stdlib.h>
00036 #include <stdio.h>
00037 #include <errno.h>
00038 #include <ctype.h>
00039 #include "gridlabd.h"
00040 #include "object.h"
00041 #include "aggregate.h"
00042
00043 #include "tape.h"
00044 #include "file.h"
00045 #include "odbc.h"
00046
00047
00048 CLASS *shaper_class = NULL;
00049 static OBJECT *last_shaper = NULL;
00050
00051 EXPORT int create_shaper(OBJECT **obj, OBJECT *parent)
00052 {
00053 *obj = gl_create_object(shaper_class,sizeof(struct shaper));
00054 if (*obj!=NULL)
00055 {
00056 struct shaper *my = OBJECTDATA(*obj,struct shaper);
00057 last_shaper = *obj;
00058 gl_set_parent(*obj,parent);
00059 strcpy(my->file,"");
00060 strcpy(my->filetype,"txt");
00061 strcpy(my->property,"");
00062 strcpy(my->group,"");
00063 my->loopnum = 0;
00064 my->status = TS_INIT;
00065 my->targets = NULL;
00066 memset(my->shape,0,sizeof(my->shape));
00067 my->scale = 0.0;
00068 my->magnitude = 1.0;
00069 my->step = 3600;
00070 my->interval = 24;
00071 my->events = 0;
00072 return 1;
00073 }
00074 return 0;
00075 }
00076
00077 static int shaper_open(OBJECT *obj)
00078 {
00079 char32 type="file";
00080 char1024 fname="";
00081 char32 flags="r";
00082 struct shaper *my = OBJECTDATA(obj,struct shaper);
00083
00084
00085 if (sscanf(my->file,"%32[^:]:%1024[^:]:%[^:]",type,fname,flags)==1)
00086 {
00087
00088 strcpy(fname,my->file);
00089 strcpy(type,"file");
00090 }
00091
00092
00093 if (strcmp(fname,"")==0)
00094
00095
00096 sprintf(fname,"%s-%d.%s",obj->parent->oclass->name,obj->parent->id, my->filetype);
00097
00098
00099 my->ops = get_ftable(type)->shaper;
00100 if(my->ops == NULL)
00101 return 0;
00102 return my->ops->open(my, fname, flags);
00103 }
00104
00105 static void rewind_shaper(struct shaper *my)
00106 {
00107 my->ops->rewind(my);
00108 }
00109
00110 static void close_shaper(struct shaper *my)
00111 {
00112 my->ops->close(my);
00113 }
00114
00115 static TIMESTAMP shaper_read(OBJECT *obj, TIMESTAMP t0, unsigned int n)
00116 {
00117 struct shaper *my = OBJECTDATA(obj,struct shaper);
00118 TIMESTAMP t1 = TS_NEVER;
00119
00120
00121 time_t t = (time_t)(t0/TS_SECOND);
00122 struct tm *tval = localtime(&t);
00123
00124
00125 if (my->events<=0)
00126 {
00127
00128 my->targets[n].value = my->magnitude * my->shape[tval->tm_mon][tval->tm_mday][tval->tm_wday][tval->tm_hour] * my->scale;
00129
00130
00131 t1 = my->targets[n].ts = ((t0 / my->step) + 1)*my->step;
00132 }
00133 else
00134 {
00135
00136 my->targets[n].value += my->shape[tval->tm_mon][tval->tm_mday][tval->tm_wday][tval->tm_hour] * my->scale * my->events;
00137
00138
00140 my->targets[n].ts = t0 + (TIMESTAMP)gl_random_uniform(0,my->step);
00141 }
00142
00143 return my->targets[n].ts;
00144 }
00145
00146 static TIMESTAMP shaper_update(OBJECT *obj, TIMESTAMP t0, unsigned int n)
00147 {
00148 struct shaper *my = OBJECTDATA(obj,struct shaper);
00149 TIMESTAMP t1 = TS_NEVER;
00150 if (my->events<=0)
00151 {
00152
00153 *(my->targets[n].addr) = my->targets[n].value;
00154 }
00155 else if (*(my->targets[n].addr)==0 && gl_random_bernoulli(my->targets[n].value)==1)
00156 {
00157 double event_size = gl_random_uniform(0,1);
00158
00159
00160 *(my->targets[n].addr) = my->magnitude;
00161
00162
00163 t1 = my->targets[n].ts = t0 + (TIMESTAMP)(event_size*my->step*my->interval/my->magnitude);
00164 my->targets[n].value-=event_size;
00165 }
00166 else if (*(my->targets[n].addr)!=0 && t0==my->targets[n].ts)
00167 {
00168
00169 t1 = shaper_read(obj,t0,n);
00170
00171
00172 *(my->targets[n].addr) = 0;
00173 }
00174 return t1;
00175 }
00176
00177 EXPORT TIMESTAMP sync_shaper(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
00178 {
00179 struct shaper *my = OBJECTDATA(obj,struct shaper);
00180 TIMESTAMP t1 = TS_NEVER;
00181 if (my->status==TS_INIT)
00182 shaper_open(obj);
00183 if (my->status==TS_OPEN)
00184 {
00185
00186 if (my->targets==NULL && my->group[0]!='\0')
00187 {
00188 FINDLIST *object_list = gl_find_objects(FL_GROUP,my->group);
00189 OBJECT *item=NULL;
00190 int n=0;
00191 if (object_list==NULL || object_list->hit_count<=0)
00192 {
00193 gl_warning("shaper group '%s' is empty", my->group);
00194 my->status=TS_DONE;
00195 return TS_NEVER;
00196 }
00197 my->n_targets = object_list->hit_count;
00198 my->targets = (SHAPERTARGET*)gl_malloc(sizeof(SHAPERTARGET*)*my->n_targets);
00199 memset(my->targets,0,sizeof(SHAPERTARGET*)*my->n_targets);
00200 if (my->targets==NULL)
00201 {
00202 gl_error("shaper memory allocation failed!");
00203 my->status=TS_DONE;
00204 return TS_NEVER;
00205 }
00206 for ( ;(item=gl_find_next(object_list,item))!=NULL; n++)
00207 {
00208 PROPERTY *prop=gl_get_property(item,my->property);
00209 if (prop!=NULL)
00210 {
00211 if (prop->ptype==PT_double)
00212 {
00213 TIMESTAMP tn;
00214
00215
00216 my->targets[n].addr = (double*)(GETADDR(item,prop));
00217
00218
00219 tn = shaper_read(obj,t0,n);
00220 if (tn<t1) t1=tn;
00221 }
00222 else
00223 gl_warning("object %s:%d property %s is not a double", item->oclass->name,item->id, prop->name);
00224 }
00225 }
00226 }
00227
00228
00229 if (my->targets!=NULL)
00230 {
00231 unsigned int n;
00232 for (n=0; n<my->n_targets; n++)
00233 {
00234 TIMESTAMP tn = TS_NEVER;
00235
00236
00237 if (my->targets[n].ts==t0)
00238 {
00239
00240 tn = shaper_update(obj,t0,n);
00241
00242
00243 if (tn==TS_NEVER)
00244 tn = shaper_read(obj,t0,n);
00245 }
00246
00247
00248 else if (my->targets[n].ts<t1)
00249 tn = my->targets[n].ts;
00250
00251
00252 if (tn<t1) t1=tn;
00253 }
00254 }
00255 }
00256 obj->clock = t0;
00257 return t1!=TS_NEVER?-t1:TS_NEVER;
00258 }
00259