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 CLASS *player_class = NULL;
00048 static OBJECT *last_player = NULL;
00049
00050 EXPORT int create_player(OBJECT **obj, OBJECT *parent)
00051 {
00052 *obj = gl_create_object(player_class);
00053 if (*obj!=NULL)
00054 {
00055 struct player *my = OBJECTDATA(*obj,struct player);
00056 last_player = *obj;
00057 gl_set_parent(*obj,parent);
00058 strcpy(my->file,"");
00059 strcpy(my->filetype,"txt");
00060 strcpy(my->property,"(undefined)");
00061 my->next.ts = TS_ZERO;
00062 strcpy(my->next.value,"");
00063 my->loopnum = 0;
00064 my->loop = 0;
00065 my->status = TS_INIT;
00066 my->target = gl_get_property(*obj,my->property);
00067 return 1;
00068 }
00069 return 0;
00070 }
00071
00072 static int player_open(OBJECT *obj)
00073 {
00074 char32 type="file";
00075 char1024 fname="";
00076 char32 flags="r";
00077 struct player *my = OBJECTDATA(obj,struct player);
00078
00079
00080 if (sscanf(my->file,"%32[^:]:%1024[^:]:%[^:]",type,fname,flags)==1)
00081 {
00082
00083 strcpy(fname,my->file);
00084 strcpy(type,"file");
00085 }
00086
00087
00088 if (strcmp(fname,"")==0)
00089
00090
00091 sprintf(fname,"%s-%d.%s",obj->parent->oclass->name,obj->parent->id, my->filetype);
00092
00093
00094 my->ops = get_ftable(type)->player;
00095 if(my->ops == NULL)
00096 return 0;
00097 else return (my->ops->open)(my, fname, flags);
00098 }
00099
00100 static void rewind_player(struct player *my)
00101 {
00102 (*my->ops->rewind)(my);
00103 }
00104
00105 static void close_player(struct player *my)
00106 {
00107 (my->ops->close)(my);
00108 }
00109
00110 static void trim(char *str, char *to){
00111 int i = 0, j = 0;
00112 if(str == 0)
00113 return;
00114 while(str[i] != 0 && isspace(str[i])){
00115 ++i;
00116 }
00117 while(str[i] != 0){
00118 to[j] = str[i];
00119 ++j;
00120 ++i;
00121 }
00122 --j;
00123 while(j > 0 && isspace(to[j])){
00124 to[j] = 0;
00125 --j;
00126 }
00127 }
00128
00129 static TIMESTAMP player_read(OBJECT *obj)
00130 {
00131 char buffer[64];
00132 char timebuf[64], valbuf[64], tbuf[64];
00133 int Y,m,d,H,M,S;
00134 struct player *my = OBJECTDATA(obj,struct player);
00135 char unit[2];
00136 TIMESTAMP t1;
00137 char *result=NULL;
00138 char32 value;
00139 int voff=0;
00140 Retry:
00141 result = my->ops->read(my, buffer, sizeof(buffer));
00142
00143 memset(timebuf, 0, 64);
00144 memset(valbuf, 0, 64);
00145 memset(tbuf, 0, 64);
00146 memset(value, 0, 32);
00147 if (result==NULL)
00148 {
00149 if (my->loopnum>0)
00150 {
00151 rewind_player(my);
00152 my->loopnum--;
00153 goto Retry;
00154 }
00155 else {
00156 close_player(my);
00157 my->status=TS_DONE;
00158 my->next.ts = TS_NEVER;
00159 goto Done;
00160 }
00161 }
00162 if (result[0]=='#' || result[0]=='\n')
00163 goto Retry;
00164
00165 if(sscanf(result, "%[^,],%[^\n\r]", tbuf, valbuf) == 2){
00166 trim(tbuf, timebuf);
00167 trim(valbuf, value);
00168 if (sscanf(timebuf,"%d-%d-%d %d:%d:%d",&Y,&m,&d,&H,&M,&S)==6)
00169 {
00170
00171 DATETIME dt;
00172 dt.year = Y;
00173 dt.month = m;
00174 dt.day = d;
00175 dt.hour = H;
00176 dt.minute = M;
00177 dt.second = S;
00178 dt.tz[0] = 0;
00179 t1 = (TIMESTAMP)gl_mktime(&dt);
00180 if (t1!=TS_INVALID && my->loop==my->loopnum){
00181 my->next.ts = t1;
00182 while(value[voff] == ' '){
00183 ++voff;
00184 }
00185 strcpy(my->next.value, value+voff);
00186 }
00187 }
00188 else if (sscanf(timebuf,"%" FMT_INT64 "d%1s", &t1, unit)==2)
00189 {
00190 {
00191 int64 scale=1;
00192 switch(unit[0]) {
00193 case 's': scale=TS_SECOND; break;
00194 case 'm': scale=60*TS_SECOND; break;
00195 case 'h': scale=3600*TS_SECOND; break;
00196 case 'd': scale=86400*TS_SECOND; break;
00197 default: break;
00198 }
00199 t1 *= scale;
00200 if (result[0]=='+'){
00201 my->next.ts += t1;
00202 while(value[voff] == ' '){
00203 ++voff;
00204 }
00205 strcpy(my->next.value, value+voff);
00206 } else if (my->loop==my->loopnum){
00207 my->next.ts = t1;
00208 while(value[voff] == ' '){
00209 ++voff;
00210 }
00211 strcpy(my->next.value, value+voff);
00212 }
00213 }
00214 }
00215 else if (sscanf(timebuf,"%" FMT_INT64 "d", &t1)==1)
00216 {
00217 if (my->loop==my->loopnum) {
00218 my->next.ts = t1;
00219 while(value[voff] == ' '){
00220 ++voff;
00221 }
00222 strcpy(my->next.value, value+voff);
00223 }
00224 }
00225 else
00226 {
00227 gl_warning("player was unable to parse timestamp \'%s\'", result);
00228 }
00229 } else {
00230 gl_warning("player was unable to split input string \'%s\'", result);
00231 }
00232
00233 Done:
00234 return my->next.ts;
00235 }
00236
00237 EXPORT TIMESTAMP sync_player(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
00238 {
00239 struct player *my = OBJECTDATA(obj,struct player);
00240 TIMESTAMP t1 = (TS_OPEN == my->status) ? my->next.ts : TS_NEVER;
00241 if (my->status==TS_INIT){
00242
00243
00244 if (my->target==NULL && obj->parent == NULL)
00245 my->target = gl_get_property(obj,"value");
00246
00247 if(player_open(obj) == 0)
00248 {
00249 gl_error("sync_player: Unable to open player file '%s' for object '%s'", my->file, obj->name?obj->name:"(anon)");
00250 }
00251 else
00252 {
00253 t1 = player_read(obj);
00254 }
00255 }
00256 while (my->status==TS_OPEN && t1<=t0)
00257 {
00258 if (my->target==NULL)
00259 my->target = gl_get_property(obj->parent,my->property);
00260 if (my->target==NULL){
00261 gl_error("sync_player: Unable to find property \"%s\" in object %s", my->property, obj->name?obj->name:"(anon)");
00262 my->status = TS_ERROR;
00263 }
00264 if (my->target!=NULL)
00265 {
00266 OBJECT *target = obj->parent ? obj->parent : obj;
00267 gl_set_value(target,GETADDR(target,my->target),my->next.value,my->target);
00268 }
00269 t1 = player_read(obj);
00270 }
00271 obj->clock = t0;
00272 return t1;
00273 }
00274