Beispiel #1
0
 def create_demand_curve(self, index):
     hvac_index = self.determine_hvac_index(index)
     demand_curve = PolyLine()
     oat = self.oat_predictions[index] if self.oat_predictions else self.tOut
     prices = self.determine_prices()
     price_max_bound = max(
         max(prices) + 0.1 * max(prices),
         max(self.prices) + max(self.prices) * 0.1)
     price_min_bound = min(
         min(prices) + 0.1 * min(prices),
         min(self.prices) - min(self.prices) * 0.1)
     temp = self.temp[index]
     quantities = []
     for i in range(len(prices)):
         if self.hvac_avail[hvac_index]:
             temp_stpt = self.tsets[i]
         else:
             temp_stpt = self.tMinAdjUnoc
         quantity = min(
             max(self.getM(oat, temp, temp_stpt, hvac_index), self.mDotMin),
             self.mDotMax)
         quantities.append(quantity)
     demand_curve.add(Point(price=price_max_bound,
                            quantity=min(quantities)))
     prices.sort(reverse=True)
     quantities.sort()
     for i in range(len(prices)):
         demand_curve.add(Point(price=prices[i], quantity=quantities[i]))
     demand_curve.add(Point(price=price_min_bound,
                            quantity=max(quantities)))
     _log.debug("{} debug demand_curve4 - curve: {}".format(
         self.agent_name, demand_curve.points))
     _log.debug("{} market {} has cleared airflow: {}".format(
         self.agent_name, index, demand_curve.x(self.prices[index])))
     return demand_curve
Beispiel #2
0
class LightAgent(MarketAgent, FirstOrderZone):
    """
    The SampleElectricMeterAgent serves as a sample of an electric meter that
    sells electricity for a single building at a fixed price.
    """
    def __init__(self, market_name, agent_name, k, qmax, Pabsnom,
                 nonResponsive, verbose_logging, subscribing_topic, **kwargs):
        super(LightAgent, self).__init__(verbose_logging, **kwargs)
        self.market_name = market_name
        self.agent_name = agent_name
        self.k = k
        self.qmax = qmax
        self.Pabsnom = Pabsnom
        self.nonResponsive = nonResponsive
        self.iniState()
        self.subscribing_topic = subscribing_topic
        self.join_market(self.market_name, BUYER, None, self.offer_callback,
                         None, self.price_callback, self.error_callback)

    @Core.receiver('onstart')
    def setup(self, sender, **kwargs):
        _log.debug('Subscribing to ' + 'devices/CAMPUS/BUILDING1/AHU1/all')
        self.vip.pubsub.subscribe(peer='pubsub',
                                  prefix='devices/CAMPUS/BUILDING1/AHU1/all',
                                  callback=self.updateState)

    def offer_callback(self, timestamp, market_name, buyer_seller):
        result, message = self.make_offer(market_name, buyer_seller,
                                          self.create_demand_curve())
        _log.debug("results of the make offer {}".format(result))
        if not result:
            _log.debug("the new lightingt (maintain{}".format(self.qMax))
            gevent.sleep(random.random())
            self.vip.rpc.call('platform.actuator', 'set_point',
                              self.agent_name,
                              self.subscribing_topic + '/' + self.agent_name,
                              round(self.qNorm, 2)).get(timeout=6)

    def create_demand_curve(self):
        self.demand_curve = PolyLine()
        pMin = 10
        pMax = 100

        if (self.hvacAvail > 0):
            self.demand_curve.add(
                Point(price=min(pMin, pMax),
                      quantity=max(self.qMin, self.qMax) * self.Pabsnom))
            self.demand_curve.add(
                Point(price=max(pMin, pMax),
                      quantity=min(self.qMin, self.qMax) * self.Pabsnom))
        else:
            self.demand_curve.add(Point(price=max(pMin, pMax), quantity=0))
            self.demand_curve.add(Point(price=min(pMin, pMax), quantity=0))
        return self.demand_curve

    def iniState(self):
        self.hvacAvail = 1
        self.pClear = None
        self.qMin = 0.7
        self.qMax = self.qmax
        self.qNorm = self.qMax
        self.qClear = self.qNorm

    def updateState(self, peer, sender, bus, topic, headers, message):
        '''Subscribe to device data from message bus
        '''
        _log.debug('Received one new dataset')
        info = message[0].copy()
        self.hvacAvail = info['SupplyFanStatus']
        if (self.hvacAvail > 0):
            self.qNorm = self.qMax
        else:
            self.qNorm = 0

    def updateSet(self):
        if self.pClear is not None and not self.nonResponsive and self.hvacAvail:
            self.qClear = self.clamp(self.demand_curve.x(self.pClear),
                                     self.qMax, self.qMin)
        else:
            self.qClear = 0


