DSO+T Agent Bidding and Sliders
This document seeks to capture all the ways that we’ve modeled the interation of agents and slider settings in the DSO+T work. Specifically, we’re concerned how the slider setting impacts customer flexibility. As part of this, a brief overview of the four-point bidding formulation used in DSO+T will also be discussed followed by a summary of the actual code implemented to allow the impact on slider settings.
The “slider” is the co-efficient of flexibility (between 0 and 1, inclusive) that is used to define how sensitive a customer or device agent (controller) is price. Generally:
slider = 1 - Maximum flexibility, prioritizes cost over comfort
slider = 0 - Minimum flexibility, prioritizes comfort over cost
In the DSO+T analysis, slider settings were randomly assigned to each customer and all participating devices (e.g. HVACs, EV Chargers) inherited that slider setting.
DSO+T Four-Point Bidding
As covered well in the DSO+T Transactive Mechanism report, all the agents participating in the market created a “four-point bid”; that is, a bid consisting of four price-quantity pairs (eight values in total) that were able to be interpretted to comprehensively define their price-responsiveness. Two of these points define the price-quantity limits for the bid. A convention was established to interpret the bid curve beyond these points; prices lower than Pmin have a quantity capped at Qmax and prices higher than Pmax have a quantity of Qmin. Qmin is generally zero for flexible loads but may be a negative value for EVs and batteries as they are able to supply energy.
The central two points in the four-point bid are used to define a deadband in the price-responsiveness; cleared prices within this band will not adjust the cleared quantity and thus the operating state of the device. This deadband is helpful in reaching convergence over multiple bidding periods in the iterative retail day-ahead market. This deadband may have a slight slope to it.
Fig. 60 Generic load four-point bid; loads are never able to have a negative bid quantity as they only consume electrical energy.
Fig. 61 Generic battery or EV (V2G) four-point bid with negative bid quantities as they are able to supply electrical energy.
Converting Between Bid Quantity and Device Amenity Setting
For the HVAC and water heaters, once informed of a cleared price the device needs to convert this into an amenity setting: a thermostat setpoint. (For batteries and EVs, the amenity is charging or discharging power and thus the cleared quantity can be used to directly set these values.) Directly from the report
Using the retail real-time market-cleared price and the asset agent’s bid curve, the HVAC’s cleared quantity is extracted. To convert the cleared quantity into a temperature setpoint, an HVAC energy quantity versus temperature setpoint mapping curve is needed.
Fig. 62 Example of the translation of cleared quantity to a thermostat setpoint performed by the HVAC agent.
The slider setting itself is also used in defining the conversion between the cleared price and the thermostat setting
Agent Configuration
HVAC agent
HVAC agents are instatiated in substation.py (l. 248) and it pulls in it’s configuration from the hvac object in the config dictionary. This dictionary is loaded from “…_agent_dict.json”. This dictionary defines the following values used by “hvac_agentp.py” to configure the hvac agent. The limit values shown are constant across all agents in the original DSOT while the slider value is randomized between zero and one.:
ramp_high_limit = 5
ramp_low_limit = 5
range_high_limit = 5
range_low_limit = 3
slider = [0,1]
Agent Implementations
For each of the agents used in the DSO+T study, a section below outlines where the slider setting is used in the agent code
EV Agent
DSO+T EV agent code is found on Github.
Sets the required departure-from-home charge:
self.home_depart_soc = self.Cmax + (just_enough_soc - self.Cmax) * self.slider
Contributes to the objective function used in forming the DA bids (optimization problem):
return sum( self.slider * self.f_DA[i] * (m.E_DA_out[i] - m.E_DA_in[i]) - self.slider * self.batteryLifeDegFactor * (1 + self.profit_margin) * (m.E_DA_out[i] + m.E_DA_in[i]) - self.quad_fac * (m.E_DA_out[i] + m.E_DA_in[i]) ** 2 for i in self.TIME) - sum((1 - self.slider) * 0.001 * (self.home_depart_soc - m.C[i]) for i in self.trans_hours)
Determines the price-responsiveness (slope) when formulating real-time bids:
CurveSlope = ((max(self.f_DA) - min(self.f_DA)) / (-self.Rd - self.Rc)) / self.slider
Battery Agent
DSO+T Battery agent code is found on Github.
Determines the price-responsiveness (slope) when formulating day-ahead bids
CurveSlope[t] = ((max(self.f_DA) - min(self.f_DA)) / (-self.Rd - self.Rc)) / self.slider
Determines the price-responsiveness (slope) when formulating the real-time bids:
CurveSlope = ((max(self.f_DA) - min(self.f_DA)) / (-self.Rd - self.Rc)) / self.slider
HVAC Agent
DSO+T HVAC agent code is found on Github.
The slider setting for the agent is used in the following ways in the agent code:
Initializing the ProfitMargin_slope:
self.ProfitMargin_slope = delta_DA_price / (Qmin - Qmax) / self.slider
which is used in formulating the real-time bid:
CurveSlope = (delta_DA_price / (0 - self.hvac_kw) * (1 + self.ProfitMargin_slope / 100))
and the day-ahead bid:
CurveSlope[t] = (delta_DA_price / (0 - self.hvac_kw) * (1 + self.ProfitMargin_slope / 100))
Setting thermostat temperature limits:
self.range_high_cool = self.range_high_limit * self.slider self.range_low_cool = self.range_low_limit * self.slider self.range_high_heat = self.range_high_limit * self.slider self.range_low_heat = self.range_low_limit * self.slider The range limits determine a customers `maximum and minimum acceptable temperatures <https://github.com/pnnl/tesp/blob/1dcd35e58124764504f4ccb4f38d2f784e0e066e/src/tesp_support/tesp_support/dsot/hvac_agent.py#L528>`_ :: self.temp_max_cool = cooling_setpt + self.range_high_cool # - self.ramp_high_limit * (1 - self.slider) self.temp_min_cool = cooling_setpt - self.range_low_cool # + self.ramp_low_limit * (1 - self.slider) self.temp_max_heat = heating_setpt + self.range_high_heat # - self.ramp_high_limit * (1 - self.slider) self.temp_min_heat = heating_setpt - self.range_low_heat # + self.ramp_low_limit * (1 - self.slider) These limits play a role in the `day-ahead energy market bidding <https://github.com/pnnl/tesp/blob/1dcd35e58124764504f4ccb4f38d2f784e0e066e/src/tesp_support/tesp_support/dsot/hvac_agent.py#L1099>`. There are multiple bidding strategies in forming the day-ahead energy market bids for the HVAC agent. Below is one but they are all constrained by this temperature limit:: elif use_DA_curve: if self.thermostat_mode == "Cooling": if self.cleared_price > self.price_forecast_0: setpoint_tmp = self.temp_room[0] + (self.cleared_price - self.price_forecast_0) * \ self.range_high_cool / self.price_delta elif self.cleared_price < self.price_forecast_0: setpoint_tmp = self.temp_room[0] + (self.cleared_price - self.price_forecast_0) * \ self.range_low_cool / self.price_deltaSetting the price-responsiveness of the thermostat setpoint temperature:
if self.slider != 0: # cooling self.ramp_high_cool = self.ramp_high_limit * (1 - self.slider) # 1+2*(1-self.slider) self.ramp_low_cool = self.ramp_low_limit * (1 - self.slider) # 1+2*(1-self.slider) # heating self.ramp_high_heat = self.ramp_low_limit * (1 - self.slider) # 1+2*(1-self.slider) self.ramp_low_heat = self.ramp_high_limit * (1 - self.slider) # 1+2*(1-self.slider)
Water Heater Agent
DSO+T water heater agent code is found on Github.
Determines the price-responsiveness (slope) when formulating day-ahead bids:
CurveSlope[t] = delta_DA_price / ((0 - self.Phw) * self.slider)