Skip to content

Instantly share code, notes, and snippets.

@sam2332
Last active May 2, 2024 18:37
Show Gist options
  • Save sam2332/e76ec0c6d7f17808d8a4d5de5f2dd301 to your computer and use it in GitHub Desktop.
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
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