#        if self.qClear is None:
#            self.qClear = 0.

    def clamp(self, value, x1, x2):
        minValue = min(x1, x2)
        maxValue = max(x1, x2)
        return min(max(value, minValue), maxValue)

    def price_callback(self, timestamp, market_name, buyer_seller, price,
                       quantity):
        _log.debug("the price is {}".format(price))
        self.pClear = price
        if self.pClear is not None:
            self.updateSet()
            _log.debug("the new lightingt is {}".format(self.qClear))
            gevent.sleep(random.random())
            self.vip.rpc.call('platform.actuator', 'set_point',
                              self.agent_name,
                              self.subscribing_topic + '/' + self.agent_name,
                              round(self.qClear, 2)).get(timeout=5)

    def error_callback(self, timestamp, market_name, buyer_seller, error_code,
                       error_message, aux):
        _log.debug("the new lightingt is {}".format(self.qNorm))
        self.vip.rpc.call('platform.actuator', 'set_point', self.agent_name,
                          self.subscribing_topic + '/' + self.agent_name,
                          round(self.qNorm, 2)).get(timeout=5)

    def ease(self, target, current, limit):
        return current - np.sign(current - target) * min(
            abs(current - target), abs(limit))
Beispiel #3
0
class VAVAgent(MarketAgent, FirstOrderZone):
    """
    The SampleElectricMeterAgent serves as a sample of an electric meter that
    sells electricity for a single building at a fixed price.
    """

    def __init__(self, market_name, agent_name, x0, x1, x2, x3, x4, c0, c1, c2, c3, c4,
                 tMinAdj, tMaxAdj, mDotMin, mDotMax, tIn, nonResponsive, verbose_logging,
                 device_topic, device_points, parent_device_topic, parent_device_points,
                 base_rpc_path, activate_topic, actuator, mode, setpoint_mode, sim_flag, **kwargs):
        super(VAVAgent, self).__init__(verbose_logging, **kwargs)
        self.market_name = market_name
        self.agent_name = agent_name
        self.x0 = x0
        self.x1 = x1
        self.x2 = x2
        self.x3 = x3
        self.x4 = x4
        self.c0 = c0
        self.c1 = c1
        self.c2 = c2
        self.c3 = c3
        self.c4 = c4
        self.hvac_avail = 0
        self.tOut = 32
        self.zone_airflow = 10
        self.zone_datemp = 12.78
        self.tDel = 0.25
        self.t_ease = 0.25
        self.tNomAdj = tIn
        self.temp_stpt = self.tNomAdj
        self.tIn = self.tNomAdj
        self.p_clear = None
        self.q_clear = None
        self.demand_curve = None
        self.tMinAdj = tMinAdj
        self.tMaxAdj = tMaxAdj
        self.mDotMin = mDotMin
        self.mDotMax = mDotMax
        self.qHvacSens = self.zone_airflow * 1006. * (self.zone_datemp - self.tIn)
        self.qMin = min(0, self.mDotMin * 1006. * (self.zone_datemp - self.tIn))
        self.qMax = min(0, self.mDotMax * 1006. * (self.zone_datemp - self.tIn))

        self.default = None
        self.actuator = actuator
        self.mode = mode
        self.nonResponsive = nonResponsive
        self.sim_flag = sim_flag

        if self.sim_flag:
            self.actuate_enabled = 1
        else:
            self.actuate_enabled = 0

        self.setpoint_offset = 0.0

        if isinstance(setpoint_mode, dict):
            self.mode_status = True
            self.status_point = setpoint_mode["point"]
            self.setpoint_mode_true_offset = setpoint_mode["true_value"]
            self.setpoint_mode_false_offset = setpoint_mode["false_value"]
        else:
            self.mode_status = False

        self.device_topic = device_topic
        self.parent_device_topic = parent_device_topic
        self.actuator_topic = base_rpc_path
        self.activate_topic = activate_topic
        # Parent device point mapping (AHU level points)
        self.supply_fan_status = parent_device_points.get("supply_fan_status", "SupplyFanStatus")
        self.outdoor_air_temperature = parent_device_points.get("outdoor_air_temperature", "OutdoorAirTemperature")

        # Device point mapping (VAV level points)
        self.zone_datemp_name = device_points.get("zone_dat", "ZoneDischargeAirTemperature")
        self.zone_airflow_name = device_points.get("zone_airflow", "ZoneAirFlow")
        self.zone_temp_name = device_points.get("zone_temperature", "ZoneTemperature")

        self.join_market(self.market_name, BUYER, None, self.offer_callback, None, self.price_callback, self.error_callback)

    @Core.receiver('onstart')
    def setup(self, sender, **kwargs):
        _log.debug('Subscribing to device' + self.device_topic)
        self.vip.pubsub.subscribe(peer='pubsub',
                                  prefix=self.device_topic,
                                  callback=self.update_zone_state)
        _log.debug('Subscribing to parent' + self.parent_device_topic)
        self.vip.pubsub.subscribe(peer='pubsub',
                                  prefix=self.parent_device_topic,
                                  callback=self.update_state)
        _log.debug('Subscribing to ' + self.activate_topic)
        self.vip.pubsub.subscribe(peer='pubsub',
                                  prefix=self.activate_topic,
                                  callback=self.update_actuation_state)

    def offer_callback(self, timestamp, market_name, buyer_seller):
        result, message = self.make_offer(market_name, buyer_seller, self.create_demand_curve())
        _log.debug("{}: demand max {} and min {} at {}".format(self.agent_name,
                                                               -self.demand_curve.x(10),
                                                               -self.demand_curve.x(100),
                                                               timestamp))
        _log.debug("{}: result of the make offer {} at {}".format(self.agent_name,
                                                                  result,
                                                                  timestamp))
        if not result:
            _log.debug("{}: maintain old set point {}".format(self.agent_name,
                                                              self.temp_stpt))
            if self.sim_flag:
                self.actuate_setpoint()

    def create_demand_curve(self):
        self.demand_curve = PolyLine()
        p_min = 10.
        p_max = 100.
        qMin = abs(self.get_q_min())
        qMax = abs(self.get_q_max())
        if self.hvac_avail:
            self.demand_curve.add(Point(price=max(p_min, p_max), quantity=min(qMin, qMax)))
            self.demand_curve.add(Point(price=min(p_min, p_max), quantity=max(qMin, qMax)))
        else:
            self.demand_curve.add(Point(price=max(p_min, p_max), quantity=0.1))
            self.demand_curve.add(Point(price=min(p_min, p_max), quantity=0.1))
        if self.hvac_avail:
            _log.debug("{} - Tout {} - Tin {} - q {}".format(self.agent_name, self.tOut, self.tIn, self.qHvacSens))
        return self.demand_curve

    def update_zone_state(self, peer, sender, bus, topic, headers, message):
        """
        Subscribe to device data from message bus
        :param peer:
        :param sender:
        :param bus:
        :param topic:
        :param headers:
        :param message:
        :return:
        """
        _log.debug('{} received zone info'.format(self.agent_name))
        info = message[0]

        if not self.sim_flag:
            self.zone_datemp = temp_f2c(info[self.zone_datemp_name])
            self.zone_airflow = flow_cfm2cms(info[self.zone_airflow_name])
            self.tIn = temp_f2c(info[self.zone_temp_name])
        else:
            self.zone_datemp = info[self.zone_datemp_name]
            self.zone_airflow = info[self.zone_airflow_name]
            self.tIn = info[self.zone_temp_name]

        if self.mode_status:
            if info[self.status_point]:
                self.setpoint_offset = self.setpoint_mode_true_offset
                _log.debug("Setpoint offset: {}".format(self.setpoint_offset))
            else:
                self.setpoint_offset = self.setpoint_mode_false_offset
                _log.debug("Setpoint offset: {}".format(self.setpoint_offset))

        self.qHvacSens = self.zone_airflow * 1006. * (self.zone_datemp - self.tIn)
        self.qMin = min(0, self.mDotMin * 1006. * (self.zone_datemp - self.tIn))
        self.qMax = min(0, self.mDotMax * 1006. * (self.zone_datemp - self.tIn))

    def update_state(self, peer, sender, bus, topic, headers, message):
        """
        Subscribe to device data from message bus.
        :param peer:
        :param sender:
        :param bus:
        :param topic:
        :param headers:
        :param message:
        :return:
        """
        _log.debug('{} received one parent_device '
                   'information on: {}'.format(self.agent_name, topic))
        info = message[0]
        if not self.sim_flag:
            self.tOut = temp_f2c(info[self.outdoor_air_temperature])
        else:
            self.tOut = info[self.outdoor_air_temperature]
        self.hvac_avail = info[self.supply_fan_status]

    def update_actuation_state(self, peer, sender, bus, topic, headers, message):
        """
        Subscribe to device data from message bus.
        :param peer:
        :param sender:
        :param bus:
        :param topic:
        :param headers:
        :param message:
        :return:
        """
        _log.debug('{} received update actuation.'.format(self.agent_name))
        _log.debug("Current actuation state: {} - '"
                   "update actuation state: {}".format(self.actuate_enabled, message))
        if not self.actuate_enabled and message:
            self.default = self.vip.rpc.call(self.actuator, 'get_point', self.actuator_topic).get(timeout=10)
        self.actuate_enabled = message
        if not self.actuate_enabled:
            if self.mode == 1:
                self.vip.rpc.call(self.actuator, 'set_point', self.agent_name, self.actuator_topic, None).get(timeout=10)
            else:
                if self.default is not None:
                    self.vip.rpc.call(self.actuator, 'set_point', self.agent_name, self.actuator_topic, self.default).get(timeout=10)

    def update_setpoint(self):
        if self.p_clear is not None and not self.nonResponsive and self.hvac_avail:
            self.q_clear = clamp(-self.demand_curve.x(self.p_clear), self.qMax, self.qMin)
            self.temp_stpt = clamp(self.getT(self.q_clear), self.tMinAdj, self.tMaxAdj)
        else:
            self.temp_stpt = clamp(ease(self.tNomAdj, self.temp_stpt, self.t_ease), self.tMinAdj, self.tMaxAdj)
            self.q_clear = clamp(self.getQ(self.temp_stpt), self.qMax, self.qMin)
        if self.q_clear is None:
            self.q_clear = 0.

    def get_q_min(self):
        t = self.tMaxAdj
        q = clamp(self.getQ(t), self.qMax, self.qMin)
        return q

    def get_q_max(self):
        #        t = self.clamp(self.temp_stpt-self.tDel, self.tMinAdj, self.tMaxAdj)
        t = self.tMinAdj
        q = clamp(self.getQ(t), self.qMax, self.qMin)
        return q

    def price_callback(self, timestamp, market_name, buyer_seller, price, quantity):
        _log.debug("{} - price of {} for market: {}".format(self.agent_name, price, market_name))
        self.p_clear = price
        if not self.qMax and not self.qMin and not self.sim_flag:
            self.update_actuation_state(None, None, None, None, None, 0)
            return
        if self.p_clear is not None:
                      self.update_setpoint()
                      _log.debug("New set point is {}".format(self.temp_stpt))
                      self.actuate_setpoint()

    def error_callback(self, timestamp, market_name, buyer_seller, error_code, error_message, aux):
        _log.debug("{} - error for Market: {} {}, Message: {}".format(self.agent_name,
                                                                      market_name,
                                                                      buyer_seller, aux))
        if self.actuate_enabled:
            if market_name == "electric":
                if aux.get('SQx,DQn', 0) == -1:
                    self.temp_stpt = self.tMaxAdj
                    self.actuate_setpoint()
                    return
            if self.sim_flag:
                self.temp_stpt = self.tNomAdj
                self.actuate_setpoint()

    def actuate_setpoint(self):
        temp_stpt = self.temp_stpt - self.setpoint_offset
        if self.actuate_enabled:
            _log.debug("{} - setting {} with value {}".format(self.agent_name, self.actuator_topic, temp_stpt))
            self.vip.rpc.call(self.actuator, 'set_point', self.agent_name, self.actuator_topic, temp_stpt).get(timeout=10)
