00001
00009 #include <stdlib.h>
00010 #include <stdio.h>
00011 #include <errno.h>
00012 #include <math.h>
00013
00014 #include "billdump.h"
00015
00017
00019
00020 CLASS* billdump::oclass = NULL;
00021
00022 billdump::billdump(MODULE *mod)
00023 {
00024 if (oclass==NULL)
00025 {
00026
00027 oclass = gl_register_class(mod,"billdump",sizeof(billdump),PC_BOTTOMUP|PC_AUTOLOCK);
00028 if (oclass==NULL)
00029 throw "unable to register class billdump";
00030 else
00031 oclass->trl = TRL_QUALIFIED;
00032
00033
00034 if (gl_publish_variable(oclass,
00035 PT_char32,"group",PADDR(group),PT_DESCRIPTION,"the group ID to output data for (all nodes if empty)",
00036 PT_timestamp,"runtime",PADDR(runtime),PT_DESCRIPTION,"the time to check voltage data",
00037 PT_char256,"filename",PADDR(filename),PT_DESCRIPTION,"the file to dump the voltage data into",
00038 PT_int32,"runcount",PADDR(runcount),PT_ACCESS,PA_REFERENCE,PT_DESCRIPTION,"the number of times the file has been written to",
00039 PT_enumeration,"meter_type",PADDR(meter_type), PT_DESCRIPTION, "describes whether to collect from 3-phase or S-phase meters",
00040 PT_KEYWORD,"TRIPLEX_METER",(enumeration)METER_TP,
00041 PT_KEYWORD,"METER",(enumeration)METER_3P,
00042 NULL)<1) GL_THROW("unable to publish properties in %s",__FILE__);
00043
00044 }
00045 }
00046
00047
00048 int billdump::create(void)
00049 {
00050 group.erase();
00051 runtime = TS_NEVER;
00052 runcount = 0;
00053 meter_type = METER_TP;
00054 return 1;
00055 }
00056
00057 int billdump::init(OBJECT *parent)
00058 {
00059 return 1;
00060 }
00061
00062 int billdump::isa(char *classname)
00063 {
00064 return strcmp(classname,"billdump")==0;
00065 }
00066
00067 void billdump::dump(TIMESTAMP t){
00068 char namestr[64];
00069 char timestr[64];
00070 FINDLIST *nodes = NULL;
00071 OBJECT *obj = NULL;
00072 FILE *outfile = NULL;
00073 gld_property *node_monthly_bill;
00074 gld_property *node_monthly_energy;
00075 double node_prev_monthly_bill, node_prev_monthly_energy;
00076
00077
00078
00079
00080 if (meter_type == METER_TP)
00081 {
00082 if(group[0] == 0){
00083 nodes = gl_find_objects(FL_NEW,FT_CLASS,SAME,"triplex_meter",FT_END);
00084 } else {
00085 nodes = gl_find_objects(FL_NEW,FT_CLASS,SAME,"triplex_meter",AND,FT_GROUPID,SAME,group.get_string(),FT_END);
00086 }
00087 }
00088 else
00089 {
00090 if(group[0] == 0){
00091 nodes = gl_find_objects(FL_NEW,FT_CLASS,SAME,"meter",FT_END);
00092 } else {
00093 nodes = gl_find_objects(FL_NEW,FT_CLASS,SAME,"meter",AND,FT_GROUPID,SAME,group.get_string(),FT_END);
00094 }
00095 }
00096
00097 if(nodes == NULL){
00098 gl_warning("no nodes were found to dump");
00099 return;
00100 }
00101
00102 outfile = fopen(filename, "w");
00103 if(outfile == NULL){
00104 gl_error("billdump unable to open %s for output", filename.get_string());
00105 return;
00106 }
00107
00108
00109
00110
00111 if (meter_type == METER_TP)
00112 {
00113
00114 gl_printtime(t, timestr, 64);
00115 fprintf(outfile,"# %s run at %s on %i triplex meters\n", filename.get_string(), timestr, nodes->hit_count);
00116 fprintf(outfile,"meter_name,previous_monthly_bill,previous_monthly_energy\n");
00117 while (obj=gl_find_next(nodes,obj)){
00118 if(gl_object_isa(obj, "triplex_meter", "powerflow")){
00119
00120
00121 node_monthly_bill = new gld_property(obj,"previous_monthly_bill");
00122
00123
00124 if ((node_monthly_bill->is_valid() != true) || (node_monthly_bill->is_double() != true))
00125 {
00126 GL_THROW("billdump - Unable to map billing property of triplex_meter:%d - %s",obj->id,(obj->name ? obj->name : "Unnamed"));
00127
00128
00129
00130
00131 }
00132
00133
00134 node_monthly_energy = new gld_property(obj,"previous_monthly_energy");
00135
00136
00137 if ((node_monthly_energy->is_valid() != true) || (node_monthly_energy->is_double() != true))
00138 {
00139 GL_THROW("billdump - Unable to map billing property of triplex_meter:%d - %s",obj->id,(obj->name ? obj->name : "Unnamed"));
00140
00141 }
00142
00143
00144 node_prev_monthly_bill = node_monthly_bill->get_double();
00145 node_prev_monthly_energy = node_monthly_energy->get_double();
00146
00147 if(obj->name == NULL){
00148 sprintf(namestr, "%s:%i", obj->oclass->name, obj->id);
00149 }
00150 fprintf(outfile,"%s,%f,%f\n",(obj->name ? obj->name : namestr),node_prev_monthly_bill,node_prev_monthly_energy);
00151
00152
00153 delete node_monthly_bill;
00154 delete node_monthly_energy;
00155 }
00156 }
00157 }
00158 else
00159 {
00160
00161 gl_printtime(t, timestr, 64);
00162 fprintf(outfile,"# %s run at %s on %i meters\n", filename.get_string(), timestr, nodes->hit_count);
00163 fprintf(outfile,"meter_name,previous_monthly_bill,previous_monthly_energy\n");
00164 while (obj=gl_find_next(nodes,obj)){
00165 if(gl_object_isa(obj, "meter", "powerflow")){
00166
00167
00168 node_monthly_bill = new gld_property(obj,"previous_monthly_bill");
00169
00170
00171 if ((node_monthly_bill->is_valid() != true) || (node_monthly_bill->is_double() != true))
00172 {
00173 GL_THROW("billdump - Unable to map billing property of meter:%d - %s",obj->id,(obj->name ? obj->name : "Unnamed"));
00174
00175
00176
00177
00178 }
00179
00180
00181 node_monthly_energy = new gld_property(obj,"previous_monthly_energy");
00182
00183
00184 if ((node_monthly_energy->is_valid() != true) || (node_monthly_energy->is_double() != true))
00185 {
00186 GL_THROW("billdump - Unable to map billing property of meter:%d - %s",obj->id,(obj->name ? obj->name : "Unnamed"));
00187
00188 }
00189
00190
00191 node_prev_monthly_bill = node_monthly_bill->get_double();
00192 node_prev_monthly_energy = node_monthly_energy->get_double();
00193
00194 if(obj->name == NULL){
00195 sprintf(namestr, "%s:%i", obj->oclass->name, obj->id);
00196 }
00197 fprintf(outfile,"%s,%f,%f\n",(obj->name ? obj->name : namestr),node_prev_monthly_bill,node_prev_monthly_energy);
00198
00199
00200 delete node_monthly_bill;
00201 delete node_monthly_energy;
00202 }
00203 }
00204 }
00205 fclose(outfile);
00206
00207
00208 gl_free(nodes);
00209 }
00210
00211 TIMESTAMP billdump::commit(TIMESTAMP t){
00212 if(runtime == 0){
00213 runtime = t;
00214 }
00215 if((t >= runtime || runtime == TS_NEVER) && (runcount < 1)){
00216
00217 dump(t);
00218 ++runcount;
00219 }
00220 return TS_NEVER;
00221 }
00222
00224
00226
00234 EXPORT int create_billdump(OBJECT **obj, OBJECT *parent)
00235 {
00236 try
00237 {
00238 *obj = gl_create_object(billdump::oclass);
00239 if (*obj!=NULL)
00240 {
00241 billdump *my = OBJECTDATA(*obj,billdump);
00242 gl_set_parent(*obj,parent);
00243 return my->create();
00244 }
00245 else
00246 return 0;
00247 }
00248 CREATE_CATCHALL(billdump);
00249 }
00250
00251 EXPORT int init_billdump(OBJECT *obj)
00252 {
00253 try {
00254 billdump *my = OBJECTDATA(obj,billdump);
00255 return my->init(obj->parent);
00256 }
00257 INIT_CATCHALL(billdump);
00258 }
00259
00260 EXPORT TIMESTAMP sync_billdump(OBJECT *obj, TIMESTAMP t1, PASSCONFIG pass)
00261 {
00262 try
00263 {
00264 billdump *my = OBJECTDATA(obj,billdump);
00265 TIMESTAMP rv;
00266 obj->clock = t1;
00267 rv = my->runtime > t1 ? my->runtime : TS_NEVER;
00268 return rv;
00269 }
00270 SYNC_CATCHALL(billdump);
00271 }
00272
00273 EXPORT TIMESTAMP commit_billdump(OBJECT *obj, TIMESTAMP t1, TIMESTAMP t2){
00274 try {
00275 billdump *my = OBJECTDATA(obj,billdump);
00276 return my->commit(t1);
00277 }
00278 I_CATCHALL(commit,billdump);
00279 }
00280
00281 EXPORT int isa_billdump(OBJECT *obj, char *classname)
00282 {
00283 return OBJECTDATA(obj,billdump)->isa(classname);
00284 }
00285
00289