def __init__(self, sensor_name, ecobee_service=None, prediction_threshold=0.6): Resource.__init__(self, "OccupancySensor_{}".format( sensor_name), ["occupancy", "predicted_occupancy", "temperature"]) self.sensor_name = sensor_name self.ecobee_service = ecobee_service if self.ecobee_service is None: # try to grab it from the EcobeeResource def wait_ecobee_service(): self.ecobee_service = Resource.resource( "EcobeeResource").ecobee_service Resource.waitResource("EcobeeResource", wait_ecobee_service) try: wait_ecobee_service() except ResourceNotFoundException: pass self.prediction_resource = OccupancyPredictorResource( self.name, prediction_threshold=prediction_threshold)
def test_topic_converter(): # we need to do this because we will be creating the resources # again with the same names clear from previous tests... Resource.clearResources() import time broker = "127.0.0.1" @mqtt_topic_converter("ResourcePublisher/foo") def convert_int(value): return int(value) publisher = MqttWrapper(Resource("ResourcePublisher", ["foo"]), broker, retain_msgs=False) resource = MqttResource("Test2Resource", broker, ["foo"], variable_mqtt_map={"foo": "ResourcePublisher/foo"}) loop = asyncio.get_event_loop() loop.run_until_complete(resource.wait_until_connected()) loop.run_until_complete(publisher.wait_until_connected()) publisher.resource.setValue("foo", 1) asyncio.get_event_loop().run_until_complete(asyncio.sleep(10)) assert resource.getValue("foo") == 1
def test_minimum_runtime_on_off_time(): Resource.clearResources() device_manager = DeviceManager(max_power_budget=800, debug=True) device = DeviceResource("fake_device", 2000) policy1 = MinimumRuntime(device, 1) device.set_runtime_policy([policy1]) device.run() device_manager.process_managed_devices() assert device.running() assert policy1.last_time is not None asyncio.get_event_loop().run_until_complete(asyncio.sleep(2)) device_manager.process_managed_devices() assert policy1.current_runtime > 1 device.stop() device_manager.process_managed_devices() asyncio.get_event_loop().run_until_complete(asyncio.sleep(5)) device_manager.process_managed_devices() # We stopped at around 2 seconds of runtime. assert policy1.current_runtime < 5
def __init__(self, name=None, occupancy_resource=None, prediction_threshold=0.70): if occupancy_resource is None: occupancy_resource = "GlobalOccupancy" if name is None: self.name = "{}_OccuppancyPredictorResource".format( occupancy_resource) else: self.name = name super().__init__( self.name, power_usage=100, variables=["occupancy_prediction", "occupancy_prediction_raw"]) self.predictors = None self.did_train = False self.runtime_policy = RunIfCanPolicy( conditions=[lambda: not self.did_train]) self.prediction_threshold = prediction_threshold self.occupancy_resource = occupancy_resource self.model_dir = "{}_occupancy_predictor".format(occupancy_resource) Resource.waitResource([occupancy_resource], self.init_predictor) asyncio.get_event_loop().create_task(self.reset_train_counter())
def test_occupancy_policy(): Resource.clearResources() device_manager = DeviceManager(max_power_budget=800) occupancy_resource = Resource( "SomeOccupancyThing", variables=["occupancy"]) occupancy_resource.setValue("occupancy", True) off_policy = OffIfUnoccupied(occupancy_resource.name) dev1 = DeviceResource("dev1", power_usage=100, device_manager=device_manager.name, runtime_policy=[off_policy]) dev1.run() device_manager.process_managed_devices() assert dev1.running(), "Device should be running" occupancy_resource.setValue("occupancy", False) assert off_policy.occupancy.value is False device_manager.process_managed_devices() assert not dev1.running(), "Device should not be running" occupancy_resource.setValue("occupancy", True) device_manager.process_managed_devices() assert not dev1.running(), "Device should not be running"
def main(): # setup a fake occupancy sensor. Normally, this would come from an ecobee # device or from a camera resource... anything that has an "occupancy" # property. fake_occupancy = Resource("Office Occupancy Sensor", ["occupancy"]) # generate lots of fake data: for i in range(100): occupied = random.choice([True, False]) fake_occupancy.set_value("occupancy", occupied) # We don't have a power source, so we'll just set the max budget manually: DeviceManager(max_power_budget=1000) # our predictor will use train and run using the "GlobalOccupancy" resource occupancy_predictor = OccupancyPredictorResource( name="FakeOccupancyPredictor", occupancy_resource=fake_occupancy.name) kasa_devices = discover_devices() for device in kasa_devices: policies = [OffIfUnoccupied(occupancy_predictor.name)] device.set_runtime_policy(policies) # run the mainloop asyncio.get_event_loop().run_forever()
def set_value(self, key, value): if key == "config": Resource.set_value(self, "config", self.config) return self.config[key] = value self.writeConfig()
def __init__(self, configFileName): Resource.__init__(self, "ConfigurationResource", ["config"]) self.configFile = configFileName self.reload() self.setValue("config", self.config)
def test_minimum_runtime(): Resource.clearResources() device_manager = DeviceManager(max_power_budget=800, debug=True) device = DeviceResource("fake_device", 2000) policy1 = MinimumRuntime(device, 1) policy2 = RunIfCanPolicy() group = PolicyGroup(or_policies=[policy1, policy2]) device.set_runtime_policy([group]) device.run() device_manager.process_managed_devices() assert device.running() assert policy1.last_time is not None asyncio.get_event_loop().run_until_complete(asyncio.sleep(2)) device_manager.process_managed_devices() print(device.to_json()) assert policy1.current_runtime > 1 assert not policy1.can_run() assert not policy2.can_run() assert not policy1.run_conditions() assert not policy2.run_conditions() assert not device.running()
def __init__(self, name, hammock_instance, poll_rate=2): self.hammock_instance = hammock_instance variables = self.hammock_instance.GET(verify=False).json()["variables"] Resource.__init__(self, name, variables.keys()) self.poller = resource_poll(self.poll_func, MINS(poll_rate))
def test_dataframe_has_timestamp_column(): Resource.clearResources() dow = DayOfWeekResource() hod = HourOfDayResource() assert "timestamp" in dow.dataframe.columns assert "timestamp" in hod.dataframe.columns
def test_mqtt_wrapper(): # we need to do this because we will be creating the resources # again with the same names. clear from previous tests... Resource.clearResources() import time broker = "127.0.0.1" resource = MqttResource("Test1Resource", broker, ["Test1Resource2/foo"]) publisher = MqttWrapper(Resource("Test1Resource2", ["foo"]), broker, retain_msgs=False) loop = asyncio.get_event_loop() loop.run_until_complete(resource.wait_until_connected()) loop.run_until_complete(publisher.wait_until_connected()) publisher.resource.setValue("foo", "bar") asyncio.get_event_loop().run_until_complete(asyncio.sleep(10)) assert resource.getValue("Test1Resource2/foo") == "bar" publisher.resource.setValue("foo", "bar2") asyncio.get_event_loop().run_until_complete(asyncio.sleep(10)) assert resource.getValue("Test1Resource2/foo") == "bar2"
def __init__(self, name="NightTime", lat=None, lon=None, timezone="US/Pacific"): Resource.__init__( self, name, ["nightTime", "night_time", "sunset", "sunrise"]) if lat is None or lon is None: try: config = get_resource("ConfigurationResource") lat = config.get_value("latitude") lon = config.get_value("longitude") except ResourceNotFoundException: raise Exception( "NightTime requires lat/lon set or ConfigurationResource") if lat is None or lon is None: raise Exception( "NightTime: missing latitude/longitude in ConfigurationResource") print("using lat/lon: {}, {}".format(lat, lon)) self.location = Location() self.location.latitude = float(lat) self.location.longitude = float(lon) self.location.timezone = timezone self.process() self.poller = resource_poll(self.process, MINS(1))
def __init__(self, name, broker, variables=None, variable_mqtt_map=None, quiet=True, encoding='utf-8', **kwargs): """ :param variable_mqtt_map - map mqtt messages to local variables. eg. remote_resource = MqttResource("light_switch1", "some.broker.com", ["foo"], {'foo' : 'light_switch1/foo'}) :param topic_conversion_map - map of mqtt topics and conversion functions """ self.encoding = encoding if variables is None: variables = [] if variable_mqtt_map is None: variable_mqtt_map = {} self.quiet = quiet Resource.__init__(self, name, variables, ignore_same_value=False) MqttCommon.__init__(self, name, broker=broker, **kwargs) self.variable_mqtt_map = variable_mqtt_map
def test_day_of_week(): Resource.clearResources() dow = DayOfWeekResource() weekday = get_current_datetime().date().weekday() assert weekday == dow.getValue("day_of_week")
def wait_resources(): self.occupancy_predictor = Resource.resource( self.occupancy_predictor_name) self.occupancy_predictor.subscribe( "occupancy_prediction", self.occupancy_changed) Resource.resource("SolarPower").subscribe( "current_power", self.solar_power_changed) self.night_time_resource = Resource.resource("NightTime")
def __init__(self, occupancy_predictor_name=None, power_usage=1750): super().__init__("EcobeeResource", power_usage=power_usage, variables=["occupancy", "setpoint_heat", "setpoint_cool", "temperature", "humidity", "running_program"], priority=RuntimePriority.high) self.subscribe("temperature", lambda v: self.process()) self.subscribe("running_program", lambda v: self.process()) self.occupancy_prediction = False self.occupancy_predictor_name = occupancy_predictor_name self.occupancy_predictor = None config = Resource.resource("ConfigurationResource").config api_key = config["ecobee_apikey"] thermostat_name = config["ecobee_thermostat_name"] self.ecobee_user_preferences = None self.present_users = [] if "ecobee_user_preferences" in config: self.ecobee_user_preferences = config["ecobee_user_preferences"] self.ecobee_service = Ecobee(thermostat_name, api_key) self.poller = resource_poll(self.poll_func, MINS(3), is_coroutine=True) def wait_resources(): self.occupancy_predictor = Resource.resource( self.occupancy_predictor_name) self.occupancy_predictor.subscribe( "occupancy_prediction", self.occupancy_changed) Resource.resource("SolarPower").subscribe( "current_power", self.solar_power_changed) self.night_time_resource = Resource.resource("NightTime") Resource.waitResource( [self.occupancy_predictor_name, "SolarPower", "NightTime"], wait_resources) def wait_ble_resource(): Resource.resource("BleUserResource").subscribe( "present_users", self.ble_present_users_changed) Resource.waitResource("BleUserResource", wait_ble_resource) self.ecobee_can_run_hold = False self.setpoint_cool = None self.setpoint_heat = None
def test_hour_of_day(): Resource.clearResources() hod = HourOfDayResource() hour = get_current_datetime().time().hour + \ round(get_current_datetime().time().minute / 60, 1) assert hour == hod.getValue("hour_of_day") assert hour == HourOfDayResource.hour(get_current_datetime())
def __init__(self): Resource.__init__(self, "TimeOfUse", ["mode", "schedule"]) try: config = Resource.resource("ConfigurationResource").config self.winter_schedule = config["time_of_use_schedule"]["winter"] self.summer_schedule = config["time_of_use_schedule"]["summer"] self.poller = resource_poll(self.update_schedule, MINS(1)) except ResourceNotFoundException: print("TimeOfUse: No configuration resource!")
def test_zero_power_usage_can_run(): Resource.clearResources() DeviceManager(max_power_budget=800) device_1 = DeviceResource("Power Hog 3000", 800) device_1.run() device_2 = DeviceResource("Power Hog 3001", 0) assert not device_2.can_run()
def __init__(self): Resource.__init__(self, "weather", [ "temperature", "humidity", "forecast_high", "forecast_low", "forecast_conditions", "condition", "current_observation", "cloud_cover", "forecast_cloud_cover" ]) self.key = get_resource("ConfigurationResource").config["weather_key"] self.lat = get_resource("ConfigurationResource").config["latitude"] self.lon = get_resource("ConfigurationResource").config["longitude"] self.poller = resource_poll(self.poll_func, MINS(15), is_coroutine=True)
def test_subscribe(): Resource.clearResources() received = False publisher = Resource("publisher234523453", ["foo"]) publisher.export_mqtt() subscriber = MqttResource( "publisher_sub", "localhost", ["foo"], variable_mqtt_map={"foo": "publisher234523453/foo"}) received = subscriber.subscribe2("foo") loop = asyncio.get_event_loop() loop.run_until_complete(publisher.mqtt_wrapper.wait_until_connected()) publisher.set_value("foo", '12345') loop.run_until_complete(asyncio.sleep(1)) assert received.value == '12345'
def test_time_of_use_policy(): Resource.clearResources() from aizero.time_of_use_resource import Modes dm = DeviceManager(max_power_budget=800, debug=True) fake_time_of_use = Resource("TimeOfUse", variables=["mode"]) fake_time_of_use.set_value("mode", Modes.on_peak) device = DeviceResource("fake_device", 100) device.set_runtime_policy([TimeOfUsePolicy(Modes.off_peak)]) device.run() assert device.running() dm.process_managed_devices() assert not device.running() fake_time_of_use.set_value("mode", Modes.off_peak) dm.process_managed_devices() assert device.running()
def process(self): t = datetime.now().time() try: current_time_resource = Resource.resource("CurrentTimeResource") has_time = current_time_resource.getValue("datetime") if has_time is not None: t = has_time.time() except ResourceNotFoundException: pass except Exception as e: print("night_time: another bad exception: {}".format(e)) self.isNightTime = ((t > self.location.sunset().time() and t <= time(23, 59, 59)) or (t >= time(0) and t < self.location.sunrise().time())) self.sunset = self.location.sunset().time() self.sunrise = self.location.sunrise().time() self.setValue("nightTime", self.isNightTime) self.setValue("night_time", self.isNightTime) self.setValue("sunset", str(self.location.sunset().time())) self.setValue("sunrise", str(self.location.sunrise().time()))
def __init__(self, resource, broker, override_name=None, retain_msgs=False, qos=0, whitelist_variables=None, blacklist_variables=None, quiet=True, **kwargs): super().__init__(name=override_name, broker=broker, **kwargs) self.resource = resource self.whitelist_variables = whitelist_variables self.blacklist_variables = blacklist_variables self.retain = retain_msgs self.qos = qos self.override_name = override_name self.quiet = quiet if isinstance(resource, str): try: self.resource = Resource.resource(resource) self._subscribe() except ResourceNotFoundException: def wait_resource(): self.resource = Resource.resource(resource) self._subscribe() Resource.waitResource(resource, wait_resource) elif isinstance(resource, Resource): self._subscribe() else: raise ValueError("Invalid resource type: {}".format( resource.__class__.__name__)) self.whitelist_variables = whitelist_variables self.blacklist_variables = blacklist_variables self.retain = retain_msgs self.qos = qos self.override_name = override_name self.connected = False
def test_ignore_power_usage(): Resource.clearResources() dm = DeviceManager() fake_device = DeviceResource("fd1", 100) fake_device2 = DeviceResource("fd2", 100) fake_device.run() fake_device2.run() asyncio.get_event_loop().run_until_complete(asyncio.sleep(1)) assert dm.running_power == 200 dm.ignore_power_usage(fake_device2) assert dm.running_power == 100
def __init__(self, linked_device_name, conditions=None, or_conditions=None): super().__init__(policy=RuntimePolicies.link_device_policy, conditions=conditions, or_conditions=or_conditions) self.linked_device_running = None def wait_resource(): self.linked_device_running = gr( linked_device_name).subscribe2("running") try: gr(linked_device_name) wait_resource() except ResourceNotFoundException: Resource.waitResource(linked_device_name, wait_resource)
def __init__(self, name="DeviceManager", max_power_budget=0, power_source=None, debug=False): """ max_power_budget is to be used to define the max power budget when there is no solar system (ie battery system, or pure-grid system). power_source must have the "available_power" property unless max power_budget is set. available_power is max_power_budget until power_source updates. """ super().__init__(name, ["total_power", "running_devices", "capacity", "total_capacity"]) if power_source is None: power_source = ["SolarPower"] if isinstance(power_source, str): power_source = [power_source] power_sources = power_source self.running_devices = [] self.managed_devices = [] self.ignored_devices = [] self.max_power_budget = max_power_budget self.time_of_use_mode = None self.debug = debug self.power_sources = None if not max_power_budget: self.power_sources = ResourceRequires( power_sources, lambda rsrcs: True) def wait_time_of_use(): gr("TimeOfUse").subscribe("mode", self.time_of_use_changed) try: wait_time_of_use() except ResourceNotFoundException: Resource.waitResource("TimeOfUse", wait_time_of_use) self.poller = resource_poll(self.process_managed_devices, MINS(1))
def test_multiple_rows_in_dataframe(): Resource.clearResources() dow = DayOfWeekResource() hod = HourOfDayResource() dow.set_value("day_of_week", 1) dow.set_value("day_of_week", 2) dow.set_value("day_of_week", 3) dow.set_value("day_of_week", 4) assert len(dow.dataframe) == 5 hod.set_value("hour_of_day", 1.2) hod.set_value("hour_of_day", 2.2) hod.set_value("hour_of_day", 1.5) hod.set_value("hour_of_day", 13.1) assert len(hod.dataframe) == 5
def test_runifcan(): Resource.clearResources() device_manager = DeviceManager(max_power_budget=1000) device1 = DeviceResource("my special device", power_usage=500) device2 = DeviceResource("my other device", power_usage=500) device1.run() device2.run() assert device1.running() assert device2.running() device4 = DeviceResource("automated device", power_usage=100, runtime_policy=RunIfCanPolicy()) assert not device4.running() device1.stop() assert device4.running()