diff --git a/berry/haco.be b/berry/haco.be index 6310045..3f79d22 100644 --- a/berry/haco.be +++ b/berry/haco.be @@ -304,6 +304,7 @@ class Daemon var callback_type=CALLBACK_MAP[data.find('type', classname(tools.callbacks.Rule))] var topic=data['topic'] var trigger=data['trigger'] + var id=data['id'] var function @@ -315,7 +316,11 @@ class Daemon function=/value,data->{'value':value,'data':data} end - return callback_type(trigger,/value,data->tasmota.set_timer(0,/->self.publish_output(function,value,data,topic))) + return callback_type( + trigger, + /value,data->tasmota.set_timer(0,/->self.publish_output(function,value,data,topic)), + id + ) end diff --git a/haco/__init__.py b/haco/__init__.py index e2c345f..615f096 100644 --- a/haco/__init__.py +++ b/haco/__init__.py @@ -1,11 +1,13 @@ from haco import tuya from .button import Button from .callback import Response +from .climate import Climate from .number import Number from .pulldown import Select from .sensor import Sensor from .switch import Switch from .tasmota import Tasmota +from .text import Text, Password from .update import Update __all__ = [ @@ -15,7 +17,10 @@ __all__ = [ "Tasmota", "Number", "Switch", + "Text", + "Password", "Update", + "Climate", "Response", "tuya" ] diff --git a/haco/configs/development.py b/haco/configs/development.py index 4fd0197..2293e3f 100644 --- a/haco/configs/development.py +++ b/haco/configs/development.py @@ -1,9 +1,5 @@ -from haco.climate import Climate -from haco.number import Number -from haco.pulldown import Select -from haco.sensor import Sensor -from haco.tasmota import Tasmota -from haco.text import Text, Password +from haco import Number, Tasmota, Select, Sensor, Text, Password, Climate + number = Number( 'Dev Number Test Control', @@ -169,3 +165,8 @@ def ha(value: str) -> Tasmota[str, 'tasmota.cmd("var14 "+str(value))']: @password.callback('var14#state') def tasmota(value: str): return value + + +from haco.debugging import get_tasmota_updater + +update = get_tasmota_updater() diff --git a/haco/configs/proscenic_t21.py b/haco/configs/proscenic_t21.py index 14bab99..4d22ca5 100644 --- a/haco/configs/proscenic_t21.py +++ b/haco/configs/proscenic_t21.py @@ -1,6 +1,7 @@ import math from haco import Tasmota, Number, Sensor, Select, Switch, tuya +from haco.debugging import get_tasmota_updater from haco.tools import add_tuya_io OPTIONS = ['Default', 'Fries', 'Shrimp', 'Pizza', 'Chicken', 'Fish', 'Steak', 'Cake', 'Bacon', 'Preheat', 'Custom'] @@ -130,4 +131,6 @@ keep_warm_time = Number( add_tuya_io(keep_warm_time, int, 2, 105) +update = get_tasmota_updater() + DEVICE_CONFIG = {'run_config_post': f'def () return tasmota.cmd("TuyaSend0") end'} diff --git a/haco/debugging.py b/haco/debugging.py index 1fc78f4..8ebd201 100644 --- a/haco/debugging.py +++ b/haco/debugging.py @@ -1,8 +1,10 @@ +import random from typing import Any -from haco import trigger +from haco import trigger, Update, Response from haco.sensor import Sensor from haco.tasmota import Tasmota +from haco.tools import get_latest def get_memory_sensor(): @@ -13,3 +15,42 @@ def get_memory_sensor(): return value.get('heap_free', 'unknown') return memory_sensor + + +def get_tasmota_updater(): + DEFAULT_OTA_URL = 'https://ota.tasmota.com/tasmota32/release/tasmota32.bin' + + once_daily = trigger.Cron(f"0 {random.randint(0, 59)} {random.randint(0, 23)} * * *") + + update = Update('Update Tasmota') + + @update.callback() + def ha(value) -> Tasmota[str, 'tasmota.cmd("upgrade 1")']: + return value + + @update.callback(trigger=once_daily) + def latest_version_tasmota(value): + tag = get_latest('arendst', 'Tasmota') + + if not tag: + return Response(send=False) + + tag = tag.lstrip('v') + + return tag + + @update.callback(trigger=once_daily) + def tasmota(value: Tasmota[Any, 'tasmota.cmd("status 2")'], otaurl: Tasmota[Any, 'tasmota.cmd("OtaUrl")']): + + if otaurl['OtaUrl'] != DEFAULT_OTA_URL: + return Response(send=False) + + version = value.get('StatusFWR', {}).get('Version') or '' + version = version.removesuffix('(tasmota32)') + + if not version: + return Response(send=False) + + return version + + return update diff --git a/haco/schema.py b/haco/schema.py index e3089d0..04002a9 100644 --- a/haco/schema.py +++ b/haco/schema.py @@ -79,6 +79,15 @@ class Platform: self.callback = None + @property + def callback_id(self): + return ( + Path() / + self.capability.schema.control.NAME / + self.capability.schema.control.name_sanitized / + self.capability.name + ) + @property def callback_function_name(self): return f'{self.capability.alias}_{self.PLATFORM}' @@ -220,7 +229,8 @@ class HomeAssistant(Platform): 'topic': None, 'trigger': str(trigger), 'function': self.callback.function_tasmota, - 'type': 'MqttSubscription' + 'type': 'MqttSubscription', + 'id': str(self.callback_id) } return config @@ -290,7 +300,8 @@ class Tasmota(Platform): 'topic': str(self.get_topic_subscription()), 'trigger': self.callback.trigger, 'function': self.callback.function_tasmota, - 'type': self.callback.type_id + 'type': self.callback.type_id, + 'id': str(self.callback_id) } return config diff --git a/setup.py b/setup.py index 3a8167d..abed16a 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,8 @@ setup( }, install_requires=[ 'aiomqtt', - 'pyyaml' + 'pyyaml', + 'requests' ], extras_require={ 'tasmota': [