TIMESTAMP stub_bidder::sync(TIMESTAMP t0, TIMESTAMP t1) { if (t1==next_t || next_t==0) { // printf("\n\n %s %d %f\n\n\n\n\n",market->name,role,quantity); next_t=t1+(TIMESTAMP)bid_period; lastbid_id = (KEY)submit_bid(market,OBJECTHDR(this),role==BUYER?-quantity:quantity,price,*thismkt_id!=lastmkt_id?new_bid_id:lastbid_id); count--; lastmkt_id = *thismkt_id; /* if(change==2) { change=1; price=0; quantity=0; } */ } if (count>0) return next_t; else return TS_NEVER; }
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 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; OBJECT *hdr = OBJECTHDR(this); /* 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){ ; // continue } else { if (pState == 0) return next_run; else if (*pState == last_pState) return next_run; } } 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)){ double clear_price; 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(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); } else if(clear_price > *pAvg && range_high != 0){ set_temp = setpoint0 + (clear_price - *pAvg) * fabs(range_high) / (ramp_high * *pStd); } else { set_temp = setpoint0; } 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("controller::postsync(): temp %f given p %f vs avg %f",set_temp, market->next.price, market->avg24); } if(dir > 0){ if(*pMonitor > max){ bid = 9999.0; } else if (*pMonitor < min){ bid = 0.0; no_bid = 1; } } else if(dir < 0){ if(*pMonitor < min){ bid = 9999.0; } else if(*pMonitor > max){ bid = 0.0; no_bid = 1; } } else if(dir == 0){ if(*pMonitor < min){ bid = 9999.0; } else if(*pMonitor > max){ bid = 0.0; no_bid = 1; } else { bid = *pAvg; // override due to lack of "real" curve } } // calculate bid price if(*pMonitor > setpoint0){ k_T = ramp_high; T_lim = range_high; } else if(*pMonitor < setpoint0) { k_T = ramp_low; T_lim = range_low; } else { k_T = 0.0; T_lim = 0.0; } if(bid < 0.0 && *pMonitor != setpoint0) { bid = *pAvg + ( (fabs(*pStd) < bid_offset) ? 0.0 : (*pMonitor - setpoint0) * (k_T * *pStd) / fabs(T_lim) ); } else if(*pMonitor == setpoint0) { bid = *pAvg; } // 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(*pDemand > 0 && no_bid != 1){ last_p = bid; last_q = *pDemand; 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); 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("controller:%d: residual unresponsive load is negative! (%.1f kW)", hdr->id, residual); } else if (control_mode == CN_DOUBLE_RAMP){ /* double heat_range_high; double heat_range_low; double heat_ramp_high; double heat_ramp_low; double cool_range_high; double cool_range_low; double cool_ramp_high; double cool_ramp_low; */ DATETIME t_next; gl_localtime(t1,&t_next); // find crossover double midpoint = 0.0; if(cool_min - heat_max < *pDeadband){ switch(resolve_mode){ case RM_DEADBAND: midpoint = (heat_max + cool_min) / 2; if(midpoint - *pDeadband/2 < heating_setpoint0 || midpoint + *pDeadband/2 > cooling_setpoint0) { gl_error("The midpoint between the max heating setpoint and the min cooling setpoint must be half a deadband away from each base setpoint"); return TS_INVALID; } else { heat_max = midpoint - *pDeadband/2; cool_min = midpoint + *pDeadband/2; } break; case RM_SLIDING: if(heat_max > cooling_setpoint0 - *pDeadband) { gl_error("the max heating setpoint must be a full deadband less than the cooling_base_setpoint"); return TS_INVALID; } if(cool_min < heating_setpoint0 + *pDeadband) { gl_error("The min cooling setpoint must be a full deadband greater than the heating_base_setpoint"); return TS_INVALID; } if(last_mode == TM_OFF || last_mode == TM_COOL){ heat_max = cool_min - *pDeadband; } else if (last_mode == TM_HEAT){ cool_min = heat_max + *pDeadband; } break; default: gl_error("unrecognized resolve_mode when double_ramp overlap resolution is needed"); break; } } // if the market has updated, if(lastmkt_id != market->market_id){ lastmkt_id = market->market_id; lastbid_id = -1; // retrieve cleared price double clear_price; clear_price = market->current_frame.clearing_price; if(clear_price == last_p){ // determine what to do at the marginal price switch(market->clearing_type){ case CT_SELLER: // may need to curtail break; case CT_PRICE: // should not occur case CT_NULL: // q zero or logic error ~ should not occur // occurs during the zero-eth market. //gl_warning("clearing price and bid price are equal with a market clearing type that involves inequal prices"); break; default: break; } } may_run = 1; // calculate setpoints if(fabs(*pStd) < bid_offset){ *pCoolingSetpoint = cooling_setpoint0; *pHeatingSetpoint = heating_setpoint0; } else { if(clear_price > *pAvg){ *pCoolingSetpoint = cooling_setpoint0 + (clear_price - *pAvg) * fabs(cool_range_high) / (cool_ramp_high * *pStd); //*pHeatingSetpoint = heating_setpoint0 + (clear_price - *pAvg) * fabs(heat_range_high) / (heat_ramp_high * *pStd); *pHeatingSetpoint = heating_setpoint0 + (clear_price - *pAvg) * fabs(heat_range_low) / (heat_ramp_low * *pStd); } else if(clear_price < *pAvg){ *pCoolingSetpoint = cooling_setpoint0 + (clear_price - *pAvg) * fabs(cool_range_low) / (cool_ramp_low * *pStd); //*pHeatingSetpoint = heating_setpoint0 + (clear_price - *pAvg) * fabs(heat_range_low) / (heat_ramp_low * *pStd); *pHeatingSetpoint = heating_setpoint0 + (clear_price - *pAvg) * fabs(heat_range_high) / (heat_ramp_high * *pStd); } else { *pCoolingSetpoint = cooling_setpoint0; *pHeatingSetpoint = heating_setpoint0; } } // apply overrides if((use_override == OU_ON)){ if(last_q != 0.0){ if(clear_price == last_p && clear_price != market->pricecap){ if(market->margin_mode == AM_DENY){ *pOverride = -1; } else if(market->margin_mode == AM_PROB){ double r = gl_random_uniform(0, 1.0); if(r < market->current_frame.marginal_frac){ *pOverride = 1; } else { *pOverride = -1; } } } else if(market->current_frame.clearing_price <= last_p){ *pOverride = 1; } else { *pOverride = -1; } } else { // equality *pOverride = 0; // 'normal operation' } } //clip if(*pCoolingSetpoint > cool_max) *pCoolingSetpoint = cool_max; if(*pCoolingSetpoint < cool_min) *pCoolingSetpoint = cool_min; if(*pHeatingSetpoint > heat_max) *pHeatingSetpoint = heat_max; if(*pHeatingSetpoint < heat_min) *pHeatingSetpoint = heat_min; lastmkt_id = market->market_id; } // submit bids double previous_q = last_q; //store the last value, in case we need it last_p = 0.0; last_q = 0.0; // We have to cool if(*pMonitor > cool_max){ last_p = market->pricecap; last_q = *pCoolingDemand; } // We have to heat else if(*pMonitor < heat_min){ last_p = market->pricecap; last_q = *pHeatingDemand; } // We're floating in between heating and cooling else if(*pMonitor > heat_max && *pMonitor < cool_min){ last_p = 0.0; last_q = 0.0; } // We might heat, if the price is right else if(*pMonitor <= heat_max && *pMonitor >= heat_min){ double ramp, range; ramp = (*pMonitor > heating_setpoint0 ? heat_ramp_high : heat_ramp_low); range = (*pMonitor > heating_setpoint0 ? heat_range_high : heat_range_low); if(*pMonitor != cooling_setpoint0){ last_p = *pAvg + ( (fabs(*pStd) < bid_offset) ? 0.0 : (*pMonitor - heating_setpoint0) * ramp * (*pStd) / fabs(range) ); } else { last_p = *pAvg; } last_q = *pHeatingDemand; } // We might cool, if the price is right else if(*pMonitor <= cool_max && *pMonitor >= cool_min){ double ramp, range; ramp = (*pMonitor > cooling_setpoint0 ? cool_ramp_high : cool_ramp_low); range = (*pMonitor > cooling_setpoint0 ? cool_range_high : cool_range_low); if(*pMonitor != cooling_setpoint0){ last_p = *pAvg + ( (fabs(*pStd) < bid_offset) ? 0 : (*pMonitor - cooling_setpoint0) * ramp * (*pStd) / fabs(range) ); } else { last_p = *pAvg; } last_q = *pCoolingDemand; } if(last_p > market->pricecap) last_p = market->pricecap; if(last_p < -market->pricecap) last_p = -market->pricecap; 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); return TS_INVALID; } } if(last_q > 0.001){ if (pState != 0 ) { KEY bid = (KEY)(lastmkt_id == market->market_id ? lastbid_id : -1); lastbid_id = submit_bid_state(this->pMarket, OBJECTHDR(this), -last_q, last_p, (*pState > 0 ? 1 : 0), bid); } else { KEY bid = (KEY)(lastmkt_id == market->market_id ? lastbid_id : -1); lastbid_id = submit_bid(this->pMarket, OBJECTHDR(this), -last_q, last_p, bid); } } else { if (last_pState != *pState) { KEY bid = (KEY)(lastmkt_id == market->market_id ? lastbid_id : -1); double my_bid = -market->pricecap; if (*pState != 0) my_bid = last_p; lastbid_id = submit_bid_state(this->pMarket, OBJECTHDR(this), -last_q, my_bid, (*pState > 0 ? 1 : 0), bid); } } } if (pState != 0) last_pState = *pState; char timebuf[128]; gl_printtime(t1,timebuf,127); //gl_verbose("controller:%i::sync(): bid $%f for %f kW at %s",hdr->id,last_p,last_q,timebuf); //return postsync(t0, t1); return TS_NEVER; }