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