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