diff --git a/README.md b/README.md index 01c4fa4..7260ebd 100644 --- a/README.md +++ b/README.md @@ -43,10 +43,10 @@ This library is configured through the "normal" appdaemon configuration file `ap blind_wohnzimmer_west: class: Blinds module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib + dependencies: + - blind_lib_global + - hysteresis_lib_global + - sun_lib_global blind: cover.raffstore_erdgeschoss_wohnzimmer_west inside_temperature: climate.thermostat_erdgeschoss_wohnzimmer max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours @@ -97,17 +97,34 @@ You need to configure these parameters for every window. ## Installation -- Copy the python files in this into your appdaemon apps/ directory. The files in the `lib/` directory land in the `apps/lib` directory as well. +- For Git users: + Open the terminal and move to the appdaemon/apps directory and clone the git repository + `cd /config/appdaemon/apps` + `clone https://github.com/wogri/hass-blinds.git` + OR if you do not have git installed: + Copy the python files in this repository into your `appdaemon/apps/hass-blinds` directory. The files in the `lib/` directory land in the `apps/lib` directory as well. - Configure your apps.yaml file. Every window gets its own yaml dict. -In addition to configuring every window the engine needs two helper apps. So please don't forget to add those: +In addition to configuring every window the engine needs three helper apps. So please don't forget to add those: ```yaml +blind_lib_global: + module: blinds_lib + global: true + +hysteresis_lib_global: + module: hysteresis_li` + global: true + +sun_lib_global: + module: sun_lib + global: true + sun: class: Sun module: sun - global_dependencies: - - sun_lib + dependencies: + - sun_lib_global max_temp: class: MaxTemp @@ -122,42 +139,32 @@ Both of these help to fill `input_number` variables inside of homeassistant. Tha ### Configuring appdaemon -To do sun math correctly homeassistant and appdaemon need to know where you live. So please be sure to configure the latitude and longitude in `appdaemon.yaml`: +To do sun math correctly homeassistant and appdaemon need to know where you live. So please be sure to configure the latitude and longitude in `appdaemon.yaml` and your `secrets.yaml`: ```yaml appdaemon: - threads: 30 +secrets: /config/secrets.yaml # Location required to calculate the time the sun rises and sets - latitude: 123.456 - longitude: 78.90 + latitude: !secret latitude_home + longitude: !secret longitude_home # Impacts weather/sunrise data (altitude above sea level in meters) - elevation: 303 + elevation: !secret elevation_home time_zone: Europe/Vienna plugins: HASS: type: hass - ha_url: https://my.homeassistant - token: +http: + url: http://127.0.0.1:5050 # Default +admin: +api: +hadashboard: ``` ### Configure homeassistant -In homeassistant's configuration.yaml you want to add the required input numbers so the apps can do some cross communication through homeassistant. You also need to add longitude / latitude and the sun module. +In homeassistant's configuration.yaml you want to add the required input numbers so the apps can do some cross communication through homeassistant. Please ensure also in your setting that your HA location is correctly set. ```yaml -homeassistant: - # Name of the location where Home Assistant is running - name: myhome - # Location required to calculate the time the sun rises and sets - latitude: 123.456 - longitude: 78.90 - # Impacts weather/sunrise data (altitude above sea level in meters) - elevation: 303 - # metric for Metric, imperial for Imperial - unit_system: metric - # Pick yours from here: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones - time_zone: Europe/Vienna - input_number: sun_lux_10_minute_average: min: 0 diff --git a/apps.yaml b/apps.yaml deleted file mode 100644 index c17c6f5..0000000 --- a/apps.yaml +++ /dev/null @@ -1,417 +0,0 @@ -global_modules: -- blinds_lib - - hysteresis_lib -- sun_lib -- hysteresis_lib - -sun: - class: Sun - module: sun - global_dependencies: - - sun_lib - brightness_sensor: sensor.wetter_zentrale_funktionen_helligkeit - brightness_at_dawn_sensor: sensor.wetter_zentrale_funktionen_daemmerung - -max_temp: - class: MaxTemp - module: max_temp - outside_temp_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - max_temp_sensor: input_number.max_outside_temp_over_24_hours - max_temp_sensor_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - -blind_kinderzimmer_oskar: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - blind: cover.raffstore_obergeschoss_kinderzimmer_oskar - contact: binary_sensor.kontakt_obergeschoss_kinderzimmer_oskar - inside_temperature: climate.thermostat_obergeschoss_kinderzimmer_oskar - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - blind_config: - azimuth_entry: 89 - azimuth_exit: 256 - manual_day_control: True - manual_night_control: True - kill_switch_hold_time: 2 - -blind_kinderzimmer_emma: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - blind: cover.raffstore_obergeschoss_kinderzimmer_emma - contact: binary_sensor.kontakt_obergeschoss_kinderzimmer_emma - inside_temperature: climate.thermostat_obergeschoss_kinderzimmer_emma - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - blind_config: - azimuth_entry: 89 - azimuth_exit: 256 - manual_day_control: True - manual_night_control: True - kill_switch_hold_time: 2 - -blind_gang_og_nord_west: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - blind: cover.raffstore_obergeschoss_gang_nord_west - inside_temperature: climate.thermostat_obergeschoss_kinderzimmer_emma - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - blind_config: - # entry and exit should never trigger. If they should take the numbers from below. - #azimuth_entry: 362 - #azimuth_exit: 361 - azimuth_entry: 256 - azimuth_exit: 359 - manual_day_control: True - kill_switch_hold_time: 6 - dawn_lights: - - light.dimmer_obergeschoss_gang_og - - light.dimmer_obergeschoss_lesefenster_west_og - -blind_gang_og_nord_ost: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - blind: cover.raffstore_obergeschoss_gang_nord_ost - inside_temperature: climate.thermostat_obergeschoss_kinderzimmer_emma - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - blind_config: - # entry and exit should never trigger. If they should take the numbers from below. - #azimuth_entry: 362 - #azimuth_exit: 361 - azimuth_entry: 256 - azimuth_exit: 359 - manual_day_control: True - kill_switch_hold_time: 6 - dawn_lights: - - light.dimmer_obergeschoss_gang_og - - light.dimmer_obergeschoss_lesefenster_ost_og - -blind_wc_obergeschoss: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - blind: cover.raffstore_obergeschoss_wc_obergeschoss - contact: binary_sensor.kontakt_obergeschoss_wc - inside_temperature: climate.thermostat_obergeschoss_kinderzimmer_emma - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - blind_config: - # entry and exit should never trigger. - azimuth_entry: 361 - azimuth_exit: 0 - # manual_night_control: True - -blind_esszimmer_west_hebe_schiebetuer: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - inside_temperature: sensor.erdgeschoss_esszimmer_temperatur - inside_temperature_is_no_thermostat: true - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - blind: cover.raffstore_erdgeschoss_kueche_schiebetuer_west - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - contact: binary_sensor.kontakt_erdgeschoss_kueche_hebe_schiebetuer - blind_config: - azimuth_entry: 173 - azimuth_exit: 276 - ledge: 200 - window_azimuth_position: 263 - window_type: door - kill_switch_hold_time: 4 - # manual_night_control: True - dawn_lights: - - light.dimmer_erdgeschoss_essbereich - - light.dimmer_erdgeschoss_kuechenzeile - - light.licht_erdgeschoss_esstisch - -blind_esszimmer_west_fix: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - inside_temperature: sensor.erdgeschoss_esszimmer_temperatur - inside_temperature_is_no_thermostat: true - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - blind: cover.raffstore_erdgeschoss_kueche_fixteil_west - blind_config: - azimuth_entry: 173 - azimuth_exit: 289 - ledge: 200 - window_azimuth_position: 263 - kill_switch_hold_time: 4 - dawn_lights: - - light.dimmer_erdgeschoss_essbereich - - light.dimmer_erdgeschoss_kuechenzeile - - light.licht_erdgeschoss_esstisch - -blind_kueche_ost: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - blind: cover.raffstore_erdgeschoss_kueche_drehtuer_ost - inside_temperature: sensor.erdgeschoss_esszimmer_temperatur - inside_temperature_is_no_thermostat: true - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - contact: binary_sensor.kontakt_erdgeschoss_kueche_drehtuer - blind_config: - azimuth_entry: 10 - azimuth_exit: 170 - manual_night_control: True - window_type: door - -blind_wc_erdgeschoss: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - blind: cover.raffstore_erdgeschoss_wc_erdgeschoss - inside_temperature: sensor.erdgeschoss_esszimmer_temperatur - inside_temperature_is_no_thermostat: true - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - blind_config: - azimuth_entry: 10 - azimuth_exit: 170 - # manual_night_control: True - max_inside_temperature_cold_day: 25.0 - max_inside_temperature_warm_day: 25.0 - -blind_esszimmer_ost_fix: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - blind: cover.raffstore_erdgeschoss_kueche_fixverglasung_ost - inside_temperature: sensor.erdgeschoss_esszimmer_temperatur - inside_temperature_is_no_thermostat: true - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - blind_config: - azimuth_entry: 10 - azimuth_exit: 170 - lux_blind_down_threshold: 30000 - lux_blind_up_threshold: 15000 - kill_switch_hold_time: 2 - dawn_lights: - - light.dimmer_erdgeschoss_essbereich - - light.dimmer_erdgeschoss_kuechenzeile - - light.licht_erdgeschoss_esstisch - -blind_buero_ost: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - blind: cover.raffstore_erdgeschoss_arbeitszimmer_erdgeschoss - inside_temperature: sensor.erdgeschoss_esszimmer_temperatur - inside_temperature_is_no_thermostat: true - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - blind_config: - azimuth_entry: 10 - azimuth_exit: 170 - manual_night_control: True - -blind_wohnzimmer_sued: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - blind: cover.raffstore_erdgeschoss_wohnzimmer_fixteil_sued - inside_temperature: climate.thermostat_erdgeschoss_wohnzimmer - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - blind_config: - azimuth_entry: 89 - azimuth_exit: 258 - manual_night_control: True - max_inside_temperature_cold_day: 24 - kill_switch_hold_time: 4 - -blind_wohnzimmer_west: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - blind: cover.raffstore_erdgeschoss_wohnzimmer_west - inside_temperature: climate.thermostat_erdgeschoss_wohnzimmer - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - contact: binary_sensor.kontakt_erdgeschoss_wohnzimmer_hebe_schiebetuer - blind_config: - azimuth_entry: 173 - azimuth_exit: 290 - manual_night_control: True - window_type: door - max_inside_temperature_cold_day: 24 - kill_switch_hold_time: 4 - -blind_mancave: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - blind: cover.raffstore_keller_mancave - inside_temperature: climate.thermostat_keller_mancave - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - contact: binary_sensor.kontakt_keller_mancave - blind_config: - azimuth_entry: 91 - azimuth_exit: 147 - manual_night_control: True - manual_day_control: True - -blind_abstellraum_og_ost: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - blind: cover.raffstore_obergeschoss_abstellraum_obergeschoss_fenster_ost - inside_temperature: climate.thermostat_obergeschoss_kinderzimmer_emma - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - blind_config: - azimuth_entry: 10 - azimuth_exit: 170 - manual_night_control: True - -blind_bad_og: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - blind: cover.raffstore_obergeschoss_bad_obergeschoss - contact: binary_sensor.kontakt_obergeschoss_bad - inside_temperature: climate.thermostat_obergeschoss_kinderzimmer_emma - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - blind_config: - azimuth_entry: 89 - azimuth_exit: 256 - manual_night_control: True - -blind_schlafzimmer_og: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - blind: cover.raffstore_obergeschoss_schlafzimmer - contact: binary_sensor.kontakt_obergeschoss_schlafzimmer - inside_temperature: climate.thermostat_obergeschoss_kinderzimmer_emma - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - blind_config: - ledge: 135 - window_height: 205 - azimuth_entry: 89 - window_azimuth_position: 173 - window_type: door - azimuth_exit: 246 - manual_night_control: True - manual_day_control: True - max_inside_temperature_cold_day: 21.0 - -blind_abstellraum_og_nord: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - blind: cover.raffstore_obergeschoss_abstellraum_obergeschoss_fenster_nord - inside_temperature: climate.thermostat_obergeschoss_kinderzimmer_emma - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - blind_config: - azimuth_entry: 258.77 - azimuth_exit: 359.55 - -blind_gang_og_sued: - class: Blinds - module: blinds - global_dependencies: - - blinds_lib - - hysteresis_lib - - sun_lib - blind: cover.raffstore_obergeschoss_gang_drehtuer_sued - contact: binary_sensor.kontakt_obergeschoss_ausgang_terasse - inside_temperature: climate.thermostat_obergeschoss_kinderzimmer_emma - wind_alarm: binary_sensor.wetter_zentrale_funktionen_windalarm_jalousien - outside_temperature_sensor: sensor.wetter_zentrale_funktionen_aussentemperatur - max_temp_sensor_value_yesterday: input_number.yesterdays_max_outside_temp_over_24_hours - blind_config: - window_height: 205 - ledge: 135 - azimuth_entry: 89 - window_azimuth_position: 173 - window_type: door - azimuth_exit: 210 - manual_night_control: True - kill_switch_hold_time: 2 diff --git a/blinds.py b/blinds.py index 2223863..9ee61f6 100644 --- a/blinds.py +++ b/blinds.py @@ -21,15 +21,15 @@ def initialize(self): self.args["min_temp_sensor_value_yesterday"] = "input_number.yesterdays_min_outside_temp_over_24_hours" self.set_max_outside_temp(None) if "contact" in self.args: - self.listen_state(self.window_closed, entity=self.args["contact"], new="off", old="on") + self.listen_state(self.window_closed, entity_id=self.args["contact"], new="off", old="on") if "wind_alarm" in self.args: - self.listen_state(self.wind_alarm_off, entity=self.args["wind_alarm"], new="off", old="on") + self.listen_state(self.wind_alarm_off, entity_id=self.args["wind_alarm"], new="off", old="on") if "dawn_lights" in self.args: for light in self.args["dawn_lights"]: - self.listen_state(self.light_on, entity=light, new="on", old="off") - self.listen_state(self.light_off, entity=light, new="off", old="on") + self.listen_state(self.light_on, entity_id=light, new="on", old="off") + self.listen_state(self.light_off, entity_id=light, new="off", old="on") def window_closed(self, entity, attribute, old, new, kwargs): if "window_type" in self.args["blind_config"] and self.args["blind_config"]["window_type"] == "door": @@ -129,6 +129,7 @@ def set_state_reason(self, reason): obj = "input_text.%s_status" % self.args["blind"].replace("cover.", "") self.call_service("input_text/set_value", entity_id=obj, value=reason) + def set_max_outside_temp(self, _unused): max_outside_temp = self.get_state(self.args["max_temp_sensor_value_yesterday"]) if self.is_not_a_number(max_outside_temp): diff --git a/max_temp.py b/max_temp.py index 2592c6c..dc85068 100644 --- a/max_temp.py +++ b/max_temp.py @@ -6,11 +6,11 @@ class MaxTemp(hass.Hass): def initialize(self): self.log("Initializing Maximum Temperature system...") - self.listen_state(self.temperature_update, entity=self.args["outside_temp_sensor"]) + self.listen_state(self.temperature_update, entity_id=self.args["outside_temp_sensor"]) time = datetime.time(0, 0, 0) self.run_daily(self.reset, time) - def temperature_update(self, _m, _n, _o, new, kwargs): + def temperature_update(self, _m, _n, _o, new, cb_args): if new == None: return max_temp_so_far = float(self.get_state(self.args["max_temp_sensor"])) @@ -20,7 +20,7 @@ def temperature_update(self, _m, _n, _o, new, kwargs): # self.log("New daily record for maximum temperatur. Was: %s, new temp is: %s" % (max_temp_so_far, new)) def reset(self, _unused): - # reset this and store the old value somewhere. + # reset this and store the old value somewhere self.call_service("input_number/set_value", entity_id=self.args["max_temp_sensor_yesterday"], value=self.get_state(self.args["max_temp_sensor"])) @@ -28,3 +28,4 @@ def reset(self, _unused): self.call_service("input_number/set_value", entity_id=self.args["max_temp_sensor"], value=self.get_state(self.args["outside_temp_sensor"])) + \ No newline at end of file diff --git a/sun.py b/sun.py index 33486f5..e4cce6e 100644 --- a/sun.py +++ b/sun.py @@ -7,10 +7,10 @@ class Sun(hass.Hass, Sun): def initialize(self): self.log("Initializing Sun data collector...") - self.listen_state(self.lux, entity=self.args["brightness_sensor"]) - self.listen_state(self.lux, entity=self.args["brightness_at_dawn_sensor"]) + self.listen_state(self.lux, entity_id=self.args["brightness_sensor"]) + self.listen_state(self.lux, entity_id=self.args["brightness_at_dawn_sensor"]) self.lux_values = [] - time = datetime.time(1, 1, 35) + time = datetime.time(0, 0, 30) self.run_minutely(self.lux, time) def lux(self, entity=None, attribute=None, old=None, new=None, kwargs=None):