Beispiel #4
0
class LightAgent(MarketAgent, FirstOrderZone):
    """
    The SampleElectricMeterAgent serves as a sample of an electric meter that
    sells electricity for a single building at a fixed price.
    """
    def __init__(self, market_name,agent_name,k,qmax,Pabsnom,nonResponsive,verbose_logging,subscribing_topic, **kwargs):
        super(LightAgent, self).__init__(verbose_logging, **kwargs)
        self.market_name = market_name
        self.agent_name = agent_name        
        self.k = k
        self.qmax = qmax
        self.Pabsnom=Pabsnom        
        self.nonResponsive = nonResponsive
        self.iniState()
        self.subscribing_topic=subscribing_topic
        self.join_market(self.market_name, BUYER, None, self.offer_callback, None, self.price_callback, self.error_callback)

    @Core.receiver('onstart')
    def setup(self, sender, **kwargs):
        _log.debug('Subscribing to '+'devices/CAMPUS/BUILDING1/AHU1/all')
        self.vip.pubsub.subscribe(peer='pubsub',
                                  prefix='devices/CAMPUS/BUILDING1/AHU1/all',
                                  callback=self.updateState)

    def offer_callback(self, timestamp, market_name, buyer_seller):
        result,message=self.make_offer(market_name, buyer_seller, self.create_demand_curve())
        _log.debug("results of the make offer {}".format(result))
        if not result:
            _log.debug("the new lightingt (maintain{}".format(self.qMax))
            gevent.sleep(random.random())
            self.vip.rpc.call('platform.actuator','set_point', self.agent_name,self.subscribing_topic+'/'+self.agent_name,round(self.qNorm,2)).get(timeout=6)

    def create_demand_curve(self):
        self.demand_curve = PolyLine()
        pMin = 10
        pMax = 100

        if (self.hvacAvail > 0):
            self.demand_curve.add(Point(price=min(pMin, pMax),quantity=max(self.qMin, self.qMax)*self.Pabsnom))
            self.demand_curve.add(Point(price=max(pMin, pMax),quantity=min(self.qMin, self.qMax)*self.Pabsnom))
        else:
            self.demand_curve.add(Point(price=max(pMin, pMax), quantity=0))
            self.demand_curve.add(Point(price=min(pMin, pMax),quantity=0))
        return self.demand_curve

    def iniState(self):
        self.hvacAvail = 1
        self.pClear = None
        self.qMin = 0.7
        self.qMax = self.qmax
        self.qNorm=self.qMax
        self.qClear=self.qNorm
 

    def updateState(self, peer, sender, bus, topic, headers, message):
        '''Subscribe to device data from message bus
        '''
        _log.debug('Received one new dataset')
        info = {}
        for key, value in message[0].items():
                  info[key] = value
        self.hvacAvail = info['SupplyFanStatus']
        if (self.hvacAvail > 0):
              self.qNorm=self.qMax  
        else:
              self.qNorm=0


    def updateSet(self):
        if self.pClear is not None and not self.nonResponsive and self.hvacAvail:
            self.qClear = self.clamp(self.demand_curve.x(self.pClear), self.qMax, self.qMin)
        else:
            self.qClear = 0
