00001
00010 #include <stdlib.h>
00011 #include <stdio.h>
00012 #include <errno.h>
00013 #include <math.h>
00014
00015 #include "dishwasher.h"
00016
00018
00020 CLASS* dishwasher::oclass = NULL;
00021 CLASS* dishwasher::pclass = NULL;
00022 dishwasher *dishwasher::defaults = NULL;
00023
00024 dishwasher::dishwasher(MODULE *module) : residential_enduse(module)
00025 {
00026
00027 if (oclass==NULL)
00028 {
00029 pclass = residential_enduse::oclass;
00030
00031
00032 oclass = gl_register_class(module,"dishwasher",sizeof(dishwasher),PC_PRETOPDOWN|PC_BOTTOMUP|PC_AUTOLOCK);
00033 if (oclass==NULL)
00034 GL_THROW("unable to register object class implemented by %s",__FILE__);
00035
00036
00037 if (gl_publish_variable(oclass,
00038 PT_INHERIT, "residential_enduse",
00039
00040 PT_double,"control_power[W]",PADDR(coil_power[0]),
00041 PT_double,"dishwasher_coil_power_1[W]",PADDR(coil_power[1]),
00042 PT_double,"dishwasher_coil_power_2[W]",PADDR(coil_power[2]),
00043 PT_double,"dishwasher_coil_power_3[W]",PADDR(coil_power[3]),
00044 PT_double,"motor_power[W]",PADDR(motor_power),
00045
00046 PT_double,"circuit_split",PADDR(circuit_split),
00047 PT_double,"queue[unit]",PADDR(enduse_queue), PT_DESCRIPTION, "number of loads accumulated",
00048 PT_double,"stall_voltage[V]", PADDR(stall_voltage),
00049 PT_double,"start_voltage[V]", PADDR(start_voltage),
00050 PT_complex,"stall_impedance[Ohm]", PADDR(stall_impedance),
00051 PT_double,"trip_delay[s]", PADDR(trip_delay),
00052 PT_double,"reset_delay[s]", PADDR(reset_delay),
00053 PT_double,"total_power[W]",PADDR(total_power),
00054
00055 PT_enumeration,"state", PADDR(state),
00056 PT_KEYWORD,"STOPPED",(enumeration)dishwasher_STOPPED,
00057 PT_KEYWORD,"STALLED",(enumeration)dishwasher_STALLED,
00058 PT_KEYWORD,"TRIPPED",(enumeration)dishwasher_TRIPPED,
00059 PT_KEYWORD,"MOTOR_ONLY",(enumeration)dishwasher_MOTOR_ONLY,
00060 PT_KEYWORD,"MOTOR_COIL_ONLY",(enumeration)dishwasher_MOTOR_COIL_ONLY,
00061 PT_KEYWORD,"COIL_ONLY",(enumeration)dishwasher_COIL_ONLY,
00062 PT_KEYWORD,"CONTROL_ONLY",(enumeration)dishwasher_CONTROL_ONLY,
00063 PT_KEYWORD,"HEATEDDRY_ONLY",(enumeration)dishwasher_HEATEDDRY_ONLY,
00064
00065
00066
00067 PT_double,"energy_baseline[kWh]",PADDR(energy_baseline),
00068 PT_double,"energy_used[kWh]",PADDR(energy_used),
00069
00070 PT_bool,"control_check1",PADDR(control_check1),
00071 PT_bool,"control_check2",PADDR(control_check2),
00072 PT_bool,"control_check3",PADDR(control_check3),
00073 PT_bool,"control_check4",PADDR(control_check4),
00074 PT_bool,"control_check5",PADDR(control_check5),
00075 PT_bool,"control_check6",PADDR(control_check6),
00076 PT_bool,"control_check7",PADDR(control_check7),
00077 PT_bool,"control_check8",PADDR(control_check8),
00078 PT_bool,"control_check9",PADDR(control_check9),
00079 PT_bool,"control_check10",PADDR(control_check10),
00080 PT_bool,"control_check11",PADDR(control_check11),
00081 PT_bool,"control_check12",PADDR(control_check12),
00082 PT_bool,"control_check_temp",PADDR(control_check_temp),
00083
00084 PT_bool,"motor_only_check1",PADDR(motor_only_check1),
00085 PT_bool,"motor_only_check2",PADDR(motor_only_check2),
00086 PT_bool,"motor_only_check3",PADDR(motor_only_check3),
00087 PT_bool,"motor_only_check4",PADDR(motor_only_check4),
00088 PT_bool,"motor_only_check5",PADDR(motor_only_check5),
00089 PT_bool,"motor_only_check6",PADDR(motor_only_check6),
00090 PT_bool,"motor_only_check7",PADDR(motor_only_check7),
00091 PT_bool,"motor_only_check8",PADDR(motor_only_check8),
00092 PT_bool,"motor_only_check9",PADDR(motor_only_check9),
00093
00094 PT_bool,"motor_only_temp1",PADDR(motor_only_temp1),
00095 PT_bool,"motor_only_temp2",PADDR(motor_only_temp2),
00096
00097 PT_bool,"motor_coil_only_check1",PADDR(motor_coil_only_check1),
00098 PT_bool,"motor_coil_only_check2",PADDR(motor_coil_only_check2),
00099
00100 PT_bool,"heateddry_check1",PADDR(heateddry_check1),
00101 PT_bool,"heateddry_check2",PADDR(heateddry_check2),
00102
00103 PT_bool,"coil_only_check1",PADDR(coil_only_check1),
00104 PT_bool,"coil_only_check2",PADDR(coil_only_check2),
00105 PT_bool,"coil_only_check3",PADDR(coil_only_check3),
00106
00107 PT_bool,"Heateddry_option_check",PADDR(Heateddry_option_check),
00108
00109 PT_double,"queue_min[unit]",PADDR(queue_min),
00110 PT_double,"queue_max[unit]",PADDR(queue_max),
00111
00112
00113 PT_double,"pulse_interval_1[s]", PADDR(pulse_interval[0]),
00114 PT_double,"pulse_interval_2[s]", PADDR(pulse_interval[1]),
00115 PT_double,"pulse_interval_3[s]", PADDR(pulse_interval[2]),
00116 PT_double,"pulse_interval_4[s]", PADDR(pulse_interval[3]),
00117 PT_double,"pulse_interval_5[s]", PADDR(pulse_interval[4]),
00118 PT_double,"pulse_interval_6[s]", PADDR(pulse_interval[5]),
00119 PT_double,"pulse_interval_7[s]", PADDR(pulse_interval[6]),
00120 PT_double,"pulse_interval_8[s]", PADDR(pulse_interval[7]),
00121 PT_double,"pulse_interval_9[s]", PADDR(pulse_interval[8]),
00122 PT_double,"pulse_interval_10[s]", PADDR(pulse_interval[9]),
00123 PT_double,"pulse_interval_11[s]", PADDR(pulse_interval[10]),
00124 PT_double,"pulse_interval_12[s]", PADDR(pulse_interval[11]),
00125 PT_double,"pulse_interval_13[s]", PADDR(pulse_interval[12]),
00126 PT_double,"pulse_interval_14[s]", PADDR(pulse_interval[13]),
00127 PT_double,"pulse_interval_15[s]", PADDR(pulse_interval[14]),
00128 PT_double,"pulse_interval_16[s]", PADDR(pulse_interval[15]),
00129 PT_double,"pulse_interval_17[s]", PADDR(pulse_interval[16]),
00130 PT_double,"pulse_interval_18[s]", PADDR(pulse_interval[17]),
00131 PT_double,"pulse_interval_19[s]", PADDR(pulse_interval[18]),
00132
00133
00134 PT_double,"dishwasher_run_prob", PADDR(dishwasher_run_prob),
00135
00136 PT_double,"energy_needed[kWh]",PADDR(energy_needed),
00137 PT_double,"dishwasher_demand[kWh]",PADDR(dishwasher_demand),
00138 PT_double,"daily_dishwasher_demand[kWh]",PADDR(daily_dishwasher_demand),
00139 PT_double,"actual_dishwasher_demand[kWh]",PADDR(actual_dishwasher_demand),
00140
00141 PT_double,"motor_on_off",PADDR(motor_on_off),
00142 PT_double,"motor_coil_on_off",PADDR(motor_coil_on_off),
00143
00144
00145 PT_bool,"is_240",PADDR(is_240), PT_DESCRIPTION, "load is 220/240 V (across both phases)",
00146 NULL)<1)
00147 GL_THROW("unable to publish properties in %s",__FILE__);
00148 }
00149 }
00150
00151 dishwasher::~dishwasher()
00152 {
00153 }
00154
00155 int dishwasher::create()
00156 {
00157 int res = residential_enduse::create();
00158
00159
00160 load.name = oclass->name;
00161
00162 load.power = load.admittance = load.current = load.total = complex(0,0,J);
00163 load.voltage_factor = 1.0;
00164 load.power_factor = 0.95;
00165 load.power_fraction = 1;
00166 is_240 = true;
00167
00168 state = dishwasher_STOPPED;
00169
00170 energy_used = 0;
00171
00172 coil_power[0] = -1;
00173 motor_on_off = motor_coil_on_off = both_coils_on_off = 0;
00174
00175 last_t = 0;
00176
00177
00178 gl_warning("explicit %s model is experimental and has not been validated", OBJECTHDR(this)->oclass->name);
00179
00180
00181
00182
00183
00184 return res;
00185 }
00186
00187 int dishwasher::init(OBJECT *parent)
00188 {
00189
00190
00191 OBJECT *hdr = OBJECTHDR(this);
00192 if(parent != NULL){
00193 if((parent->flags & OF_INIT) != OF_INIT){
00194 char objname[256];
00195 gl_verbose("dishwasher::init(): deferring initialization on %s", gl_name(parent, objname, 255));
00196 return 2;
00197 }
00198 }
00199 int rv = 0;
00200
00201 if (motor_power==0) motor_power = gl_random_uniform(&hdr->rng_state,150,350);
00202 if (heat_fraction==0) heat_fraction = 0.2;
00203 if (is_240)
00204 {
00205 load.config = EUC_IS220;
00206 if (stall_voltage==0) stall_voltage = 1.2*default_line_voltage;
00207 }
00208 else
00209 if (stall_voltage==0) stall_voltage = 0.6*default_line_voltage;
00210
00211 if (trip_delay==0) trip_delay = 10;
00212 if (reset_delay==0) reset_delay = 60;
00213
00214 count_motor_only = 0;
00215 count_motor_only1 =0;
00216 count_motor_only_25 = 0;
00217 count_coil_only = 0;
00218 count_control_only =0;
00219 count_control_only1 =0;
00220 count_motor_only_68 =0;
00221
00222 pulse_interval[0] = 8;
00223 pulse_interval[1] = 18;
00224 pulse_interval[2] = 21;
00225 pulse_interval[3] = 28;
00226 pulse_interval[4] = 38;
00227 pulse_interval[5] = 50;
00228 pulse_interval[6] = 65;
00229
00230 pulse_interval[7] = 118;
00231 pulse_interval[8] = 150;
00232 pulse_interval[9] = 220;
00233 pulse_interval[10] = 320;
00234 pulse_interval[11] = 355;
00235 pulse_interval[12] = 460;
00236 pulse_interval[13] = 580;
00237
00238 pulse_interval[14] = 615;
00239 pulse_interval[15] = 780;
00240 pulse_interval[16] = 800;
00241 pulse_interval[17] = 950;
00242 pulse_interval[18] = 1150;
00243
00244
00245 if (coil_power[0]==-1) coil_power[0] = 5800;
00246
00247 coil_power[0] = 10;
00248 coil_power[1] = 580;
00249 coil_power[2] = 695;
00250 coil_power[3] = 950;
00251 motor_power = 250;
00252
00253 enduse_queue = 1;
00254 queue_min = 0;
00255 queue_max = 2;
00256
00257 control_check1 = false;
00258 control_check2 = false;
00259 control_check3 = false;
00260
00261 control_check4 = false;
00262 control_check5 = false;
00263 control_check6 = false;
00264
00265 control_check7 = false;
00266 control_check8 = false;
00267 control_check9 = false;
00268 control_check10 = false;
00269 control_check11 = false;
00270 control_check12 = false;
00271
00272 motor_only_check1 = false;
00273 motor_only_check2 = false;
00274 motor_only_check3 = false;
00275 motor_only_check4 = false;
00276
00277 motor_only_check5 = false;
00278 motor_only_check6 = false;
00279 motor_only_check7 = false;
00280 motor_only_check8 = false;
00281 motor_only_check9 = false;
00282
00283 motor_coil_only_check1 = false;
00284 motor_coil_only_check2 = false;
00285
00286 heateddry_check1 = false;
00287 heateddry_check2 = false;
00288
00289 coil_only_check1 = false;
00290 coil_only_check2 = false;
00291 coil_only_check3 = false;
00292
00293
00294
00295 hdr->flags |= OF_SKIPSAFE;
00296
00297 load.power_factor = 0.95;
00298 load.breaker_amps = 30;
00299 actual_dishwasher_demand = 0;
00300 energy_needed = 0;
00301
00302 rv = residential_enduse::init(parent);
00303
00304 if (rv==SUCCESS) update_state(0.0);
00305
00306
00307 switch(shape.type){
00308 case MT_UNKNOWN:
00309 gl_warning("This device, %s, is considered very experimental and has not been validated.", get_name());
00310 break;
00311 case MT_ANALOG:
00312 if(shape.params.analog.energy == 0.0){
00313 GL_THROW("dishwasher does not support fixed energy shaping");
00314
00315 } else if (shape.params.analog.power == 0){
00316
00317 daily_dishwasher_demand = gl_get_loadshape_value(&shape) / 2.4449;
00318 } else {
00319 daily_dishwasher_demand = gl_get_loadshape_value(&shape);
00320 }
00321 break;
00322 case MT_PULSED:
00323
00324
00325 if(shape.params.pulsed.pulsetype == MPT_TIME){
00326 ;
00327 } else if(shape.params.pulsed.pulsetype == MPT_POWER){
00328 ;
00329 daily_dishwasher_demand = gl_get_loadshape_value(&shape) / 2.4449;
00330 }
00331 break;
00332 case MT_MODULATED:
00333 if(shape.params.modulated.pulsetype == MPT_TIME){
00334 GL_THROW("Amplitude modulated dishwasher usage is nonsensical for residential dishwashers");
00335
00336
00337
00338
00339 } else if(shape.params.modulated.pulsetype == MPT_POWER){
00340
00341
00342 daily_dishwasher_demand = gl_get_loadshape_value(&shape) / 2.4449;
00343 }
00344 break;
00345 case MT_QUEUED:
00346 if(shape.params.queued.pulsetype == MPT_TIME){
00347 ;
00348 } else if(shape.params.queued.pulsetype == MPT_POWER){
00349 ;
00350 daily_dishwasher_demand = gl_get_loadshape_value(&shape) / 2.4449;
00351 }
00352 break;
00353 default:
00354 GL_THROW("dishwasher load shape has an unknown state!");
00355 break;
00356 }
00357 return residential_enduse::init(parent);
00358
00359
00360
00361
00362
00363 }
00364
00365 int dishwasher::isa(char *classname)
00366 {
00367 return (strcmp(classname,"dishwasher")==0 || residential_enduse::isa(classname));
00368 }
00369
00370
00371 TIMESTAMP dishwasher::sync(TIMESTAMP t0, TIMESTAMP t1)
00372 {
00373 double dt = 0;
00374 TIMESTAMP t3;
00375
00376
00377
00378 TIMESTAMP t2 = residential_enduse::sync(t0,t1);
00379
00380 if ((last_t != t0) && (last_t != 0))
00381 {
00382
00383 dt = gl_toseconds(t0>0?t0-last_t:0);
00384
00385
00386 if (t0>TS_ZERO && dt>0)
00387 {
00388
00389 load.energy += load.total * dt/3600.0;
00390
00391
00392 last_t = t0;
00393 }
00394
00395 dt = update_state(dt);
00396 }
00397 else if (last_t == 0)
00398 {
00399 last_t = t0;
00400 }
00401
00402
00403 t3 = (TIMESTAMP)(dt*TS_SECOND+t0);
00404
00405 if (t3>t2)
00406 return -t3;
00407 else
00408 return t2;
00409 }
00410
00411 TIMESTAMP dishwasher::presync(TIMESTAMP t0, TIMESTAMP t1){
00412
00413 switch(shape.type){
00414 case MT_UNKNOWN:
00415
00416 break;
00417 case MT_ANALOG:
00418 if(shape.params.analog.energy == 0.0){
00419 GL_THROW("dishwasher does not support fixed energy shaping");
00420
00421 } else if (shape.params.analog.power == 0){
00422
00423 daily_dishwasher_demand = gl_get_loadshape_value(&shape) / 2.4449;
00424 } else {
00425 daily_dishwasher_demand = gl_get_loadshape_value(&shape);
00426 }
00427 break;
00428 case MT_PULSED:
00429
00430
00431 if(shape.params.pulsed.pulsetype == MPT_TIME){
00432 ;
00433 } else if(shape.params.pulsed.pulsetype == MPT_POWER){
00434 ;
00435 daily_dishwasher_demand = gl_get_loadshape_value(&shape) / 2.4449;
00436 }
00437 break;
00438 case MT_MODULATED:
00439 if(shape.params.modulated.pulsetype == MPT_TIME){
00440 GL_THROW("Amplitude modulated dishwasher usage is nonsensical for residential dishwashers");
00441
00442
00443
00444
00445 } else if(shape.params.modulated.pulsetype == MPT_POWER){
00446
00447
00448 daily_dishwasher_demand = gl_get_loadshape_value(&shape) / 2.4449;
00449 }
00450 break;
00451 case MT_QUEUED:
00452 if(shape.params.queued.pulsetype == MPT_TIME){
00453 ;
00454 } else if(shape.params.queued.pulsetype == MPT_POWER){
00455 ;
00456 daily_dishwasher_demand = gl_get_loadshape_value(&shape) / 2.4449;
00457 }
00458 break;
00459 default:
00460 GL_THROW("dishwasher load shape has an unknown state!");
00461 break;
00462 }
00463 return TS_NEVER;
00464 }
00465
00466 double dishwasher::update_state(double dt)
00467 {
00468
00469
00470 double temp_voltage_value_mag;
00471 OBJECT *hdr = OBJECTHDR(this);
00472
00473 energy_used += total_power/1000 * dt/3600;
00474
00475
00476 temp_voltage_value_mag = (pCircuit->pV->get_complex()).Mag();
00477
00478 switch(state) {
00479
00480 case dishwasher_STOPPED:
00481
00482 if (enduse_queue>1)
00483
00484 dishwasher_run_prob = double(gl_random_uniform(&hdr->rng_state,queue_min,queue_max));
00485
00486 if (enduse_queue > 1 && (dishwasher_run_prob > enduse_queue))
00487 {
00488 state = dishwasher_CONTROL_ONLY;
00489 if (Heateddry_option_check == true)
00490 energy_needed = energy_baseline;
00491 else
00492 energy_needed = 0.66*energy_baseline;
00493
00494 cycle_duration = cycle_time = 1000 * (energy_needed - energy_used) / coil_power[0] * 60 * 60;
00495 cycle_time = pulse_interval[5];
00496 enduse_queue--;
00497
00498 new_running_state = true;
00499
00500 }
00501 else if (temp_voltage_value_mag<stall_voltage)
00502 {
00503 state = dishwasher_STALLED;
00504 state_time = 0;
00505 }
00506 break;
00507
00508 case dishwasher_CONTROL_ONLY:
00509
00510 if (energy_used >= energy_needed || cycle_time <= 0)
00511 {
00512 if (energy_used >= energy_needed)
00513 {
00514 state = dishwasher_STOPPED;
00515 cycle_time = 0;
00516 energy_used = 0;
00517
00518 control_check1 = false;
00519 control_check2 = false;
00520 control_check3 = false;
00521
00522 control_check4 = false;
00523 control_check5 = false;
00524 control_check6 = false;
00525
00526 control_check7 = false;
00527 control_check8 = false;
00528 control_check9 = false;
00529 control_check10 = false;
00530 control_check11 = false;
00531 control_check12 = false;
00532
00533 motor_only_check1 = false;
00534 motor_only_check2 = false;
00535 motor_only_check3 = false;
00536 motor_only_check4 = false;
00537
00538 motor_only_check5 = false;
00539 motor_only_check6 = false;
00540 motor_only_check7 = false;
00541 motor_only_check8 = false;
00542 motor_only_check9 = false;
00543
00544 motor_coil_only_check1 = false;
00545 motor_coil_only_check2 = false;
00546
00547 heateddry_check1 = false;
00548 heateddry_check2 = false;
00549
00550 coil_only_check1 = false;
00551 coil_only_check2 = false;
00552 coil_only_check3 = false;
00553
00554
00555 new_running_state = true;
00556
00557 }
00558 else if (cycle_time<=0)
00559 {
00560
00561 if (cycle_time<=0 && (control_check1 == false || control_check_temp == true))
00562 {
00563 state = dishwasher_MOTOR_ONLY;
00564 double cycle_t = 1000 * (energy_needed - energy_used) / motor_power * 60 * 60;
00565 double interval = pulse_interval[0];
00566
00567 if (cycle_t > interval)
00568 cycle_time = interval;
00569 else
00570 cycle_time = cycle_t;
00571 control_check1 = true;
00572 control_check2 = true;
00573 }
00574
00575 if (cycle_time<=0 && control_check2 == true)
00576 {
00577 state = dishwasher_MOTOR_ONLY;
00578 double cycle_t = 1000 * (energy_needed - energy_used) / motor_power * 60 * 60;
00579 double interval = pulse_interval[7];
00580 if (cycle_t > interval)
00581 cycle_time = interval;
00582 else
00583 cycle_time = cycle_t;
00584 control_check2 = false;
00585 control_check6 = true;
00586
00587 }
00588
00589 if (cycle_time<=0 && control_check3 == true)
00590 {
00591 state = dishwasher_MOTOR_ONLY;
00592 double cycle_t = 1000 * (energy_needed - energy_used) / motor_power * 60 * 60;
00593 double interval = pulse_interval[6];
00594 if (cycle_t > interval)
00595 cycle_time = interval;
00596 else
00597 cycle_time = cycle_t;
00598 control_check3 = false;
00599 control_check7 = true;
00600 }
00601
00602 if (cycle_time<=0 && control_check4 == true)
00603 {
00604 state = dishwasher_MOTOR_ONLY;
00605 double cycle_t = 1000 * (energy_needed - energy_used) / motor_power * 60 * 60;
00606 double interval = pulse_interval[9];
00607 if (cycle_t > interval)
00608 cycle_time = interval;
00609 else
00610 cycle_time = cycle_t;
00611 control_check4 = false;
00612 control_check5 = true;
00613 }
00614
00615 if (cycle_time<=0 && control_check5 == true)
00616 {
00617 state = dishwasher_MOTOR_ONLY;
00618 double cycle_t = 1000 * (energy_needed - energy_used) / motor_power * 60 * 60;
00619 double interval = pulse_interval[4];
00620 if (cycle_t > interval)
00621 cycle_time = interval;
00622 else
00623 cycle_time = cycle_t;
00624
00625 control_check5 = false;
00626 control_check8 = true;
00627 }
00628
00629
00630
00631 if (cycle_time<=0 && control_check6 == true)
00632 {
00633 state = dishwasher_COIL_ONLY;
00634
00635 double cycle_t = 1000 * (energy_needed - energy_used) / coil_power[1] * 60 * 60;
00636
00637 double interval = pulse_interval[0];
00638
00639 if (cycle_t > interval)
00640 cycle_time = interval;
00641 else
00642 cycle_time = cycle_t;
00643 control_check6 = false;
00644 control_check3 = true;
00645
00646 }
00647
00648
00649 if(cycle_time<=0 && (control_check7 == true))
00650 {
00651
00652 state = dishwasher_MOTOR_COIL_ONLY;
00653 double cycle_t = 1000 * (energy_needed - energy_used) / (motor_power + coil_power[3]) * 60 * 60;
00654 double interval = pulse_interval[10];
00655
00656 if (cycle_t > interval)
00657 cycle_time = interval;
00658 else
00659 cycle_time = cycle_t;
00660
00661 control_check7 = false;
00662 control_check4 = true;
00663 }
00664
00665
00666 if (cycle_time<=0 && control_check8 == true && count_control_only<5)
00667 {
00668 state = dishwasher_COIL_ONLY;
00669
00670 double cycle_t = 1000 * (energy_needed - energy_used) / coil_power[1] * 60 * 60;
00671
00672 double interval = pulse_interval[0];
00673
00674 if (cycle_t > interval)
00675 cycle_time = interval;
00676 else
00677 cycle_time = cycle_t;
00678
00679 count_control_only += 1;
00680
00681 if (count_control_only == 4)
00682 {
00683
00684 control_check8 = false;
00685 control_check9 = true;
00686 }
00687 }
00688
00689
00690 if (cycle_time<=0 && control_check9 == true && count_control_only1 < 7)
00691 {
00692 state = dishwasher_MOTOR_ONLY;
00693
00694 double cycle_t = 1000 * (energy_needed - energy_used) / motor_power * 60 * 60;
00695
00696 double interval = pulse_interval[0];
00697
00698 if (cycle_t > interval)
00699 cycle_time = interval;
00700 else
00701 cycle_time = cycle_t;
00702
00703 count_control_only1 +=1;
00704 if (count_control_only1 ==6)
00705 {
00706 control_check9 = false;
00707 control_check10 = true;
00708 }
00709 }
00710
00711 if(cycle_time<=0 && (control_check10 == true))
00712 {
00713
00714 state = dishwasher_MOTOR_COIL_ONLY;
00715 double cycle_t = 1000 * (energy_needed - energy_used) / (motor_power + coil_power[3]) * 60 * 60;
00716 double interval = pulse_interval[17];
00717
00718 if (cycle_t > interval)
00719 cycle_time = interval;
00720 else
00721 cycle_time = cycle_t;
00722
00723 control_check10 = false;
00724 control_check11 = true;
00725 }
00726
00727
00728 if(cycle_time<=0 && control_check11 == true && Heateddry_option_check == true)
00729 {
00730 state = dishwasher_HEATEDDRY_ONLY;
00731
00732 double cycle_t = 1000 * (energy_needed - energy_used) / (coil_power[2]) * 60 * 60;
00733 double interval = pulse_interval[16];
00734
00735 if (cycle_t > interval)
00736 cycle_time = interval;
00737 else
00738 cycle_time = cycle_t;
00739 control_check11 = false;
00740 control_check12 = true;
00741 }
00742
00743 if(cycle_time<=0 && control_check12 == true && Heateddry_option_check == true)
00744 {
00745 state = dishwasher_HEATEDDRY_ONLY;
00746
00747 double cycle_t = 1000 * (energy_needed - energy_used) / (coil_power[2]) * 60 * 60;
00748 double interval = pulse_interval[15];
00749
00750 if (cycle_t > interval)
00751 cycle_time = interval;
00752 else
00753 cycle_time = cycle_t;
00754 control_check12 = false;
00755 }
00756
00757
00758
00759 new_running_state = true;
00760 }
00761
00762
00763 else if (temp_voltage_value_mag<stall_voltage)
00764 {
00765 state = dishwasher_STALLED;
00766 state_time = 0;
00767 }
00768 }
00769 break;
00770
00771 case dishwasher_MOTOR_ONLY:
00772
00773 if (energy_used >= energy_needed || cycle_time<=0)
00774 {
00775 if (energy_used >= energy_needed)
00776 {
00777 state = dishwasher_STOPPED;
00778 cycle_time = 0;
00779
00780 energy_used = 0;
00781
00782 control_check1 = false;
00783 control_check2 = false;
00784 control_check3 = false;
00785
00786 control_check4 = false;
00787 control_check5 = false;
00788 control_check6 = false;
00789
00790 control_check7 = false;
00791 control_check8 = false;
00792 control_check9 = false;
00793 control_check10 = false;
00794 control_check11 = false;
00795 control_check12 = false;
00796
00797 motor_only_check1 = false;
00798 motor_only_check2 = false;
00799 motor_only_check3 = false;
00800 motor_only_check4 = false;
00801
00802 motor_only_check5 = false;
00803 motor_only_check6 = false;
00804 motor_only_check7 = false;
00805 motor_only_check8 = false;
00806 motor_only_check9 = false;
00807
00808 motor_coil_only_check1 = false;
00809 motor_coil_only_check2 = false;
00810
00811 heateddry_check1 = false;
00812 heateddry_check2 = false;
00813
00814 coil_only_check1 = false;
00815 coil_only_check2 = false;
00816 coil_only_check3 = false;
00817
00818
00819 new_running_state = true;
00820 }
00821
00822 else if (cycle_time<=0)
00823 {
00824 state = dishwasher_CONTROL_ONLY;
00825
00826 if(cycle_time<=0 && (motor_only_check1 == false))
00827
00828 {
00829
00830 double cycle_t = 1000 * (energy_needed - energy_used) / coil_power[0] * 60 * 60;
00831 double interval = pulse_interval[5];
00832
00833
00834 if (cycle_t > interval)
00835 cycle_time = interval;
00836 else
00837 cycle_time = cycle_t;
00838
00839 motor_only_check1 = true;
00840 motor_only_check2 = true;
00841 }
00842
00843
00844 if(cycle_time<=0 && motor_only_check2 == true)
00845 {
00846
00847 double cycle_t = 1000 * (energy_needed - energy_used) / coil_power[0] * 60 * 60;
00848
00849 double interval = pulse_interval[3];
00850 if (cycle_t > interval)
00851 cycle_time = interval;
00852 else
00853 cycle_time = cycle_t;
00854
00855 motor_only_check2 = false;
00856
00857 motor_only_check3 = true;
00858 }
00859
00860 if(cycle_time<=0 && motor_only_check3 == true && count_motor_only_68 < 3)
00861
00862 {
00863
00864 double cycle_t = 1000 * (energy_needed - energy_used) / coil_power[0] * 60 * 60;
00865 double interval = pulse_interval[5];
00866
00867 if (cycle_t > interval)
00868 cycle_time = interval;
00869 else
00870 cycle_time = cycle_t;
00871
00872 count_motor_only_68 +=1;
00873
00874 if (count_motor_only_68 ==2)
00875 {
00876 motor_only_check3 = false;
00877 motor_only_check4 = true;
00878
00879 }
00880 }
00881
00882
00883 if(cycle_time<=0 && motor_only_check4 == true)
00884 {
00885
00886
00887 double cycle_t = 1000 * (energy_needed - energy_used) / coil_power[0] * 60 * 60;
00888 double interval = pulse_interval[2];
00889 if (cycle_t > interval)
00890 cycle_time = interval;
00891 else
00892 cycle_time = cycle_t;
00893 motor_only_check4 = false;
00894 motor_only_check5 = true;
00895 }
00896
00897 if(cycle_time<=0 && motor_only_check5 == true && count_motor_only_25 <6)
00898 {
00899
00900 double cycle_t = 1000 * (energy_needed - energy_used) / coil_power[0] * 60 * 60;
00901 double interval = pulse_interval[1];
00902 if (cycle_t > interval)
00903 cycle_time = interval;
00904 else
00905 cycle_time = cycle_t;
00906
00907 count_motor_only_25 +=1;
00908 if (count_motor_only_25 == 5)
00909 {
00910 motor_only_check5 = false;
00911 motor_only_check6 = true;
00912 }
00913 }
00914
00915 if(cycle_time<=0 && motor_only_check6 == true)
00916 {
00917
00918 double cycle_t = 1000 * (energy_needed - energy_used) / coil_power[0] * 60 * 60;
00919 double interval = pulse_interval[7];
00920 if (cycle_t > interval)
00921 cycle_time = interval;
00922 else
00923 cycle_time = cycle_t;
00924 motor_only_check6 = false;
00925 motor_only_check7 = true;
00926
00927 }
00928
00929 if(cycle_time<=0 && motor_only_check7 == true && count_motor_only <6)
00930 {
00931
00932 double cycle_t = 1000 * (energy_needed - energy_used) / coil_power[0] * 60 * 60;
00933 double interval = pulse_interval[4];
00934 if (cycle_t > interval)
00935 cycle_time = interval;
00936 else
00937 cycle_time = cycle_t;
00938
00939 count_motor_only +=1;
00940 if (count_motor_only ==5)
00941 {
00942 motor_only_check7 = false;
00943 motor_only_check8 = true;
00944 }
00945
00946 }
00947
00948 if(cycle_time<=0 && motor_only_check8 == true)
00949 {
00950
00951 double cycle_t = 1000 * (energy_needed - energy_used) / coil_power[0] * 60 * 60;
00952 double interval = pulse_interval[8];
00953 if (cycle_t > interval)
00954 cycle_time = interval;
00955 else
00956 cycle_time = cycle_t;
00957
00958 motor_only_check8 = false;
00959 motor_only_check9 = true;
00960
00961 }
00962
00963 if(cycle_time<=0 && motor_only_check9 == true)
00964 {
00965
00966 double cycle_t = 1000 * (energy_needed - energy_used) / coil_power[0] * 60 * 60;
00967 double interval = pulse_interval[12];
00968 if (cycle_t > interval)
00969 cycle_time = interval;
00970 else
00971 cycle_time = cycle_t;
00972
00973 count_motor_only1 +=1;
00974
00975 motor_only_check9 = false;
00976
00977 }
00978
00979 new_running_state = true;
00980 }
00981
00982
00983 else if (temp_voltage_value_mag<stall_voltage)
00984 {
00985 state = dishwasher_STALLED;
00986 state_time = 0;
00987 }
00988 }
00989
00990 break;
00991
00992 case dishwasher_MOTOR_COIL_ONLY:
00993
00994 if (energy_used >= energy_needed || cycle_time <= 0)
00995 {
00996 if (energy_used >= energy_needed)
00997 {
00998 state = dishwasher_STOPPED;
00999 cycle_time = 0;
01000 energy_used = 0;
01001
01002
01003 control_check1 = false;
01004 control_check2 = false;
01005 control_check3 = false;
01006
01007 control_check4 = false;
01008 control_check5 = false;
01009 control_check6 = false;
01010
01011 control_check7 = false;
01012 control_check8 = false;
01013 control_check9 = false;
01014 control_check10 = false;
01015 control_check11 = false;
01016 control_check12 = false;
01017
01018 motor_only_check1 = false;
01019 motor_only_check2 = false;
01020 motor_only_check3 = false;
01021 motor_only_check4 = false;
01022
01023 motor_only_check5 = false;
01024 motor_only_check6 = false;
01025 motor_only_check7 = false;
01026 motor_only_check8 = false;
01027 motor_only_check9 = false;
01028
01029 motor_coil_only_check1 = false;
01030 motor_coil_only_check2 = false;
01031
01032 heateddry_check1 = false;
01033 heateddry_check2 = false;
01034
01035 coil_only_check1 = false;
01036 coil_only_check2 = false;
01037 coil_only_check3 = false;
01038
01039
01040 new_running_state = true;
01041
01042 }
01043 else if (cycle_time<=0)
01044 {
01045 state = dishwasher_MOTOR_ONLY;
01046 double cycle_t = 1000 * (energy_needed - energy_used) / motor_power * 60 * 60;
01047
01048
01049 if (cycle_time<=0 && motor_coil_only_check1 == false)
01050 {
01051 double interval = pulse_interval[11];
01052 if (cycle_t > interval)
01053 cycle_time = interval;
01054 else
01055 cycle_time = cycle_t;
01056
01057 motor_coil_only_check1 = true;
01058 motor_coil_only_check2 = true;
01059 }
01060
01061 if(cycle_time<=0 && motor_coil_only_check2 == true)
01062 {
01063 double interval = pulse_interval[13];
01064 if (cycle_t > interval)
01065 cycle_time = interval;
01066 else
01067 cycle_time = cycle_t;
01068
01069 motor_coil_only_check2 = false;
01070 }
01071
01072 new_running_state = true;
01073 }
01074
01075
01076 else if (temp_voltage_value_mag<stall_voltage)
01077 {
01078 state = dishwasher_STALLED;
01079 state_time = 0;
01080 }
01081 }
01082 break;
01083
01084
01085
01086 case dishwasher_HEATEDDRY_ONLY:
01087
01088 if (energy_used >= energy_needed || cycle_time <= 0 )
01089 {
01090 if (energy_used >= energy_needed)
01091 {
01092 state = dishwasher_STOPPED;
01093 cycle_time = 0;
01094
01095 energy_used = 0;
01096
01097 control_check1 = false;
01098 control_check2 = false;
01099 control_check3 = false;
01100
01101 control_check4 = false;
01102 control_check5 = false;
01103 control_check6 = false;
01104
01105 control_check7 = false;
01106 control_check8 = false;
01107 control_check9 = false;
01108 control_check10 = false;
01109 control_check11 = false;
01110 control_check12 = false;
01111
01112 motor_only_check1 = false;
01113 motor_only_check2 = false;
01114 motor_only_check3 = false;
01115 motor_only_check4 = false;
01116
01117 motor_only_check5 = false;
01118 motor_only_check6 = false;
01119 motor_only_check7 = false;
01120 motor_only_check8 = false;
01121 motor_only_check9 = false;
01122
01123 motor_coil_only_check1 = false;
01124 motor_coil_only_check2 = false;
01125
01126 heateddry_check1 = false;
01127 heateddry_check2 = false;
01128
01129 coil_only_check1 = false;
01130 coil_only_check2 = false;
01131 coil_only_check3 = false;
01132
01133
01134 new_running_state = true;
01135 }
01136
01137 else if (cycle_time<=0 && heateddry_check1 == false)
01138 {
01139 state = dishwasher_CONTROL_ONLY;
01140 double cycle_t = 1000 * (energy_needed - energy_used) / coil_power[0] * 60 * 60;
01141 double interval = pulse_interval[7];
01142
01143 heateddry_check1 = true;
01144 heateddry_check2 = true;
01145
01146 if (cycle_t > interval)
01147 cycle_time = interval;
01148 else
01149 cycle_time = cycle_t;
01150
01151
01152 new_running_state = true;
01153 }
01154
01155
01156 else if (cycle_time<=0 && heateddry_check2 == true)
01157 {
01158 state = dishwasher_CONTROL_ONLY;
01159 double cycle_t = 1000 * (energy_needed - energy_used) / (coil_power[0]) * 60 * 60;
01160 double interval = pulse_interval[18];
01161
01162
01163 if (cycle_t > interval)
01164 cycle_time = interval;
01165 else
01166 cycle_time = cycle_t;
01167 motor_only_check2 = false;
01168
01169 new_running_state = true;
01170 }
01171
01172
01173
01174 else if (temp_voltage_value_mag<stall_voltage)
01175 {
01176 state = dishwasher_STALLED;
01177 state_time = 0;
01178 }
01179 }
01180
01181 break;
01182
01183 case dishwasher_COIL_ONLY:
01184
01185 if (energy_used >= energy_needed || cycle_time <= 0)
01186 {
01187 if (energy_used >= energy_needed)
01188 {
01189 state = dishwasher_STOPPED;
01190 cycle_time = 0;
01191 energy_used = 0;
01192
01193
01194 control_check1 = false;
01195 control_check2 = false;
01196 control_check3 = false;
01197
01198 control_check4 = false;
01199 control_check5 = false;
01200 control_check6 = false;
01201
01202 control_check7 = false;
01203 control_check8 = false;
01204 control_check9 = false;
01205 control_check10 = false;
01206 control_check11 = false;
01207 control_check12 = false;
01208
01209 motor_only_check1 = false;
01210 motor_only_check2 = false;
01211 motor_only_check3 = false;
01212 motor_only_check4 = false;
01213
01214 motor_only_check5 = false;
01215 motor_only_check6 = false;
01216 motor_only_check7 = false;
01217 motor_only_check8 = false;
01218 motor_only_check9 = false;
01219
01220 motor_coil_only_check1 = false;
01221 motor_coil_only_check2 = false;
01222
01223 heateddry_check1 = false;
01224 heateddry_check2 = false;
01225
01226 coil_only_check1 = false;
01227 coil_only_check2 = false;
01228 coil_only_check3 = false;
01229
01230
01231 new_running_state = true;
01232
01233 }
01234 else if (cycle_time<=0)
01235 {
01236 state = dishwasher_MOTOR_ONLY;
01237 double cycle_t = 1000 * (energy_needed - energy_used) / motor_power * 60 * 60;
01238
01239 if (cycle_time<=0 && coil_only_check1 == false)
01240 {
01241 double interval = pulse_interval[8];
01242 if (cycle_t > interval)
01243 cycle_time = interval;
01244 else
01245 cycle_time = cycle_t;
01246
01247 coil_only_check1 = true;
01248 coil_only_check2 = true;
01249 }
01250 if(cycle_time<=0 && coil_only_check2 == true && count_coil_only <4)
01251 {
01252 double interval = pulse_interval[4];
01253
01254 if (cycle_t > interval)
01255 cycle_time = interval;
01256 else
01257 cycle_time = cycle_t;
01258
01259 count_coil_only +=1;
01260 if (count_coil_only == 3)
01261 {
01262 coil_only_check2 = false;
01263 coil_only_check3 = true;
01264 }
01265 }
01266
01267 if(cycle_time<=0 && coil_only_check3 == true)
01268 {
01269 double interval = pulse_interval[14];
01270
01271 if (cycle_t > interval)
01272 cycle_time = interval;
01273 else
01274 cycle_time = cycle_t;
01275 coil_only_check3 = false;
01276
01277 }
01278 new_running_state = true;
01279 }
01280
01281
01282 else if (temp_voltage_value_mag<stall_voltage)
01283 {
01284 state = dishwasher_STALLED;
01285 state_time = 0;
01286 }
01287 }
01288 break;
01289
01290 case dishwasher_STALLED:
01291
01292 if (temp_voltage_value_mag>start_voltage)
01293 {
01294 state = dishwasher_MOTOR_ONLY;
01295 state_time = cycle_time;
01296 }
01297 else if (state_time>trip_delay)
01298 {
01299 state = dishwasher_TRIPPED;
01300 state_time = 0;
01301 }
01302
01303 break;
01304
01305 case dishwasher_TRIPPED:
01306
01307 if (state_time>reset_delay)
01308 {
01309 if (temp_voltage_value_mag>start_voltage)
01310 state = dishwasher_MOTOR_ONLY;
01311 else
01312 state = dishwasher_STALLED;
01313 state_time = 0;
01314 }
01315
01316 break;
01317 }
01318
01319
01320 enduse_queue += daily_dishwasher_demand * dt/3600/24;
01321
01322
01323
01324 switch(state) {
01325 case dishwasher_STOPPED:
01326
01327
01328 load.power = load.current = load.admittance = complex(0,0,J);
01329
01330 dt = ((enduse_queue>=1) || (enduse_queue==0)) ? 0 : ((1-enduse_queue)*3600)/(enduse_queue*24);
01331
01332 break;
01333
01334 case dishwasher_MOTOR_COIL_ONLY:
01335
01336 cycle_time -= dt;
01337 load.power.SetPowerFactor(motor_power/1000, load.power_factor);
01338 load.admittance = complex((coil_power[3])/1000,0,J);
01339 load.current = complex(0,0,J);
01340
01341 dt = cycle_time;
01342 break;
01343
01344 case dishwasher_COIL_ONLY:
01345
01346 cycle_time -= dt;
01347 load.power = load.current = complex(0,0,J);
01348 load.admittance = complex((coil_power[1])/1000,0,J);
01349
01350 dt = cycle_time;
01351 break;
01352
01353
01354 case dishwasher_HEATEDDRY_ONLY:
01355
01356 cycle_time -= dt;
01357 load.power = load.current = complex(0,0,J);
01358 load.admittance = complex((coil_power[2])/1000,0,J);
01359
01360 dt = cycle_time;
01361 break;
01362
01363 case dishwasher_CONTROL_ONLY:
01364
01365 if(true==new_running_state){
01366
01367 new_running_state = false;
01368
01369 }
01370 else{
01371
01372 cycle_time -= dt;
01373 }
01374 load.power = load.current = complex(0,0,J);
01375 load.admittance = complex(coil_power[0]/1000,0,J);
01376
01377 dt = cycle_time;
01378 break;
01379
01380 case dishwasher_STALLED:
01381
01382 load.power = load.current = complex(0,0,J);
01383 load.admittance = complex(1)/stall_impedance;
01384
01385 dt = trip_delay;
01386
01387 break;
01388
01389 case dishwasher_TRIPPED:
01390
01391 load.power = load.current = load.admittance = complex(0,0,J);
01392
01393 dt = reset_delay;
01394
01395 break;
01396
01397
01398 case dishwasher_MOTOR_ONLY:
01399 motor_on_off = 1;
01400 motor_coil_on_off = both_coils_on_off = 0;
01401 cycle_time -= dt;
01402
01403 load.power.SetPowerFactor(motor_power/1000, load.power_factor);
01404 load.admittance = complex(0,0,J);
01405 load.current = complex(0,0,J);
01406
01407 dt = cycle_time;
01408 break;
01409
01410 default:
01411
01412 throw "unexpected motor state";
01413
01414
01415
01416
01417 break;
01418 }
01419
01420
01421 load.total = load.power + load.current + load.admittance;
01422 total_power = (load.power.Re() + (load.current.Re() + load.admittance.Re()*load.voltage_factor)*load.voltage_factor) * 1000;
01423
01424
01425 load.heatgain = load.total.Mag() * heat_fraction;
01426
01427
01428 if (dt > 0 && dt < 1)
01429 dt = 1;
01430
01431 return dt;
01432 }
01433
01434
01436
01438
01439
01440 EXPORT TIMESTAMP sync_dishwasher(OBJECT *obj, TIMESTAMP t0, PASSCONFIG pass)
01441 {
01442 TIMESTAMP tret;
01443 dishwasher *my = OBJECTDATA(obj, dishwasher);
01444 if (obj->clock <= ROUNDOFF)
01445 obj->clock = t0;
01446 try {
01447 TIMESTAMP t1 = TS_NEVER;
01448 switch (pass) {
01449 case PC_PRETOPDOWN:
01450 return my->presync(obj->clock, t0);
01451 case PC_BOTTOMUP:
01452 tret = my->sync(obj->clock, t0);
01453 obj->clock = t0;
01454 return tret;
01455 default:
01456 throw "invalid pass request";
01457 }
01458 }
01459 catch (int m)
01460 {
01461 gl_error("%s (dishwasher:%d) model zone exception (code %d) not caught", obj->name?obj->name:"(anonymous dishwasher)", obj->id, m);
01462 }
01463 catch (char *msg)
01464 {
01465 gl_error("%s (dishwasher:%d) %s", obj->name?obj->name:"(anonymous dishwasher)", obj->id, msg);
01466 }
01467 return TS_INVALID;
01468 }
01469
01470 EXPORT int create_dishwasher(OBJECT **obj, OBJECT *parent)
01471 {
01472 *obj = gl_create_object(dishwasher::oclass);
01473 if (*obj!=NULL)
01474 {
01475 dishwasher *my = OBJECTDATA(*obj,dishwasher);
01476 gl_set_parent(*obj,parent);
01477 my->create();
01478 return 1;
01479 }
01480 return 0;
01481 }
01482
01483 EXPORT int init_dishwasher(OBJECT *obj)
01484 {
01485 dishwasher *my = OBJECTDATA(obj,dishwasher);
01486 return my->init(obj->parent);
01487 }
01488
01489 EXPORT int isa_dishwasher(OBJECT *obj, char *classname)
01490 {
01491 if(obj != 0 && classname != 0){
01492 return OBJECTDATA(obj,dishwasher)->isa(classname);
01493 } else {
01494 return 0;
01495 }
01496 }
01497
01498
01499
01500
01501
01502
01503
01504
01505