diff --git a/.gitignore b/.gitignore index 2af6b44..1dbcfc6 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,7 @@ node_modules /custom_components/hacs /custom_components/scheduler /custom_components/pyscript +/custom_components/homematicip_local /themes -/.storage/hacs/*.hacs \ No newline at end of file +/node-red +/.storage/hacs/*.hacs diff --git a/config_creation/groups.yaml b/config_creation/groups.yaml index aacb561..302b21f 100644 --- a/config_creation/groups.yaml +++ b/config_creation/groups.yaml @@ -56,6 +56,7 @@ kids_room: - light.kinderzimmer_fluter - cover.kinderzimmer_rollo - light.music_mouse_regal_licht + - light.kinderzimmer_deckenlampe bathroom: name: Bad diff --git a/config_creation/knx_conf.py b/config_creation/knx_conf.py index 456e09c..ee278b5 100644 --- a/config_creation/knx_conf.py +++ b/config_creation/knx_conf.py @@ -43,7 +43,7 @@ def create_power_plug(device_info: List[DeviceInfo], postfix_counter_reset=" BSZ Neustart"): result = {'switch': [], 'sensor': []} - template_sensors = {'sensor': []} + template_sensors = {'template': {'sensor': []}} for entry in device_info: try: # Switching @@ -82,13 +82,11 @@ def create_power_plug(device_info: List[DeviceInfo], 'type': 'DPT-9', }) name = name_to_id(entry.display_name + " Verbrauch mA", 'sensor') - template_sensors['sensor'].append({ - 'platform': 'template', - 'sensors': { - name_to_id(entry.display_name + " Verbrauch", None): - {'friendly_name': entry.display_name + " Verbrauch", - 'unit_of_measurement': 'W', - 'value_template': f"{{{{ (states('{name}') | float / 1000 * 230) | round(1) }}}}"}} + template_sensors['template']['sensor'].append({ + 'unique_id': name_to_id(entry.display_name + " Verbrauch", None), + 'name': entry.display_name + " Verbrauch", + 'unit_of_measurement': 'W', + 'state': f"{{{{ (states('{name}') | float / 1000 * 230) | round(1) }}}}" }) consumption_sum = csv_contents.get(entry.csv_name + postfix_consumption_sum, None) if consumption_sum: diff --git a/config_creation/manual_config.yaml b/config_creation/manual_config.yaml index 31708ff..045ac45 100644 --- a/config_creation/manual_config.yaml +++ b/config_creation/manual_config.yaml @@ -226,27 +226,27 @@ octoprint: number_of_tools: 1 bed: true -telegram_bot: - - platform: webhooks - parse_mode: html - url: https://ha.bauer.tech - api_key: !secret telegram_token - allowed_chat_ids: - - !secret telegram_chatid_martin - trusted_networks: - - 127.0.0.1/32 - - 192.168.178.80 - - 149.154.167.197/32 - - 149.154.167.198/31 - - 149.154.167.200/29 - - 149.154.167.208/28 - - 149.154.167.224/29 - - 149.154.167.232/31 +#telegram_bot: +# - platform: webhooks +# parse_mode: html +# url: https://ha.bauer.tech +# api_key: !secret telegram_token +# allowed_chat_ids: +# - !secret telegram_chatid_martin +# trusted_networks: +# - 127.0.0.1/32 +# - 192.168.178.80 +# - 149.154.167.197/32 +# - 149.154.167.198/31 +# - 149.154.167.200/29 +# - 149.154.167.208/28 +# - 149.154.167.224/29 +# - 149.154.167.232/31 -notify: - - name: telegram_martin - platform: telegram - chat_id: !secret telegram_chatid_martin +#notify: +# - name: telegram_martin +# platform: telegram +# chat_id: !secret telegram_chatid_martin # Custom stuff @@ -258,6 +258,7 @@ counter: initial: 0 step: 1 + #switch: # - platform: httpsispmctl # name: esszimmer_oben_radio_steckdose @@ -297,52 +298,52 @@ logger: # Weather prediction # - platform: yr -tts: - - platform: watson_tts - watson_apikey: !secret watson_api_key - watson_url: https://gateway-lon.watsonplatform.net/text-to-speech/api - voice: de-DE_BirgitVoice - output_format: audio/flac - output_audio_rate: 44100 +#tts: +# - platform: watson_tts +# watson_apikey: !secret watson_api_key +# watson_url: https://gateway-lon.watsonplatform.net/text-to-speech/api +# voice: de-DE_BirgitVoice +# output_format: audio/flac +# output_audio_rate: 44100 -alexa: - smart_home: - locale: de-DE - #endpoint: https://api.eu.amazonalexa.com/v3/events - #client_id: amzn1.application-oa2-client.a4de8a70130c4f9383b277044f07a3af - #client_secret: !secret alexa_client_secret - filter: - include_entities: - # Light Groups - #- light.kuche_esszimmer_lichter - #- light.arbeitszimmer_lichter - # Arbeitszimmer - - light.arbeitszimmer_deckenlampe - - light.arbeitszimmer_fluter - - light.arbeitszimmer_stehlampe_unten - - light.arbeitszimmer_stehlampe_oben - - cover.arbeitszimmer_rollo - - scene.arbeitszimmer_orange - - scene.arbeitszimmer_blau_grun - - scene.arbeitszimmer_hell - # Gang - - light.gang_bogen - - light.gang_licht - - light.gang_einganglicht - # Wohnbereich - - cover.wohnzimmer_fenster_rollo - - cover.wohnzimmer_terrassentur_rollo - - cover.kuche_fenster_rollo - - cover.esszimmer_fenster_rollo - entity_config: - cover.arbeitszimmer_rollo: - display_categories: EXTERIOR_BLIND - cover.wohnzimmer_fenster_rollo: - display_categories: EXTERIOR_BLIND - cover.wohnzimmer_terrassentur_rollo: - display_categories: EXTERIOR_BLIND - cover.esszimmer_fenster_rollo: - display_categories: EXTERIOR_BLIND +#alexa: +# smart_home: +# locale: de-DE +# #endpoint: https://api.eu.amazonalexa.com/v3/events +# #client_id: amzn1.application-oa2-client.a4de8a70130c4f9383b277044f07a3af +# #client_secret: !secret alexa_client_secret +# filter: +# include_entities: +# # Light Groups +# #- light.kuche_esszimmer_lichter +# #- light.arbeitszimmer_lichter +# # Arbeitszimmer +# - light.arbeitszimmer_deckenlampe +# - light.arbeitszimmer_fluter +# - light.arbeitszimmer_stehlampe_unten +# - light.arbeitszimmer_stehlampe_oben +# - cover.arbeitszimmer_rollo +# - scene.arbeitszimmer_orange +# - scene.arbeitszimmer_blau_grun +# - scene.arbeitszimmer_hell +# # Gang +# - light.gang_bogen +# - light.gang_licht +# - light.gang_einganglicht +# # Wohnbereich +# - cover.wohnzimmer_fenster_rollo +# - cover.wohnzimmer_terrassentur_rollo +# - cover.kuche_fenster_rollo +# - cover.esszimmer_fenster_rollo +# entity_config: +# cover.arbeitszimmer_rollo: +# display_categories: EXTERIOR_BLIND +# cover.wohnzimmer_fenster_rollo: +# display_categories: EXTERIOR_BLIND +# cover.wohnzimmer_terrassentur_rollo: +# display_categories: EXTERIOR_BLIND +# cover.esszimmer_fenster_rollo: +# display_categories: EXTERIOR_BLIND homekit: name: !secret homekit_name @@ -396,6 +397,10 @@ homekit: - light.gartenhaus_deckenlicht_mitte - light.gartenhaus_deckenlicht_vorne - light.gartenhaus_wandlicht + - switch.pool_pumpe_switch + - switch.pool_pumpe_speed1 + - switch.pool_pumpe_speed2 + - switch.pool_pumpe_speed3 # -- Schlafzimmer - light.schlafzimmer_deckenlampe - light.schlafzimmer_fluter @@ -424,82 +429,84 @@ homekit: - light.kinderzimmer_deckenlampe - cover.kinderzimmer_rollo - light.music_mouse_regal_licht + - light.kinderzimmer_fluter -google_assistant: - project_id: homeassistant-d3afc - service_account: !include google_assistant_service_account.json - report_state: true - expose_by_default: false - entity_config: - # Arbeitszimmer - light.arbeitszimmer_deckenlampe: - room: Arbeitszimmer - light.arbeitszimmer_fluter: - room: Arbeitszimmer - light.arbeitszimmer_stehlampe_unten: - room: Arbeitszimmer - light.arbeitszimmer_stehlampe_oben: - room: Arbeitszimmer - cover.arbeitszimmer_rollo: - room: Arbeitszimmer - scene.arbeitszimmer_orange: - room: Arbeitszimmer - scene.arbeitszimmer_blau_grun: - room: Arbeitszimmer - scene.arbeitszimmer_hell: - room: Arbeitszimmer - # Gang - light.gang_bogen: - room: Gang - light.gang_licht: - room: Gang - light.gang_einganglicht: - room: Gang - # Wohnbereich - cover.wohnzimmer_fenster_rollo: - room: Wohnbereich - cover.wohnzimmer_terrassentur_rollo: - room: Wohnbereich - cover.kuche_fenster_rollo: - room: Wohnbereich - cover.esszimmer_fenster_rollo: - room: Wohnbereich +#google_assistant: +# project_id: homeassistant-d3afc +# service_account: !include google_assistant_service_account.json +# report_state: true +# expose_by_default: false +# entity_config: +# # Arbeitszimmer +# light.arbeitszimmer_deckenlampe: +# room: Arbeitszimmer +# light.arbeitszimmer_fluter: +# room: Arbeitszimmer +# light.arbeitszimmer_stehlampe_unten: +# room: Arbeitszimmer +# light.arbeitszimmer_stehlampe_oben: +# room: Arbeitszimmer +# cover.arbeitszimmer_rollo: +# room: Arbeitszimmer +# scene.arbeitszimmer_orange: +# room: Arbeitszimmer +# scene.arbeitszimmer_blau_grun: +# room: Arbeitszimmer +# scene.arbeitszimmer_hell: +# room: Arbeitszimmer +# # Gang +# light.gang_bogen: +# room: Gang +# light.gang_licht: +# room: Gang +# light.gang_einganglicht: +# room: Gang +# # Wohnbereich +# cover.wohnzimmer_fenster_rollo: +# room: Wohnbereich +# cover.wohnzimmer_terrassentur_rollo: +# room: Wohnbereich +# cover.kuche_fenster_rollo: +# room: Wohnbereich +# cover.esszimmer_fenster_rollo: +# room: Wohnbereich knx: !include knx_conf.yaml -homematic: - interfaces: - rf: - host: de838cd8-raspberrymatic - port: 2001 - resolvenames: json - username: homeassistant - password: !secret homematic_pw - wired: - host: de838cd8-raspberrymatic - port: 2000 - resolvenames: json - username: homeassistant - password: !secret homematic_pw - hmip: - host: de838cd8-raspberrymatic - port: 2010 - resolvenames: json - username: homeassistant - password: !secret homematic_pw - groups: - host: de838cd8-raspberrymatic - port: 9292 - resolvenames: json - username: homeassistant - password: !secret homematic_pw - path: /groups - hosts: - raspberrymatic: - host: de838cd8-raspberrymatic - username: homeassistant - password: !secret homematic_pw +#homematic: +# interfaces: +# rf: +# host: 127.0.0.1 +# port: 2001 +# resolvenames: json +# username: homeassistant +# password: !secret homematic_pw +# wired: +# host: 127.0.0.1 +# port: 2000 +# resolvenames: json +# username: homeassistant +# password: !secret homematic_pw +# hmip: +# host: 127.0.0.1 +# port: 2010 +# resolvenames: json +# username: homeassistant +# password: !secret homematic_pw +# groups: +# host: 127.0.0.1 +# port: 9292 +# resolvenames: json +# username: homeassistant +# password: !secret homematic_pw +# path: /groups +# hosts: +# raspberrymatic: +# host: 127.0.0.1 +# port: 2001 +# username: homeassistant +# password: !secret homematic_pw #zwave: # usb_path: /dev/serial/by-id/usb-0658_0200-if00 @@ -542,7 +549,7 @@ sysdweb: - irserver - squeezelite - shairport-sync - - dht22_sensing + #- dht22_sensing - logitechmediaserver lirc_network: @@ -573,21 +580,92 @@ media_player: - platform: squeezebox_telnet host: musikserverWohnzimmerOben.fritz.box +template: +- sensor: + - default_entity_id: motion_combined + friendly_name: Bewegung + state: > + {%- set pirs = {'Gang Mitte': states.binary_sensor.gang_bewegungsmelder_mitte, + 'Eingang': states.binary_sensor.gang_bewegungsmelder_ost, + 'Gang Hinten': states.binary_sensor.gang_bewegungsmelder_schlafzimmer, + 'Gang Wohnzimmer': states.binary_sensor.gang_bewegungsmelder_wohnzimmer} %} + {% for pir_name, pir in pirs.items() %} + {% if as_timestamp(pir.last_changed) == as_timestamp(pirs.values() | map(attribute='last_changed') | max) %} + {{ pir_name }} + {% endif %} + {% endfor %} + - default_entity_id: oxilife_ph_filtered + friendly_name: Oxilify pH Filtered + unit_of_measurement: "{{ states.sensor.oxilife_ph.attributes.unit_of_measurement }}" + state: > + {% if 200 <= states('sensor.gartenhaus_steckdose2_verbrauch') | float %} + {{ states('sensor.oxilife_ph') }} + {% else %} + unknown + {% endif %} + - default_entity_id: oxilife_redox_level_filtered + friendly_name: Oxilify Redox Filtered + unit_of_measurement: "{{ states.sensor.oxilife_redox_level.attributes.unit_of_measurement }}" + state: > + {% if 200 <= states('sensor.gartenhaus_steckdose2_verbrauch') | float %} + {{ states('sensor.oxilife_redox_level') }} + {% else %} + unknown + {% endif %} + - default_entity_id: pool_temperatur_filtered + friendly_name: Oxilify Temperature Filtered + unit_of_measurement: "{{ states.sensor.pool_temperatur.attributes.unit_of_measurement }}" + state: > + {% if 200 <= states('sensor.gartenhaus_steckdose2_verbrauch') | float %} + {{ states('sensor.pool_temperatur') }} + {% else %} + unknown + {% endif %} +- switch: + - unique_id: pool_pumpe_switch + state: "{{ 1 if 100 <= states('sensor.gartenhaus_steckdose2_verbrauch') | float else 0 }}" + turn_on: + service: script.pool_pumpe_schalten + data: + value: 1 + turn_off: + service: script.pool_pumpe_schalten + data: + value: 0 + - unique_id: pool_pumpe_speed1 + state: "{{ 200 <= states('sensor.gartenhaus_steckdose2_verbrauch') | float < 650 }}" + turn_on: + service: script.pool_pumpe_schalten + data: + value: 1 + turn_off: + service: script.pool_pumpe_schalten + data: + value: 0 + - unique_id: pool_pumpe_speed2 + state: "{{ 650 <= states('sensor.gartenhaus_steckdose2_verbrauch') | float < 1100 }}" + turn_on: + service: script.pool_pumpe_schalten + data: + value: 2 + turn_off: + service: script.pool_pumpe_schalten + data: + value: 0 + - unique_id: pool_pumpe_speed3 + state: "{{ 1100 <= states('sensor.gartenhaus_steckdose2_verbrauch') | float }}" + turn_on: + service: script.pool_pumpe_schalten + data: + value: 3 + turn_off: + service: script.pool_pumpe_schalten + data: + value: 0 + + + sensor: - - platform: template - sensors: - motion_combined: - friendly_name: Bewegung - value_template: > - {%- set pirs = {'Gang Mitte': states.binary_sensor.gang_bewegungsmelder_mitte, - 'Eingang': states.binary_sensor.gang_bewegungsmelder_ost, - 'Gang Hinten': states.binary_sensor.gang_bewegungsmelder_schlafzimmer, - 'Gang Wohnzimmer': states.binary_sensor.gang_bewegungsmelder_wohnzimmer} %} - {% for pir_name, pir in pirs.items() %} - {% if as_timestamp(pir.last_changed) == as_timestamp(pirs.values() | map(attribute='last_changed') | max) %} - {{ pir_name }} - {% endif %} - {% endfor %} - platform: time_date display_options: - 'time' diff --git a/config_creation/secrets.yaml b/config_creation/secrets.yaml index 8c5ee99..f7952b0 100644 --- a/config_creation/secrets.yaml +++ b/config_creation/secrets.yaml @@ -4,4 +4,4 @@ telegram_token: 824902906:AAHKLyNuEX_Sd_r0S-3jiZ-OPnlWnO8XSeM telegram_chatid_martin: 747324122 sysdweb_pw: jo8ddgrUmGj7cP1mk43z camera_pw: 1238djie!d24yu -ondilo_pw: AxZY4lCMFb \ No newline at end of file +ondilo_pw: AxZY4lCMFb diff --git a/pyscript/ios_actions.py b/pyscript/ios_actions.py index e991063..e71a099 100644 --- a/pyscript/ios_actions.py +++ b/pyscript/ios_actions.py @@ -1,40 +1,6 @@ -from datetime import datetime, timedelta - +from datetime import datetime from ir_helpers import * -TIMEOUT_REPEAT_PRESS = 5 # time to switch states when pressed shortly in sequence, in seconds - -# --------------------------------- Helper functions ---------------------------------------------------- - -light_scene_helper_dict = {} -def scene_helper(scene_function): - """Function to manage the repeated press of the same action - When pressed shortly in sequence, states are cycled - Otherwise light is toggled""" - unique_name_for_globals = id(scene_function) - is_on_func, scenes = scene_function() - last_called, call_idx = light_scene_helper_dict.get(unique_name_for_globals, (datetime.now(), -1)) - now = datetime.now() - time_since_last_call = now - last_called - recently_called = (time_since_last_call < timedelta(seconds=TIMEOUT_REPEAT_PRESS)) - light_already_on = is_on_func() - log.warning(f"{light_already_on=}") - if recently_called: - call_idx = (call_idx + 1) - else: - call_idx = -1 - - if light_already_on and call_idx == -1: - scenes[-1]() - call_idx = -1 - elif not light_already_on: - scenes[0]() - call_idx = 0 - else: - idx = call_idx % len(scenes) - scenes[idx]() - - light_scene_helper_dict[unique_name_for_globals] = (now, call_idx) # --------------------------------- "Scenes" for actions ---------------------------------------------------- diff --git a/pyscript/ir_remote_kinderzimmer.py b/pyscript/ir_remote_kinderzimmer.py index 1c66687..a771973 100644 --- a/pyscript/ir_remote_kinderzimmer.py +++ b/pyscript/ir_remote_kinderzimmer.py @@ -5,32 +5,36 @@ async def regal_licht_f(**kwargs): await hass.services.async_call('light', 'turn_on', {'entity_id': "light.music_mouse_regal_licht", 'effect': 'static', **kwargs}) return f -@event_trigger("ir_command_received", "host == 'musicmouse.fritz.box' and repeat_counter == 0 and remote == 'ir_led3'") +@event_trigger("ir_command_received", "host == 'musicmouse.fritz.box' and repeat_counter == 0 and remote == 'small_led_remote'") def ir_remote_kinderzimmer(button_name=None, **kwargs): + def dim_offset_f(offset): + async def f(): + await hass.services.async_call('dimmer', 'dim', {'entity_id': 'group.kids_room', 'offset': offset}) + return f + mapping = { - 'key_on': scene_f('kinderzimmer_hell'), - 'key_off': light_f("turn_off", entity_id="group.kids_room"), - 'key_brightnessup': cover_f('open_cover', 'cover.kinderzimmer_rollo'), - 'key_brightnessdown': cover_f('close_cover', 'cover.kinderzimmer_rollo'), - 'key_white': scene_f('kinderzimmer_hell'), - 'key_red': scene_f('kinderzimmer_wickeln_nachts'), - 'key_pound': regal_licht_f(rgbw_color=[255, 30, 60, 0]), - 'key_1': regal_licht_f(rgbw_color=[255, 30, 60, 0]), - 'key_2': regal_licht_f(rgbw_color=[28, 255, 35, 0]), - 'key_3': regal_licht_f(rgbw_color=[0, 0, 255, 0]), - 'key_4': regal_licht_f(rgbw_color=[255, 156, 17, 0]), - 'key_5': regal_licht_f(rgbw_color=[12, 166, 255, 0]), - 'key_6': regal_licht_f(rgbw_color=[185, 10, 255, 0]), - 'key_7': regal_licht_f(rgbw_color=[255, 156, 17, 0], brightness=50, effect="side_0.2_inc8"), - 'key_8': regal_licht_f(rgbw_color=[0, 0, 255, 0], brightness=50, effect="side_0.2_inc8"), - 'key_9': regal_licht_f(rgbw_color=[255, 30, 60, 0], brightness=50, effect="side_0.2_inc8"), + 'on': scene_f('kinderzimmer_hell'), + 'off': light_f("turn_off", entity_id="group.kids_room"), + 'brightness_up': cover_f('open_cover', 'cover.kinderzimmer_rollo'), + 'brightness_down': cover_f('close_cover', 'cover.kinderzimmer_rollo'), + 'white': scene_f('kinderzimmer_hell'), + 'red': scene_f('kinderzimmer_wickeln_nachts'), + 'hash_pink': regal_licht_f(rgbw_color=[255, 30, 60, 0]), + '1_orange': regal_licht_f(rgbw_color=[255, 30, 60, 0]), + '2_green': regal_licht_f(rgbw_color=[28, 255, 35, 0]), + '3_light_blue': regal_licht_f(rgbw_color=[0, 0, 255, 0]), + '4_orange': regal_licht_f(rgbw_color=[255, 156, 17, 0]), + '5_blue': regal_licht_f(rgbw_color=[12, 166, 255, 0]), + '6_purple': regal_licht_f(rgbw_color=[185, 10, 255, 0]), + '7_yellow': regal_licht_f(rgbw_color=[255, 156, 17, 0], brightness=50, effect="side_0.2_inc8"), + '8_light_blue': regal_licht_f(rgbw_color=[0, 0, 255, 0], brightness=50, effect="side_0.2_inc8"), + '9_pink': regal_licht_f(rgbw_color=[255, 30, 60, 0], brightness=50, effect="side_0.2_inc8"), + 'star_yellow': scene_f('kinderzimmer_regal_dunkel'), + 'fade': dim_offset_f(+30), + 'smooth': dim_offset_f(-30), } if button_name in mapping: mapping[button_name]() - elif button_name == 'key_smooth': - dimmer.dim(entity_id="light.music_mouse_regal_licht", offset=-30) - elif button_name == 'key_fade': - dimmer.dim(entity_id="light.music_mouse_regal_licht", offset=+30) @event_trigger("ir_command_received", "host == 'musicmouse.fritz.box' and repeat_counter == 0 and remote == 'Hauppauge'") def ir_remote_hauppauge_kinderzimmer(button_name=None, **kwargs): @@ -39,6 +43,16 @@ def ir_remote_hauppauge_kinderzimmer(button_name=None, **kwargs): **default_ir_light_control('group.kids_room'), **default_ir_cover_control('group.kids_room'), **default_ir_music_control(**p), + + 'key_red': scene_f('kinderzimmer_regal_dunkel'), + 'key_green': scene_f('kinderzimmer_orange'), + 'key_yellow': scene_f('kinderzimmer_hell'), + 'key_blue': scene_f('kinderzimmer_normal'), + + 'btn_1': playlist_f('Good Morning', **p), + 'btn_2': playlist_f('Good Night Long', **p), + 'btn_3': playlist_f('Good Night', **p), + 'key_video': playlist_f('Good Night', **p), } if button_name in mapping: mapping[button_name]() \ No newline at end of file diff --git a/pyscript/licht_schlafzimmer.py b/pyscript/licht_schlafzimmer.py index a9c02ec..5a64f8f 100644 --- a/pyscript/licht_schlafzimmer.py +++ b/pyscript/licht_schlafzimmer.py @@ -4,11 +4,11 @@ # unten: kurz: off, but 1 min bedlight # lang: rollos zu: nur tagsueber wenn komplett offen @event_trigger("homematic.keypress", "name == 'schlafzimmer_deckenlampe'") -def schlafzimmer_licht(channel=None, param=None, **kwargs): - up = (channel == 2) - down = (channel == 1) - long = (param == "PRESS_LONG") - short = not long +def schlafzimmer_licht(subtype=None, type=None, **kwargs): + up = (subtype == 2) + down = (subtype == 1) + long = (type == "press_long") + short= (type == "press_short") log.info(f"Schlafzimmer knopf up {up}, long {long}") if up and short: diff --git a/pyscript/modules/ir_helpers.py b/pyscript/modules/ir_helpers.py index b04d23a..b324682 100644 --- a/pyscript/modules/ir_helpers.py +++ b/pyscript/modules/ir_helpers.py @@ -1,3 +1,4 @@ +from datetime import datetime, timedelta # ---------------------------------- Music --------------------------------------------- URLS = { @@ -129,3 +130,39 @@ class CyclicCounter: def prev(self): self.idx = (self.idx - 1) % len(self.values) self.func(self.values[self.idx]) + + + +TIMEOUT_REPEAT_PRESS = 5 # time to switch states when pressed shortly in sequence, in seconds + +# --------------------------------- Helper functions ---------------------------------------------------- + +light_scene_helper_dict = {} +def scene_helper(scene_function): + """Function to manage the repeated press of the same action + When pressed shortly in sequence, states are cycled + Otherwise light is toggled""" + unique_name_for_globals = id(scene_function) + is_on_func, scenes = scene_function() + last_called, call_idx = light_scene_helper_dict.get(unique_name_for_globals, (datetime.now(), -1)) + now = datetime.now() + time_since_last_call = now - last_called + recently_called = (time_since_last_call < timedelta(seconds=TIMEOUT_REPEAT_PRESS)) + light_already_on = is_on_func() + log.warning(f"{light_already_on=}") + if recently_called: + call_idx = (call_idx + 1) + else: + call_idx = -1 + + if light_already_on and call_idx == -1: + scenes[-1]() + call_idx = -1 + elif not light_already_on: + scenes[0]() + call_idx = 0 + else: + idx = call_idx % len(scenes) + scenes[idx]() + + light_scene_helper_dict[unique_name_for_globals] = (now, call_idx) \ No newline at end of file