Last active
May 2, 2024 18:37
-
-
Save sam2332/e76ec0c6d7f17808d8a4d5de5f2dd301 to your computer and use it in GitHub Desktop.
home assistant pyscript that adds a custom device and updates the sensor in the file every 30 seconds
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import json | |
import logging | |
class MQTTDevice: | |
def __init__(self, name): | |
name = self.sanitize(name,lower=False) | |
self.name = name | |
self.sensors = {} | |
self.sensor_topic_root = f"homeassistant/sensor/{self.name}" | |
self.button_topic_root = f"homeassistant/button/{self.name}" | |
def sanitize(self, title,lower = True): | |
return title.replace(' ','_').replace('.','').replace(',','').replace('(','').replace(')','').replace('-','_').replace('!','').replace('?','').replace(':','').replace(';','').replace('\'','').replace('"','').replace('/','_').replace('\\','_').replace('&','and').replace('@','at').replace('#','').replace('$','').replace('%','').replace('^','').replace('*','').replace('+','').replace('=','').replace('~','').replace('`','').replace('<','').replace('>','').replace('|','').replace('[','').replace(']','').replace('{','').replace('}','').replace('`','') | |
def register_sensor(self, sensor, sensor_type="number", unit_of_measurement=None,value=None): | |
sensor = self.sanitize(sensor,lower=False) | |
# Save the sensor configuration in the device's sensor dictionary | |
self.sensors[sensor] = { | |
'value': None, | |
'type': sensor_type, | |
'unit': unit_of_measurement | |
} | |
# Define the MQTT topic for configuration | |
config_topic = f"{self.sensor_topic_root}/{sensor}/config" | |
config_payload = { | |
"name": sensor, | |
"state_topic": f"{self.sensor_topic_root}/{sensor}/state", | |
"unique_id": f"{self.name.lower()}_{sensor.lower()}", | |
"device_class": "text" if sensor_type == "text" else None, | |
"unit_of_measurement": unit_of_measurement, | |
"device": { | |
"identifiers": [self.name.lower()], | |
"name": self.name, | |
"model": "PyScript Device", | |
"manufacturer": "PyScript" | |
} | |
} | |
# Publish the configuration message to MQTT | |
mqtt.publish(topic=config_topic, payload=json.dumps(config_payload)) | |
if value is not None: | |
self.set_sensor_value(sensor, value) | |
def set_sensor_value(self, sensor, value): | |
sensor = self.sanitize(sensor) | |
if self.sensors[sensor]['value'] != value: | |
self.sensors[sensor]['value'] = value | |
self.publish_state(sensor, value) | |
def publish_state(self, sensor, value): | |
state_topic = f"{self.sensor_topic_root}/{sensor}/state" | |
mqtt.publish(topic=state_topic, payload=str(value)) | |
def update_sensor(self, sensor, update_function): | |
new_value = update_function() | |
self.set_sensor_value(sensor, new_value) | |
def _button(self,name,icon): | |
name = self.sanitize(name,lower=False) | |
button_config_topic = f"{self.button_topic_root}/{name}/config" | |
button_payload = { | |
"command_topic": f"{self.button_topic_root}/{name}/set", | |
"action_topic": f"{self.button_topic_root}/{name}/action", | |
"unique_id": f"{self.name.lower()}_{name.lower()}", | |
"device": { | |
"identifiers": [self.name.lower()], | |
"manufacturer": "PyScript", | |
"model": "PyScript Device", | |
"name": self.name, | |
}, | |
"name": name, | |
"icon": icon, | |
} | |
mqtt.publish(topic=button_config_topic, payload=json.dumps(button_payload)) | |
#mqtt.subscribe(f"{self.button_topic_root}/{name}/set",action) | |
logging.error("%s",f"Button {name} registered") | |
def create_button(self,name,icon): | |
self._button(name,icon) | |
return f"{self.button_topic_root}/{self.sanitize(name,lower=False)}/set" | |
import random | |
def update_test_value(): | |
return random.randint(0, 100) | |
# Example of using the class with registration of sensors | |
device = MQTTDevice("Device Test") | |
device.register_sensor("Test Value", "number", "test_unit") | |
button_mqtt_path = device.create_button("Test Button","mdi:bomb") | |
logging.error("%s",f"Button mqtt path: {button_mqtt_path}") | |
@mqtt_trigger(button_mqtt_path) | |
def action(topic,payload): | |
logging.error("%s",f"Button action: {topic} {payload}") | |
device.update_sensor("Test Value", update_test_value) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment