void setObjectValue_Double(OBJECT* obj, char* Property, double value) { char buffer[1024]; snprintf(buffer,sizeof(buffer),"%g",value); gl_set_value_by_name(obj,Property,buffer); }
TIMESTAMP ZIPload::sync(TIMESTAMP t0, TIMESTAMP t1) { TIMESTAMP t2 = TS_NEVER; double real_power = 0.0; double imag_power = 0.0; double angleval; double test = multiplier; if(first_time==0) { first_time=t1; } if(gl_todays(t1)-gl_todays(first_time)==1) { first_time=2; } if(soil_sensor!=NULL){ double *humidity2=gl_get_double_by_name(soil_sensor,"humidity"); humidity=*humidity2; } if(first_time==2) { if( irrigation_contr_object!=NULL) { if(actual_power>0) { //mpila mia fora gl_set_value_by_name(irrigation_contr_object,"insync","2"); actual_power_non_zero=actual_power.Re(); //system("pause"); } insync=gl_get_int16_by_name(irrigation_contr_object,"insync"); test3=gl_get_int16_by_name(irrigation_contr_object,"test"); if(*test3==1) { // printf("ewdw"); // system("pause"); base_power=prev_base_power; } clear_price=gl_get_double_by_name(auction_object,"current_market.clearing_price"); clear_quantity=gl_get_double_by_name(auction_object,"current_market.seller_total_quantity"); bid_price=gl_get_double_by_name(irrigation_contr_object,"bid_price"); bid_q=gl_get_double_by_name(irrigation_contr_object,"bid_quantity"); /* if(*bid_price>=*clear_price && (*bid_q)*3>=*clear_quantity)// && last_q<market->past_frame.clearing_quantity) { ///printf(" den "); base_power=prev_base_power; //printf("%f ----------------------------------",base_power); /// base_power=0; } else { base_power=0; }*/ } } /////////////////////////////////////////////////////////////////////////////////// if(choose_load==0) { // printf("den anrebazw nero \n"); //system("pause"); // actual_power=0; } if(choose_load==1) { if (demand_response_mode == true && next_time <= t1) { double dNon,dNoff; double hold_off; N_on = N_off = 0; for (int jj=0; jj<L; jj++) { //previous_drm.on[jj] = drm.on[jj]; //previous_drm.off[jj] = drm.off[jj]; if (eta > 0) { if (jj != (L-1)) dNon = -ron * drm.on[jj] + eta * drm.off[jj] + ron * drm.on[jj+1]; else dNon = -ron * drm.on[jj] + (1 - eta) * drm.off[jj] * roff + eta * drm.off[jj]; if (jj != 0) dNoff = -(1 - eta) * drm.off[jj] * roff - eta * drm.off[jj] + (1 - eta) * hold_off * roff; else dNoff = -(1 - eta) * drm.off[jj] * roff - eta * drm.off[jj] + ron * drm.on[jj]; } else { if (jj != (L-1)) dNon = -ron * (1 + eta) * drm.on[jj] + eta * drm.on[jj] + ron * (1 + eta) * drm.on[jj+1]; else dNon = -ron * (1 + eta) * drm.on[jj] + eta * drm.on[jj] + roff * drm.off[jj]; if (jj != 0) dNoff = -roff * drm.off[jj] - eta * drm.on[jj] + hold_off * roff; else dNoff = -roff * drm.off[jj] - eta * drm.on[jj] + ron * (1 + eta) * drm.on[jj]; } hold_off = drm.off[jj]; drm.on[jj] = drm.on[jj] + dNon; N_on += drm.on[jj]; drm.off[jj] = drm.off[jj] + dNoff; } N_off = N - N_on; phi = roff / (ron + roff); nominal_power = base_power * N_on / N; double R = ron; int dt = 0; if (ron < roff) R = roff; dt = int(1/R * 3600); next_time = t1 + dt; } // We're in duty cycle mode if (duty_cycle != -1) { double phase_shift = 0; if (first_pass == 0) // after first time step { phase_shift = (t1 - last_time) / (period * 3600); phase = phase + phase_shift; last_time = t1; } else first_pass = 0; last_time = t1; if (this->re_override == OV_NORMAL) // Normal operation { if (phase >= 1) phase = 0; // Track the time of 2 transistions if (t1 >= next_time || last_duty_cycle != duty_cycle) { if (duty_cycle > phase) // OFF->ON { multiplier = 1; next_time = t1 + (period * 3600) * (duty_cycle - phase) + 1; // +1 a bit of an offset for rounding } else // ON->OFF { multiplier = 0; next_time = t1 + (period * 3600) * (1 - phase) + 1; } } last_duty_cycle = duty_cycle; } else if (this->re_override == OV_OFF) // After release or recovery time { if (phase <= 1 && t1>=next_time) { this->re_override = OV_NORMAL; next_time = t1; } else if (t1 >= next_time || next_time == TS_NEVER) // we just came from override ON { if (recovery_duty_cycle > fmod(phase,1)) // OFF->ON { multiplier = 1; next_time = t1 + (period * 3600) * (recovery_duty_cycle - fmod(phase,1)) + 1; // +1 a bit of an offset for rounding if (duty_cycle != 0.0) phase -= 1 * recovery_duty_cycle / duty_cycle * (1 - fmod(phase,1)); // Track everything by the original duty cycle else phase = 0; //Start over /*if (phase < 0) { next_time = t1 + (period * 3600) * (recovery_duty_cycle - 0) + 1; phase = 0; }*/ } else // ON->OFF { //if (multiplier == 1) // we just transitioned //{ //if (phase >= 1 * recovery_duty_cycle / duty_cycle) // phase -= 1 * recovery_duty_cycle / duty_cycle; // Track everything by the original duty cycle //else if (phase < 1) // this->re_override = OV_NORMAL; //} multiplier = 0; next_time = t1 + (period * 3600) * (1 - fmod(phase,1)) + 1; } } last_duty_cycle = duty_cycle; } else // override is ON, so no power { if (multiplier == 1 && duty_cycle > phase) { // do nothing last_duty_cycle = duty_cycle; } else { multiplier = 0; next_time = TS_NEVER; if (recovery_duty_cycle > 0) // in TOU/CPP mode last_duty_cycle = duty_cycle; else // DLC mode { if (phase >= 1) phase -= 1; last_duty_cycle = 0; } } } // last_duty_cycle = duty_cycle; } if (pCircuit!=NULL){ if (is_240) { load.voltage_factor = pCircuit->pV->Mag() / 240; // update voltage factor - not really used for anything } else //120 { load.voltage_factor = pCircuit->pV->Mag() / 120; // update voltage factor - not really used for anything } } t2 = residential_enduse::sync(t0,t1); if (pCircuit->status==BRK_CLOSED) { //All values placed as kW/kVAr values - to be consistent with other loads double demand_power = multiplier * base_power; if (demand_response_mode == true) demand_power = nominal_power; if (heatgain_only == false) { //Calculate power portion real_power = demand_power * load.power_fraction; imag_power = (power_pf == 0.0) ? 0.0 : real_power * sqrt(1.0/(power_pf * power_pf) - 1.0); if (power_pf < 0) { imag_power *= -1.0; //Adjust imaginary portion for negative PF } load.power.SetRect(real_power,imag_power); //Calculate current portion real_power = demand_power * load.current_fraction; imag_power = (current_pf == 0.0) ? 0.0 : real_power * sqrt(1.0/(current_pf * current_pf) - 1.0); if (current_pf < 0) { imag_power *= -1.0; //Adjust imaginary portion for negative PF } load.current.SetRect(real_power,imag_power); //Calculate impedance portion real_power = demand_power * load.impedance_fraction; imag_power = (impedance_pf == 0.0) ? 0.0 : real_power * sqrt(1.0/(impedance_pf * impedance_pf) - 1.0); if (impedance_pf < 0) { imag_power *= -1.0; //Adjust imaginary portion for negative PF } load.admittance.SetRect(real_power,imag_power); //Put impedance in admittance. From a power point of view, they are the same //Compute total power - not sure if needed, but will use below load.total = load.power + load.current + load.admittance; if(first_time==2) { if(*test3==2) { actual_power.Re()=actual_power_non_zero; } } actual_power = load.power + load.current * load.voltage_factor + load.admittance * load.voltage_factor * load.voltage_factor; //Update power factor, just in case angleval = load.total.Arg(); load.power_factor = (angleval < 0) ? -1.0 * cos(angleval) : cos(angleval); //Determine the heat contributions - percentage of real power load.heatgain = load.total.Re() * load.heatgain_fraction * BTUPHPKW; } else { load.power = load.current = load.admittance = actual_power = load.total = 0.0; load.heatgain = demand_power * BTUPHPKW; return TS_NEVER; } } else //Breaker's open - nothing happens { load.total = 0.0; load.power = 0.0; load.current = 0.0; load.admittance = 0.0; load.heatgain = 0.0; load.power_factor = 0.0; } } if (next_time < t2 && next_time > 0) t2 = next_time; ///////////////////estimate if i satisfied from market///////////////////////////// if( irrigation_contr_object!=NULL) { int16 *insync=gl_get_int16_by_name(irrigation_contr_object,"insync"); if(*insync==2&&only_once==1) { actual_power_non_zero=actual_power.Re(); only_once=2; gl_set_value_by_name(irrigation_contr_object,"insync","2"); } } return t2; }
TIMESTAMP irrigation_controller::sync(TIMESTAMP t0, TIMESTAMP t1){ double bid = -1.0; int64 no_bid = 0; // flag gets set when the current temperature drops in between the the heating setpoint and cooling setpoint curves double demand = 0.0; double rampify = 0.0; extern double bid_offset; double deadband_shift = 0.0; double shift_direction = 0.0; double shift_setpoint = 0.0; double prediction_ramp = 0.0; double prediction_range = 0.0; double midpoint = 0.0; OBJECT *hdr = OBJECTHDR(this); if(insync==0) { insync=2; } else if(insync==2) { x=gl_get_double_by_name(parent2,"actual_power_non_zero"); // printf("%d %f ",parent2->id,*x); //system("pause"); insync=1; pDemand=x; initial_zipload_power=x; } if(first_period==0) //for two diffrent periods { //OBJECT *p=gl_get_object("sensor"); // double *humidity=gl_get_double_by_name(p,"humidity"); double *humidity=gl_get_double_by_name(soil_sensor,"humidity"); *pMonitor =*humidity; //printf("irrigaiton:%d %f \n",soil_sensor->id,*pMonitor); // system("pause"); //printf("%f %f",*pMonitor,setpoint0); //system("pause"); /* short circuit if the state variable doesn't change during the specified interval */ if((t1 < next_run) && (market->market_id == lastmkt_id)){ if(t1 <= next_run - bid_delay){ if(use_predictive_bidding == TRUE && ((control_mode == CN_RAMP && last_setpoint != setpoint0) || (control_mode == CN_DOUBLE_RAMP && (last_heating_setpoint != heating_setpoint0 || last_cooling_setpoint != cooling_setpoint0)))) { ; } else {// check to see if we have changed states if(pState == 0){ return next_run; } else if(*pState == last_pState){ return next_run; } } } else { return next_run; } } if(use_predictive_bidding == TRUE){ deadband_shift = *pDeadband * 0.5; } if(control_mode == CN_RAMP){ // if market has updated, continue onwards if(market->market_id != lastmkt_id){// && (*pAvg == 0.0 || *pStd == 0.0 || setpoint0 == 0.0)){ //printf("EDWWWWWWWWWWWWWWWWWWW\n"); //system("pause"); lastmkt_id = market->market_id; lastbid_id = -1; // clear last bid id, refers to an old market // update using last price // T_set,a = T_set + (P_clear - P_avg) * | T_lim - T_set | / (k_T * stdev24) clear_price = market->current_frame.clearing_price; if(use_predictive_bidding == TRUE){ if((dir > 0 && clear_price < last_p) || (dir < 0 && clear_price > last_p)){ shift_direction = -1; } else if((dir > 0 && clear_price >= last_p) || (dir < 0 && clear_price <= last_p)){ shift_direction = 1; } else { shift_direction = 0; } } if(fabs(*pStd) < bid_offset){ set_temp = setpoint0; } else if(clear_price < *pAvg && range_low != 0){ set_temp = setpoint0 + (clear_price - *pAvg) * fabs(range_low) / (ramp_low * *pStd) + deadband_shift*shift_direction; } else if(clear_price > *pAvg && range_high != 0){ set_temp = setpoint0 + (clear_price - *pAvg) * fabs(range_high) / (ramp_high * *pStd) + deadband_shift*shift_direction; } else { set_temp = setpoint0 + deadband_shift*shift_direction; } if((use_override == OU_ON) && (pOverride != 0)){ if(clear_price <= last_p){ // if we're willing to pay as much as, or for more than the offered price, then run. *pOverride = 1; } else { *pOverride = -1; } } // clip if(set_temp > max){ set_temp = max; } else if(set_temp < min){ set_temp = min; } *pSetpoint = set_temp; //gl_verbose("irrigation_controller::postsync(): temp %f given p %f vs avg %f",set_temp, market->next.price, market->avg24); } if(dir > 0){ //edw mpainei if(use_predictive_bidding == TRUE){ if(*pState == 0 && *pMonitor > (max - deadband_shift)){ bid = market->pricecap; } else if(*pState != 0 && *pMonitor < (min + deadband_shift)){ bid = 0.0; no_bid = 1; } else if(*pState != 0 && *pMonitor > max){ bid = market->pricecap; } else if(*pState == 0 && *pMonitor < min){ bid = 0.0; no_bid = 1; } } else { if(*pMonitor > max){ // printf("sto max"); bid = market->pricecap; } else if (*pMonitor < min){ // printf("sto min"); bid = -1.0; no_bid = 0; } } } else if(dir < 0){ if(use_predictive_bidding == TRUE){ if(*pState == 0 && *pMonitor < (min + deadband_shift)){ bid = market->pricecap; } else if(*pState != 0 && *pMonitor > (max - deadband_shift)){ bid = 0.0; no_bid = 1; } else if(*pState != 0 && *pMonitor < min){ bid = market->pricecap; } else if(*pState == 0 && *pMonitor > max){ bid = 0.0; no_bid = 1; } } else { if(*pMonitor < min){ bid = market->pricecap; } else if (*pMonitor > max){ bid = 0.0; no_bid = 0; } } } else if(dir == 0){ if(use_predictive_bidding == TRUE){ if(direction == 0.0) { gl_error("the variable direction did not get set correctly."); } else if((*pMonitor > max + deadband_shift || (*pState != 0 && *pMonitor > min - deadband_shift)) && direction > 0){ bid = market->pricecap; } else if((*pMonitor < min - deadband_shift || (*pState != 0 && *pMonitor < max + deadband_shift)) && direction < 0){ bid = market->pricecap; } else { bid = 0.0; no_bid = 0; } } else { if(*pMonitor < min){ bid = market->pricecap; } else if(*pMonitor > max){ bid = 0.0; no_bid = 0; } else { bid = *pAvg; } } } // calculate bid price //printf("%f,monitor:%f,min:%f max:%f, setpoint:%f\n",*humidity,*pMonitor,min,max,setpoint0); if(*pMonitor > setpoint0){ k_T = ramp_low; T_lim = range_low; bid=0; // printf("values : %f %f %f \n",bid,k_T, T_lim ); } else if(*pMonitor < setpoint0) { //printf("right_side "); k_T = ramp_low; T_lim = range_low; //printf("values : %f %f %f \n",bid,k_T, T_lim ); ///////////////////close all the controllers//////////////////////////// static FINDLIST *xt1=NULL; xt1=gl_find_objects(FL_NEW,FT_CLASS,SAME,"controller",FT_END); OBJECT *firstt1= gl_find_next(xt1,NULL); OBJECT *it1; for(it1=firstt1;it1!=NULL;it1=it1->next) { if(gl_object_isa(it1,"controller")) { gl_set_value_by_name(it1,"second_period_for_market","1") ; } } ////////////////////////////////////////////////////////////////////////////////// } else { k_T = 0.0; T_lim = 0.0; } if(bid < 0.0 && *pMonitor != setpoint0) { gl_set_value_by_name(soil_sensor,"irrigate_flag","1"); last_q = *initial_zipload_power; *pDemand =*initial_zipload_power; bid = *pAvg + ( (fabs(*pStd) < bid_offset) ? 0.0 : (*pMonitor - setpoint0) * (k_T * *pStd) / fabs(T_lim) ); //printf("price:%f %f %f %f\n",bid,(*pMonitor - setpoint0) ,(k_T * *pStd) , fabs(T_lim)); ////////////////////////////////////// char x_position_string[1024]; double *prev=gl_get_double_by_name(parent2,"prev_base_power"); double pos_x = *prev; sprintf(x_position_string, "%f", pos_x); gl_set_value_by_name(parent2,"base_power",x_position_string); ///////////////////////////////////// } else if(*pMonitor == setpoint0) { bid = *pAvg; } else { last_q=0; gl_set_value_by_name(parent2,"base_power","0"); } // bid the response part of the load double residual = *pTotal; /* WARNING ~ bid ID check will not work properly */ KEY bid_id = (KEY)(lastmkt_id == market->market_id ? lastbid_id : -1); // override //bid_id = -1; if(last_q > 0 && no_bid != 1){ last_p = bid; last_q= *initial_zipload_power; //if(last_p < 0) //{ //last_p=clear_price; //} if(0 != strcmp(market->unit, "")){ if(0 == gl_convert("kW", market->unit, &(last_q))){ gl_error("unable to convert bid units from 'kW' to '%s'", market->unit.get_string()); return TS_INVALID; } } //lastbid_id = market->submit(OBJECTHDR(this), -last_q, last_p, bid_id, (BIDDERSTATE)(pState != 0 ? *pState : 0)); if(pState != 0){ lastbid_id = submit_bid_state(pMarket, hdr, -last_q, last_p, (*pState > 0 ? 1 : 0), bid_id); } else { lastbid_id = submit_bid(pMarket, hdr, -last_q, last_p, bid_id); } residual -= *pLoad; } else { last_p = 0; last_q = 0; gl_verbose("%s's is not bidding", hdr->name); } if(residual < -0.001) gl_warning("irrigation_controller:%d: residual unresponsive load is negative! (%.1f kW)", hdr->id, residual); } if (pState != 0) last_pState = *pState; char timebuf[128]; gl_printtime(t1,timebuf,127); return TS_NEVER; //} } //end of first_period==0 }
TIMESTAMP irrigation_controller::presync(TIMESTAMP t0, TIMESTAMP t1){ //two different periods if(first_time==0) { first_time=t1; } if(gl_todays(t1)-gl_todays(first_time)==2) { first_period=1; static FINDLIST *xt1=NULL; xt1=gl_find_objects(FL_NEW,FT_CLASS,SAME,"controller",FT_END); OBJECT *firstt1= gl_find_next(xt1,NULL); OBJECT *it1; for(it1=firstt1;it1!=NULL;it1=it1->next) { if(gl_object_isa(it1,"controller")) { gl_set_value_by_name(it1,"second_period_for_market","1") ; } } } if(slider_setting < -0.001) slider_setting = 0.0; if(slider_setting_heat < -0.001) slider_setting_heat = 0.0; if(slider_setting_cool < -0.001) slider_setting_cool = 0.0; if(slider_setting > 1.0) slider_setting = 1.0; if(slider_setting_heat > 1.0) slider_setting_heat = 1.0; if(slider_setting_cool > 1.0) slider_setting_cool = 1.0; if(control_mode == CN_RAMP && setpoint0 == -1) setpoint0 = *pSetpoint; // auto tha einai to orio gia to humidity to setpoint pou tha vazei o xristis if(control_mode == CN_RAMP){ if (slider_setting == -0.001){ min = setpoint0 + range_low; max = setpoint0 + range_high; } else if(slider_setting > 0){ min = setpoint0 + range_low * slider_setting; max = setpoint0 + range_high * slider_setting; if(range_low != 0) ramp_low = 2 + (1 - slider_setting); else ramp_low = 0; if(range_high != 0) ramp_high = 2 + (1 - slider_setting); else ramp_high = 0; } else { min = setpoint0; max = setpoint0; } } if((thermostat_mode != TM_INVALID && thermostat_mode != TM_OFF) || t1 >= time_off) last_mode = thermostat_mode; else if(thermostat_mode == TM_INVALID) last_mode = TM_OFF;// this initializes last mode to off if(thermostat_mode != TM_INVALID) previous_mode = thermostat_mode; else previous_mode = TM_OFF; return TS_NEVER; }
void setObjectValue_Char(OBJECT* obj, char* Property, char* value) { gl_set_value_by_name(obj,Property,value); }
void setObjectValue_Double2Complex(OBJECT* obj, char* Property, double Re, double Im) { char buffer[1024]; snprintf(buffer,sizeof(buffer),"%g+%gj",Re,Im); gl_set_value_by_name(obj,Property,buffer); }