def get_signal(self): """get and format DR signal and schedule DR proc.""" time_now = time.mktime(datetime.datetime.now().timetuple()) time_pre = time.mktime( datetime.datetime.now().replace(hour=settings.pre_cpp_hour, minute=0, second=0, microsecond=0).timetuple()) time_event = time.mktime(datetime.datetime.now().replace( hour=settings.during_cpp_hour, minute=12, second=0, microsecond=0).timetuple()) time_after = time.mktime(datetime.datetime.now().replace( hour=settings.after_cpp_hour, minute=14, second=0, microsecond=0).timetuple()) if (settings.signal and time_now < time_pre): _log.debug("Scheduling1") time_step = settings.pre_time / 3600 #self.cooling_slope = (self.csp_norm - settings.csp_pre) / ((((time_event - time_pre) / 3600) - 0.5) * time_step) self.cooling_slope = 1 # for testing use a constant temp = ((time_event - time_pre) / 3600) _log.debug("cooling slope: " + repr(self.cooling_slope)) self.schedule(time_pre, sched.Event(self._pre_cpp_timer)) self.schedule(time_event, sched.Event(self._during_cpp_timer)) after_cpp_time = datetime.datetime.now().replace( hour=settings.after_cpp_hour, minute=59, second=0, microsecond=0) self.schedule(time_after, sched.Event(self._after_cpp_timer)) #self.start_timer.cancel() elif (settings.signal and time_now > time_pre and time_now < time_event): _log.debug("Scheduling2") #self.start_timer.cancel() #self.accel_slope = (self.csp_norm - settings.csp_pre) / ((time_event - time_now) / (3600)) self.accel_slope = 2 #for testing use a constant #self.cooling_slope = (self.csp_norm - settings.csp_pre) / ((((time_event - time_pre) / 3600) - 0.5) * time_step) self.cooling_slope = 1 # for testing use a constant self.schedule(time_event, sched.Event(self._during_cpp_timer)) self.schedule(time_after, sched.Event(self._after_cpp_timer)) self._accelerated_pre_cpp_timer() elif (settings.signal and time_now > time_event and time_now < time_after): _log.debug("Too late to pre-cool!") #self.start_timer.cancel() self.schedule(time_after, sched.Event(self._after_cpp_timer)) self._during_cpp() else: _log.debug("CPP Event Is Over") #self.start_timer.cancel() self._sleep(60) self.get_signal()
def retry_lock(): def retry_lock_event(): headers = { headers_mod.CONTENT_TYPE: headers_mod.CONTENT_TYPE.JSON, 'requesterID': agent_id} self.publish(topics.ACTUATOR_LOCK_ACQUIRE(**rtu_path), headers) retry_time = datetime.datetime.now() + datetime.timedelta(seconds=5) if retry_time > e_end: self.state = 'IDLE' self.error_handler = None return event = sched.Event(retry_lock_event) self.schedule(retry_time, event)
def get_signal(self): """get and format DR signal and schedule DR proc.""" #Pull signal from source self.__sleep(2) #remove after testing global csp_norm global cooling_slope global accel_slope time_now = time.mktime(datetime.datetime.now().timetuple()) time_pre = time.mktime(datetime.datetime.now().replace(hour = settings.pre_cpp_hour, minute = 23, second=0, microsecond = 0).timetuple()) time_event = time.mktime(datetime.datetime.now().replace(hour = settings.during_cpp_hour, minute = 25, second = 0, microsecond = 0).timetuple()) time_after = time.mktime(datetime.datetime.now().replace(hour = settings.after_cpp_hour, minute = 27, second = 0, microsecond = 0).timetuple()) if (settings.signal and time_now<time_pre): _log.debug ("Scheduling1") time_step = settings.pre_cooling_time/3600 #cooling_slope = (csp_norm-settings.csp_pre)/((((time_event-time_pre)/3600)-0.5)*time_step) cooling_slope = 1 # for testing use a constant temp = ((time_event-time_pre)/3600) _log.debug ("cooling slope: "+ repr(cooling_slope)) pre_cpp_time = datetime.datetime.now().replace(hour = settings.pre_cpp_hour, minute = 23, second = 0, microsecond = 0) self.schedule(pre_cpp_time, sched.Event(self.__pre_cpp_timer)) during_cpp_time = datetime.datetime.now().replace(hour = settings.during_cpp_hour, minute=25, second = 0, microsecond = 0) self.schedule(during_cpp_time, sched.Event(self.__during_cpp_timer)) after_cpp_time = datetime.datetime.now().replace(hour = settings.after_cpp_hour, minute = 27, second = 0, microsecond = 0) self.schedule(after_cpp_time, sched.Event(self.__after_cpp_timer)) #self.start_timer.cancel() elif(settings.signal and time_now>time_pre and time_now<time_event): _log.debug("Scheduling2") #self.start_timer.cancel() #accel_slope = (csp_norm-settings.csp_pre)/((time_event-time_now)/(3600)) accel_slope = 2 #for testing use a constant during_cpp_time = datetime.datetime.now().replace(hour = settings.during_cpp_hour, minute = 36, second =20, microsecond = 0) self.schedule(during_cpp_time, sched.Event(self.__during_cpp_timer)) after_cpp_time = datetime.datetime.now().replace(hour = settings.after_cpp_hour, minute = 39, second = 10, microsecond = 0) self.schedule(after_cpp_time, sched.Event(self.__after_cpp_timer)) self.__accelerated_pre_cpp_timer() elif(settings.signal and time_now>time_event and time_now<time_after): _log.debug("Too late to pre-cool!") #self.start_timer.cancel() after_cpp_time = datetime.datetime.now().replace(hour=settings.after_cpp_hour, minute = 17, second = 0, microsecond = 0) self.schedule(after_cpp_time, sched.Event(self.__after_cpp_timer)) self.tasklet = greenlet.greenlet(self.__during_cpp) self.tasklet.switch() else: _log.debug("CPP Event Is Over") #self.start_timer.cancel() self.__sleep(60) self.get_signal()
def get_signal(self): #Pull signal from source time_now=time.mktime(datetime.datetime.now().timetuple()) time_pre=time.mktime(datetime.datetime.now().replace(hour=settings.pre_cpp_hour,minute=0,second=0, microsecond=0).timetuple()) time_event=time.mktime(datetime.datetime.now().replace(hour=settings.during_cpp_hour,minute=51,second=0, microsecond=0).timetuple()) time_after=time.mktime(datetime.datetime.now().replace(hour=settings.after_cpp_hour,minute=54,second=0, microsecond=0).timetuple()) print(time_now) print(time_event) #PULL NORMAL COOLING SETPOINT csp_normal=settings.csp_norm if (settings.signal and time_now<time_pre): print ("Scheduling") pre_cpp_time=datetime.datetime.now().replace(hour=settings.pre_cpp_hour,minute=25,second=10, microsecond=0) self.schedule(pre_cpp_time,sched.Event(self.pre_cpp_timer, (csp_normal,))) during_cpp_time=datetime.datetime.now().replace(hour=settings.during_cpp_hour,minute=26,second=20, microsecond=0) self.schedule(during_cpp_time,sched.Event(self.during_cpp)) after_cpp_time=datetime.datetime.now().replace(hour=settings.after_cpp_hour,minute=27,second=30, microsecond=0) self.schedule(after_cpp_time,sched.Event(self.after_cpp_timer, (csp_normal,))) self.start_timer.cancel() elif(settings.signal and time_now>time_pre and time_now<time_event): print("Scheduling") self.start_timer.cancel() pre_slope=(time_event-time_now)/(3600) during_cpp_time=datetime.datetime.now().replace(hour=settings.during_cpp_hour,minute=46,second=20, microsecond=0) self.schedule(during_cpp_time,sched.Event(self.during_cpp)) after_cpp_time=datetime.datetime.now().replace(hour=settings.after_cpp_hour,minute=47,second=10, microsecond=0) self.schedule(after_cpp_time,sched.Event(self.after_cpp_timer, (csp_normal,))) self.accelerated_pre_cooling_timer(pre_slope,csp_normal) elif(settings.signal and time_now>time_event and time_now<time_after): print("Too late to pre-cool!") self.start_timer.cancel() after_cpp_time=datetime.datetime.now().replace(hour=settings.after_cpp_hour,minute=54,second=10, microsecond=0) self.schedule(after_cpp_time,sched.Event(self.after_cpp_timer, (csp_normal,))) self.during_cpp() print("CPP Event Missed") self.setup()
def schedule_builder(self,start_time, end_time, current_spacetemp, pre_csp, building_thermal_constant, normal_coolingstpt, timestep_length, dr_csp): """schedule all events for a DR event.""" current_time = time.time() if current_time > end_time: return _log.debug('Scheduling all DR actions') pre_hsp = pre_csp - 5.0 ideal_cooling_window = int(((current_spacetemp - pre_csp)/building_thermal_constant) *3600) ideal_precool_start_time = start_time - ideal_cooling_window max_cooling_window = start_time - current_time cooling_window = ideal_cooling_window if ideal_cooling_window < max_cooling_window else max_cooling_window precool_start_time = start_time - cooling_window pre_cool_step = 0 if (max_cooling_window > 0): _log.debug('Schedule Pre Cooling') num_cooling_timesteps = int(math.ceil(float(cooling_window) / float(timestep_length))) cooling_step_delta = (normal_coolingstpt - pre_csp) / num_cooling_timesteps if num_cooling_timesteps <= 0: num_cooling_timesteps=1 for step_index in range (1, num_cooling_timesteps): if step_index == 1: pre_cool_step = 2*timestep_length else: pre_cool_step += timestep_length event_time = start_time - pre_cool_step csp = pre_csp + ((step_index-1) * cooling_step_delta) _log.debug('Precool step: '+ str(datetime.datetime.fromtimestamp(event_time)) + ' CSP: ' + str(csp)) event = sched.Event(self.modify_temp_set_point, args = [csp, pre_hsp]) self.schedule(event_time, event) self.currently_running_dr_event_handlers.append(event) else: _log.debug('Too late to pre-cool!') restore_window = int(((dr_csp - normal_coolingstpt)/building_thermal_constant) *3600) restore_start_time = end_time num_restore_timesteps = int(math.ceil(float(restore_window) / float(timestep_length))) restore_step_delta = (dr_csp - normal_coolingstpt) / num_restore_timesteps _log.debug('Schedule DR Event: ' + str(datetime.datetime.fromtimestamp(start_time)) +' CSP: ' + str(dr_csp)) event = sched.Event(self.start_dr_event) self.schedule(start_time, event) self.currently_running_dr_event_handlers.append(event) _log.debug('Schedule Restore Event: '+ str(datetime.datetime.fromtimestamp(end_time)) + ' CSP: ' + str(dr_csp-restore_step_delta)) event = sched.Event(self.start_restore_event, args = [dr_csp-restore_step_delta, self.normal_heatingstpt]) self.schedule(end_time, event) self.currently_running_dr_event_handlers.append(event) for step_index in range (1, num_restore_timesteps): event_time = end_time + (step_index * timestep_length) csp = dr_csp - ((step_index + 1) * restore_step_delta) _log.debug('Restore step: ' + str(datetime.datetime.fromtimestamp(event_time)) +' CSP: ' + str(csp)) event = sched.Event(self.modify_temp_set_point, args = [csp, self.normal_heatingstpt]) self.schedule(event_time, event) self.currently_running_dr_event_handlers.append(event) event_time = end_time + (num_restore_timesteps * timestep_length) _log.debug('Schedule Cleanup Event: ' + str(datetime.datetime.fromtimestamp(event_time))) event = sched.Event(self.cancel_event) self.schedule(event_time,event) self.currently_running_dr_event_handlers.append(event)
def cancel_event(self, cancel_type='NORMAL'): if cancel_type == 'OVERRIDE': self.state = 'OVERRIDE' smap_input = 3.0 elif cancel_type != 'UPDATING': self.state = 'CLEANUP' smap_input = 2.0 self.publish(topics.ACTUATOR_SET(point=cooling_stpt, **rtu_path), self.headers, str(self.normal_coolingstpt)) self.publish(topics.ACTUATOR_SET(point=heating_stpt, **rtu_path), self.headers, str(self.normal_heatingstpt)) self.publish(topics.ACTUATOR_SET(point=cooling_fan_sp1, **rtu_path), self.headers, str(self.normal_firststage_fanspeed)) self.publish(topics.ACTUATOR_SET(point=cooling_fan_sp2, **rtu_path), self.headers, str(self.normal_secondstage_fanspeed)) self.publish(topics.ACTUATOR_SET(point=min_damper_stpt, **rtu_path), self.headers, str(self.normal_damper_stpt)) self.publish(topics.ACTUATOR_SET(point=cooling_stage_diff, **rtu_path), self.headers, str(self.default_cooling_stage_differential)) self.publish(topics.ACTUATOR_SET(point=volttron_flag, **rtu_path), self.headers,str( 0)) for event in self.currently_running_dr_event_handlers: event.cancel() if cancel_type != 'UPDATING': mytime = int(time.time()) content = { "Demand Response Event": { "Readings": [[mytime, smap_input]], "Units": "TU", "data_type": "double" } } self.publish(self.smap_path, self.headers, jsonapi.dumps(content)) self.currently_running_dr_event_handlers = [] def backup_run(): self.cancel_event() self.lock_handler=None self.lock_handler = backup_run expected_values = {cooling_stpt: self.normal_coolingstpt, heating_stpt: self.normal_heatingstpt, cooling_fan_sp1: self.normal_firststage_fanspeed, cooling_fan_sp2: self.normal_secondstage_fanspeed, min_damper_stpt: self.normal_damper_stpt, cooling_stage_diff: self.default_cooling_stage_differential} EPSILON = 0.5 #allowed difference from expected value def result_handler(point, value): #print "actuator point being handled:", point, value expected_value = expected_values.pop(point, None) if expected_value is not None: diff = abs(expected_value-value) if diff > EPSILON: _log.debug( "Did not get back expected value for: " + str(point)) if not expected_values: self.actuator_handler = None self.lock_handler=None self.error_handler = None self.state = 'IDLE' if not cancel_type == 'OVERRIDE' else 'OVERRIDE' headers = { headers_mod.CONTENT_TYPE: headers_mod.CONTENT_TYPE.JSON, 'requesterID': agent_id} self.publish(topics.ACTUATOR_LOCK_RELEASE(**rtu_path), headers) if cancel_type != 'UPDATING': self.actuator_handler = result_handler else: self.actuator_handler = None self.lock_handler=None if cancel_type == 'OVERRIDE': def on_reset(): self.error_handler = None self.state = 'IDLE' today = datetime.datetime.now() reset_time = today + datetime.timedelta(days=1) reset_time = reset_time.replace(hour=0, minute =0, second = 0) event = sched.Event(on_reset) self.schedule(reset_time, event)
def pre_cool_get_lock(self, e_start, e_end): if self.state == 'OVERRIDE': _log.debug("Override today") return if self.pre_cool_idle == False: return now = datetime.datetime.now() day=now.weekday() if not schedule[day]: _log.debug("Unoccupied today") return if self.state == 'PRECOOL' and self.pre_cool_idle == True: for event in self.currently_running_dr_event_handlers: event.cancel() self.all_scheduled_events = {} self.state = 'PRECOOL' e_start_unix = time.mktime(e_start.timetuple()) e_end_unix = time.mktime(e_end.timetuple()) if self.pre_cool_idle == True: event_start = now + datetime.timedelta(minutes=15) event = sched.Event(self.pre_cool_get_lock, args=[self.e_start, self.e_end]) self.schedule(event_start, event) self.all_scheduled_events[e_start] = event self.pre_cool_idle = True self.schedule_builder(e_start_unix, e_end_unix, current_spacetemp=self.current_spacetemp, pre_csp=csp_pre, building_thermal_constant=building_thermal_constant, normal_coolingstpt=self.normal_coolingstpt, timestep_length=timestep_length, dr_csp=csp_cpp) else: event_start = now + datetime.timedelta(minutes=15) event = sched.Event(self.pre_cool_get_lock, args=[self.e_start, self.e_end]) self.schedule(event_start, event) self.all_scheduled_events[e_start] = event self.pre_cool_idle = True def run_schedule_builder(): self.schedule_builder(e_start_unix, e_end_unix, current_spacetemp=self.current_spacetemp, pre_csp=csp_pre, building_thermal_constant=building_thermal_constant, normal_coolingstpt=self.normal_coolingstpt, timestep_length=timestep_length, dr_csp=csp_cpp) self.lock_handler=None self.lock_handler = run_schedule_builder headers = { headers_mod.CONTENT_TYPE: headers_mod.CONTENT_TYPE.JSON, 'requesterID': agent_id} self.publish(topics.ACTUATOR_LOCK_ACQUIRE(**rtu_path), headers) def retry_lock(): def retry_lock_event(): headers = { headers_mod.CONTENT_TYPE: headers_mod.CONTENT_TYPE.JSON, 'requesterID': agent_id} self.publish(topics.ACTUATOR_LOCK_ACQUIRE(**rtu_path), headers) retry_time = datetime.datetime.now() + datetime.timedelta(seconds=5) if retry_time > e_end: self.state = 'IDLE' self.error_handler = None return event = sched.Event(retry_lock_event) self.schedule(retry_time, event) self.error_handler = retry_lock
def _on_dr_event(self, topic, headers, message, match): if self.state == 'STARTUP': _log.debug('DR event ignored because of startup.') return """handle openADR events""" msg = jsonapi.loads(message[0]) _log.debug('EVENT Received: ' + str(msg)) e_id = msg['id'] e_status = msg['status'] e_start = msg['start_at'] #e_start = datetime.datetime.strptime(e_start, datefmt) today = datetime.datetime.now().date() e_end = msg['end_at'] e_end = parser.parse(e_end, fuzzy=True) e_start = parser.parse(e_start, fuzzy=True) #e_end = datetime.datetime.strptime(e_end, datefmt) current_datetime = datetime.datetime.now() #For UTC offset #offset= datetime.datetime.utcnow() - datetime.datetime.now() #e_end = e_end - offset #e_start = e_start - offset if current_datetime > e_end: _log.debug('Too Late Event is Over') return if e_status == 'cancelled': if e_start in self.all_scheduled_events: _log.debug('Event Cancelled') self.all_scheduled_events[e_start].cancel() del self.all_scheduled_events[e_start] if e_start.date() == today and (self.state == 'PRECOOL' or self.state == 'DR_EVENT'): self.cancel_event() return if today > e_start.date(): if e_start in self.all_scheduled_events: self.all_scheduled_events[e_start].cancel() del self.all_scheduled_events[e_start] return for item in self.all_scheduled_events.keys(): if e_start.date() == item.date(): if e_start.time() != item.time(): _log.debug( 'Updating Event') self.all_scheduled_events[item].cancel() del self.all_scheduled_events[item] if e_start.date() == today and (self.state == 'PRECOOL' or self.state == 'DR_EVENT'): self.cancel_event(cancel_type='UPDATING') break elif e_start.time() == item.time(): _log.debug("same event") return #Don't schedule an event if we are currently in OVERRIDE state. if e_start.date() == today and (self.state == 'OVERRIDE'): return self.e_start = e_start self.e_end = e_end event_start = e_start - datetime.timedelta(hours = max_precool_hours) event = sched.Event(self.pre_cool_get_lock, args=[self.e_start, self.e_end]) self.schedule(event_start, event) self.all_scheduled_events[e_start] = event
def schedule_builder(self,start_time, end_time, current_spacetemp, pre_csp, building_thermal_constant, normal_coolingstpt, timestep_length, dr_csp): """schedule all events for a DR event.""" print 'Scheduling all DR actions' pre_hsp = pre_csp - 5.0 current_time = time.time() ideal_cooling_window = int(((current_spacetemp - pre_csp)/building_thermal_constant) *3600) ideal_precool_start_time = start_time - ideal_cooling_window max_cooling_window = start_time - current_time cooling_window = ideal_cooling_window if ideal_cooling_window < max_cooling_window else max_cooling_window precool_start_time = start_time - cooling_window if (max_cooling_window > 0): print "Schedule Pre Cooling" num_cooling_timesteps = int(math.ceil(float(cooling_window) / float(timestep_length))) cooling_step_delta = (normal_coolingstpt - pre_csp) / num_cooling_timesteps for step_index in range (1, num_cooling_timesteps+1): event_time = start_time - (step_index * timestep_length) csp = pre_csp + ((step_index-1)*cooling_step_delta) print 'Precool step:', datetime.datetime.fromtimestamp(event_time), csp event = sched.Event(self.modify_temp_set_point, args = [csp, pre_hsp]) self.schedule(event_time, event) self.currently_running_dr_event_handlers.append(event) else: print "Too late to pre-cool!" restore_window = int(((dr_csp - normal_coolingstpt)/building_thermal_constant) *3600) restore_start_time = end_time num_restore_timesteps = int(math.ceil(float(restore_window) / float(timestep_length))) restore_step_delta = (dr_csp - normal_coolingstpt) / num_restore_timesteps print 'Schedule DR Event:', datetime.datetime.fromtimestamp(start_time), dr_csp event = sched.Event(self.start_dr_event) self.schedule(start_time, event) self.currently_running_dr_event_handlers.append(event) print 'Schedule Restore Event:', datetime.datetime.fromtimestamp(end_time), dr_csp-restore_step_delta event = sched.Event(self.start_restore_event, args = [dr_csp-restore_step_delta, self.default_heatingstpt]) self.schedule(end_time, event) self.currently_running_dr_event_handlers.append(event) for step_index in range (1, num_restore_timesteps): event_time = end_time + (step_index * timestep_length) csp = dr_csp - ((step_index + 1) * restore_step_delta) print 'Restore step:', datetime.datetime.fromtimestamp(event_time), csp event = sched.Event(self.modify_temp_set_point, args = [csp, self.default_heatingstpt]) self.schedule(event_time, event) self.currently_running_dr_event_handlers.append(event) event_time = end_time + (num_restore_timesteps * timestep_length) print 'Schedule Cleanup Event:', datetime.datetime.fromtimestamp(event_time) event = sched.Event(self.cancel_event) self.schedule(event_time,event) self.currently_running_dr_event_handlers.append(event)
def _on_dr_event(self, topic, headers, message, match): if self.state == 'STARTUP': print "DR event ignored because of startup." return """handle openADR events""" msg = jsonapi.loads(message[0]) print('EVENT Received') print(msg) e_id = msg['id'] e_status = msg['status'] e_start = msg['start'] e_start = datetime.datetime.strptime(e_start, datefmt) today = datetime.datetime.now().date() #e_start_day = e_start.date() #e_end = e_start.replace(hour=cpp_end_hour, minute =0, second = 0) current_datetime = datetime.datetime.now() e_end = e_start + datetime.timedelta(minutes=2) if current_datetime > e_end: print 'Too Late Event is Over' return if e_status == 'cancelled': if e_start in self.all_scheduled_events: print 'Event Cancelled' self.all_scheduled_events[e_start].cancel() del self.all_scheduled_events[e_start] if e_start.date() == today and (self.state == 'PRECOOL' or self.state == 'DR_EVENT'): self.cancel_event() return #TODO: change this to UTC later #utc_now = datetime.datetime.utcnow() if today > e_start.date(): if e_start in self.all_scheduled_events: self.all_scheduled_events[e_start].cancel() del self.all_scheduled_events[e_start] return for item in self.all_scheduled_events.keys(): if e_start.date() == item.date(): if e_start.time() != item.time(): print "Updating Event" self.all_scheduled_events[item].cancel() del self.all_scheduled_events[item] if e_start.date() == today and (self.state == 'PRECOOL' or self.state == 'DR_EVENT'): self.update_running_event() self.state = 'IDLE' break elif e_start.time() == item.time(): print "same event" return #if e_id in self.all_scheduled_dr_events and update is None: # if e_id == self.currently_running_msg: # return #return #Minutes used for testing #event_start = e_start - datetime.timedelta(hours = max_precool_hours) event_start = e_start - datetime.timedelta(minutes = max_precool_hours) event = sched.Event(self.pre_cool_get_lock, args=[e_start, e_end]) self.schedule(event_start, event) self.all_scheduled_events[e_start] = event