#        if self.qClear is None:
#            self.qClear = 0.

    def clamp(self, value, x1, x2):
        minValue = min(x1, x2)
        maxValue = max(x1, x2)
        return min(max(value, minValue), maxValue)        
                        
    def price_callback(self, timestamp, market_name, buyer_seller, price, quantity):
        _log.debug("the price is {}".format(price))
        self.pClear=price
        if self.pClear is not None: 
            self.updateSet()
            _log.debug("the new lightingt is {}".format(self.qClear))
            gevent.sleep(random.random())
            self.vip.rpc.call('platform.actuator','set_point', self.agent_name,self.subscribing_topic+'/'+self.agent_name,round(self.qClear,2)).get(timeout=5)


    def error_callback(self, timestamp, market_name, buyer_seller,  error_code, error_message, aux):
        _log.debug("the new lightingt is {}".format(self.qNorm))
        self.vip.rpc.call('platform.actuator','set_point', self.agent_name,self.subscribing_topic+'/'+self.agent_name,round(self.qNorm,2)).get(timeout=5)
        

    def ease(self, target, current, limit):
        return current - np.sign(current-target)*min(abs(current-target), abs(limit))        
class LightAgent(MarketAgent):
    """
    Transactive control lighting agent.
    """

    def __init__(self, market_name, agent_name, min_occupied_lighting_level,
                 default_occ_lighting_level, power_absnom, non_responsive, verbose_logging,
                 base_rpc_path, schedule_topic, schedule_point, actuator, **kwargs):
        super(LightAgent, self).__init__(verbose_logging, **kwargs)
        self.market_name = market_name
        self.agent_name = agent_name
        self.qmin = min_occupied_lighting_level/100.0
        self.qmax = default_occ_lighting_level/100.0
        self.power_absnom = power_absnom
        self.non_responsive = non_responsive
        self.actuation_topic = base_rpc_path
        self.actuator = actuator
        self.schedule_topic = schedule_topic
        self.schedule_point = schedule_point
        self.demand_curve = None
        self.hvac_avail = 1
        self.price_cleared = None
        self.qnorm = float(self.qmax)
        self.lighting_stpt = float(self.qnorm)
        self.join_market(self.market_name, BUYER, None, self.offer_callback,
                         None, self.price_callback, self.error_callback)

    @Core.receiver('onstart')
    def setup(self, sender, **kwargs):
        _log.debug("{}: schedule topic for HVAC - {}".format(self.agent_name,
                                                             self.schedule_topic))
        self.vip.pubsub.subscribe(peer='pubsub',
                                  prefix=self.schedule_topic,
                                  callback=self.update_state)

    def offer_callback(self, timestamp, market_name, buyer_seller):
        result, message = self.make_offer(market_name, buyer_seller, self.create_demand_curve())
        _log.debug("{}: result of the make offer {} at {}".format(self.agent_name,
                                                                  result,
                                                                  timestamp))
        if not result:
            _log.debug("{}: maintain current lighting level: {}".format(self.agent_name,
                                                                        self.qnorm))
            self.vip.rpc.call(self.actuator, 'set_point', self.agent_name,
                              self.actuation_topic, round(self.qnorm, 2)).get(timeout=10)

    def create_demand_curve(self):
        """
        Create electric demand curve for agents respective lighting zone.
        :return:
        """
        self.demand_curve = PolyLine()
        p_min = 10.
        p_max = 100.
        if self.hvac_avail:
            self.demand_curve.add(Point(price=min(p_min, p_max), quantity=max(self.qmin, self.qmax) * self.power_absnom))
            self.demand_curve.add(Point(price=max(p_min, p_max), quantity=min(self.qmin, self.qmax)* self.power_absnom))
        else:
            self.demand_curve.add(Point(price=max(p_min, p_max), quantity=0.))
            self.demand_curve.add(Point(price=min(p_min, p_max), quantity=0.))
        return self.demand_curve

    def update_state(self, peer, sender, bus, topic, headers, message):
        """
        Update state from device data from message bus.
        :param peer:
        :param sender:
        :param bus:
        :param topic:
        :param headers:
        :param message:
        :return:
        """
        _log.debug('{}: received one new data set'.format(self.agent_name))
        info = message[0]
        self.hvac_avail = info[self.schedule_point]
        if self.hvac_avail:
            self.qnorm = self.qmax
        else:
            self.qnorm = 0.0

    def update_set(self):
        """
        Determine new set point for the zone lighting level.
        :return:
        """
        if self.price_cleared is not None and not self.non_responsive and self.hvac_avail:
            self.lighting_stpt = clamp(self.demand_curve.x(self.price_cleared) / self.power_absnom, self.qmax, self.qmin)
        else:
            self.lighting_stpt = self.qnorm

    def price_callback(self, timestamp, market_name, buyer_seller, price, quantity):
        """
        Price callback for agent when interacting with electric market.
        :param timestamp:
        :param market_name:
        :param buyer_seller:
        :param price:
        :param quantity:
        :return:
        """
        _log.debug("{}: price {} quantity{}, for {} as {} at {}".format(self.agent_name,
                                                                        price,
                                                                        quantity,
                                                                        market_name,
                                                                        buyer_seller,
                                                                        timestamp))
        self.price_cleared = price
        if self.price_cleared is not None:
            self.update_set()
            _log.debug("{}: new lighting level is {}".format(self.agent_name,
                                                             self.lighting_stpt))
            self.vip.rpc.call(self.actuator, 'set_point', self.agent_name,
                             self.actuation_topic, round(self.lighting_stpt, 2)).get(timeout=10)

    def error_callback(self, timestamp, market_name, buyer_seller, error_code, error_message, aux):
        """
        Error callback for agent when interacting with electric market.
        :param timestamp:
        :param market_name:
        :param buyer_seller:
        :param error_code:
        :param error_message:
        :param aux:
        :return:
        """
        _log.debug("{}: error for {} at {} - Message: {}".format(self.agent_name,
                                                                 market_name,
                                                                 timestamp,
                                                                 error_message))
        if market_name == "electric":   
#            if aux.get('Sn,Dn', 0) == -1 and aux.get('Sx,Dx', 0) == -1:
            if aux.get('SQx,DQn', 0) == -1:
                _log.debug("{}: use minimum lighting level: {}".format(self.agent_name, self.qmin))
                self.vip.rpc.call(self.actuator, 'set_point', self.agent_name, self.actuation_topic, self.qmin).get(timeout=10)
                return
            else:
                _log.debug("{}: maintain default lighting level at: {}".format(self.agent_name, self.qnorm))
                self.vip.rpc.call(self.actuator, 'set_point', self.agent_name, self.actuation_topic, round(self.qnorm, 2)).get(timeout=10)