diff --git a/README.md b/README.md index 75a6898..d256312 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,21 @@ python_script: data: id: "{{ trigger.payload_json.src }}" device_config: "{{ trigger.payload_json.result }}" + +- id: shellies_status_gen2 + alias: "Shellies Status Gen2" + trigger: + - platform: time_pattern + minutes: "/15" + action: + - service: mqtt.publish + data: + topic: shellyplus1pm-a8032ab22864/rpc + payload: "{{ {'id': 1, 'src':'shellypro4pm-aabbccddeeff/status', 'method':'Shelly.GetStatus'} | to_json }}" # shellypro4pm-aabbccddeeff is a device ID + - service: mqtt.publish + data: + topic: shellyplusi4-30839809e6ac/rpc + payload: "{{ {'id': 1, 'src':'shellyplus1pm-112233445566/status', 'method':'Shelly.GetStatus'} | to_json }}" # shellyplus1pm-112233445566 is a device ID ``` [releases]: https://github.com/bieniu/ha-shellies-discovery-gen2/releases diff --git a/info.md b/info.md index 1491fd9..5ff3cc2 100644 --- a/info.md +++ b/info.md @@ -101,6 +101,21 @@ python_script: data: id: "{{ trigger.payload_json.src }}" device_config: "{{ trigger.payload_json.result }}" + +- id: shellies_status_gen2 + alias: "Shellies Status Gen2" + trigger: + - platform: time_pattern + minutes: "/15" + action: + - service: mqtt.publish + data: + topic: shellyplus1pm-a8032ab22864/rpc + payload: "{{ {'id': 1, 'src':'shellypro4pm-aabbccddeeff/status', 'method':'Shelly.GetStatus'} | to_json }}" # shellypro4pm-aabbccddeeff is a device ID + - service: mqtt.publish + data: + topic: shellyplusi4-30839809e6ac/rpc + payload: "{{ {'id': 1, 'src':'shellyplus1pm-112233445566/status', 'method':'Shelly.GetStatus'} | to_json }}" # shellyplus1pm-112233445566 is a device ID ``` [forum]: https://community.home-assistant.io/t/shellies-discovery-gen2-script/384479 diff --git a/python_scripts/shellies_discovery_gen2.py b/python_scripts/shellies_discovery_gen2.py index 98990b8..2e2c026 100644 --- a/python_scripts/shellies_discovery_gen2.py +++ b/python_scripts/shellies_discovery_gen2.py @@ -1,5 +1,6 @@ """This script adds MQTT discovery support for Shellies Gen2 devices.""" +ATTR_BINARY_SENSORS = "binary_sensors" ATTR_BUTTON = "button" ATTR_BUTTONS = "buttons" ATTR_FW_ID = "fw_id" @@ -26,6 +27,7 @@ DEFAULT_DISC_PREFIX = "homeassistant" +DEVICE_CLASS_CONNECTIVITY = "connectivity" DEVICE_CLASS_CURRENT = "current" DEVICE_CLASS_ENERGY = "energy" DEVICE_CLASS_POWER = "power" @@ -34,6 +36,7 @@ DEVICE_CLASS_RESTART = "restart" DEVICE_CLASS_SIGNAL_STRENGTH = "signal_strength" DEVICE_CLASS_TEMPERATURE = "temperature" +DEVICE_CLASS_TIMESTAMP = "timestamp" DEVICE_CLASS_UPDATE = "update" DEVICE_CLASS_VOLTAGE = "voltage" @@ -51,6 +54,7 @@ KEY_COMMAND_TOPIC = "cmd_t" KEY_CONFIGURATION_URL = "cu" KEY_CONNECTIONS = "cns" +KEY_DEFAULT_TOPIC = "~" KEY_DEVICE = "dev" KEY_DEVICE_CLASS = "dev_cla" KEY_ENABLED_BY_DEFAULT = "en" @@ -91,14 +95,17 @@ MODEL_PRO_2PM = "shellypro2pm" MODEL_PRO_4PM = "shellypro4pm" +SENSOR_CLOUD = "cloud" SENSOR_CURRENT = "current" SENSOR_ENERGY = "energy" SENSOR_INPUT = "input" +SENSOR_LAST_RESTART = "last_restart" SENSOR_OVERPOWER = "overpower" SENSOR_OVERTEMP = "overtemp" SENSOR_OVERVOLTAGE = "overvoltage" SENSOR_POWER = "power" SENSOR_POWER_FACTOR = "power_factor" +SENSOR_SSID = "ssid" SENSOR_TEMPERATURE = "temperature" SENSOR_VOLTAGE = "voltage" SENSOR_WIFI_SIGNAL = "wifi_signal" @@ -111,6 +118,7 @@ TOPIC_STATUS_RPC = "~status/rpc" TOPIC_SWITCH_RELAY = "~status/switch:{relay}" +TPL_CLOUD = "{%if value_json.result.cloud.connected%}ON{%else%}OFF{%endif%}" TPL_CURRENT = "{{value_json.current|round(1)}}" TPL_ENERGY = "{{value_json.aenergy.total|round(2)}}" TPL_INPUT = "{%if value_json.state%}ON{%else%}OFF{%endif%}" @@ -126,8 +134,10 @@ "{%if ^overvoltage^ in value_json.get(^errors^,[])%}ON{%else%}OFF{%endif%}" ) TPL_TEMPERATURE = "{{value_json.temperature.tC|round(1)}}" +TPL_UPTIME = "{{(as_timestamp(now())-value_json.result.sys.uptime)|timestamp_local}}" TPL_VOLTAGE = "{{value_json.voltage|round(1)}}" TPL_WIFI_SIGNAL = "{{value_json.result.wifi.rssi}}" +TPL_WIFI_SSID = "{{value_json.result.wifi.ssid}}" TRIGGER_BUTTON_DOUBLE_PRESS = "button_double_press" TRIGGER_BUTTON_LONG_PRESS = "button_long_press" @@ -165,6 +175,14 @@ KEY_NAME: "Update Firmware", KEY_PAYLOAD_PRESS: "{{^id^:1,^src^:^{device_id}^,^method^:^Shelly.Update^,^params^:{{^stage^:^stable^}}}}", } +DESCRIPTION_SENSOR_CLOUD = { + KEY_DEVICE_CLASS: DEVICE_CLASS_CONNECTIVITY, + KEY_ENABLED_BY_DEFAULT: False, + KEY_ENTITY_CATEGORY: ENTITY_CATEGORY_DIAGNOSTIC, + KEY_NAME: "Cloud", + KEY_STATE_TOPIC: TOPIC_STATUS_RPC, + KEY_VALUE_TEMPLATE: TPL_CLOUD, +} DESCRIPTION_SENSOR_CURRENT = { KEY_DEVICE_CLASS: DEVICE_CLASS_CURRENT, KEY_ENABLED_BY_DEFAULT: False, @@ -188,6 +206,14 @@ KEY_STATE_TOPIC: TOPIC_INPUT, KEY_VALUE_TEMPLATE: TPL_INPUT, } +DESCRIPTION_SENSOR_LAST_RESTART = { + KEY_DEVICE_CLASS: DEVICE_CLASS_TIMESTAMP, + KEY_ENABLED_BY_DEFAULT: False, + KEY_ENTITY_CATEGORY: ENTITY_CATEGORY_DIAGNOSTIC, + KEY_NAME: "Last Restart", + KEY_STATE_TOPIC: TOPIC_STATUS_RPC, + KEY_VALUE_TEMPLATE: TPL_UPTIME, +} DESCRIPTION_SENSOR_OVERPOWER = { KEY_DEVICE_CLASS: DEVICE_CLASS_PROBLEM, KEY_ENABLED_BY_DEFAULT: False, @@ -230,6 +256,14 @@ KEY_UNIT: UNIT_PERCENT, KEY_VALUE_TEMPLATE: TPL_POWER_FACTOR, } +DESCRIPTION_SENSOR_SSID = { + KEY_ENABLED_BY_DEFAULT: False, + KEY_ENTITY_CATEGORY: ENTITY_CATEGORY_DIAGNOSTIC, + KEY_ICON: "mdi:wifi-settings", + KEY_NAME: "SSID", + KEY_STATE_TOPIC: TOPIC_STATUS_RPC, + KEY_VALUE_TEMPLATE: TPL_WIFI_SSID, +} DESCRIPTION_SENSOR_TEMPERATURE = { KEY_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, KEY_ENABLED_BY_DEFAULT: False, @@ -250,7 +284,7 @@ } DESCRIPTION_SENSOR_WIFI_SIGNAL = { KEY_DEVICE_CLASS: DEVICE_CLASS_SIGNAL_STRENGTH, - KEY_ENABLED_BY_DEFAULT: True, + KEY_ENABLED_BY_DEFAULT: False, KEY_ENTITY_CATEGORY: ENTITY_CATEGORY_DIAGNOSTIC, KEY_NAME: "WiFi Signal", KEY_STATE_CLASS: STATE_CLASS_MEASUREMENT, @@ -271,10 +305,15 @@ ATTR_INPUT_EVENTS: [EVENT_SINGLE_PUSH, EVENT_DOUBLE_PUSH, EVENT_LONG_PUSH], ATTR_RELAYS: 1, ATTR_RELAY_BINARY_SENSORS: {SENSOR_OVERTEMP: DESCRIPTION_SENSOR_OVERTEMP}, - ATTR_SENSORS: {SENSOR_WIFI_SIGNAL: DESCRIPTION_SENSOR_WIFI_SIGNAL}, + ATTR_SENSORS: { + SENSOR_LAST_RESTART: DESCRIPTION_SENSOR_LAST_RESTART, + SENSOR_SSID: DESCRIPTION_SENSOR_SSID, + SENSOR_WIFI_SIGNAL: DESCRIPTION_SENSOR_WIFI_SIGNAL, + }, }, MODEL_PLUS_1PM: { ATTR_NAME: "Shelly Plus 1PM", + ATTR_BINARY_SENSORS: {SENSOR_CLOUD: DESCRIPTION_SENSOR_CLOUD}, ATTR_BUTTONS: { BUTTON_RESTART: DESCRIPTION_BUTTON_RESTART, BUTTON_UPDATE_FIRMWARE: DESCRIPTION_UPDATE_FIRMWARE, @@ -295,7 +334,11 @@ SENSOR_TEMPERATURE: DESCRIPTION_SENSOR_TEMPERATURE, SENSOR_VOLTAGE: DESCRIPTION_SENSOR_VOLTAGE, }, - ATTR_SENSORS: {SENSOR_WIFI_SIGNAL: DESCRIPTION_SENSOR_WIFI_SIGNAL}, + ATTR_SENSORS: { + SENSOR_LAST_RESTART: DESCRIPTION_SENSOR_LAST_RESTART, + SENSOR_SSID: DESCRIPTION_SENSOR_SSID, + SENSOR_WIFI_SIGNAL: DESCRIPTION_SENSOR_WIFI_SIGNAL, + }, }, MODEL_PLUS_I4: { ATTR_NAME: "Shelly Plus i4", @@ -306,7 +349,11 @@ ATTR_INPUTS: 4, ATTR_INPUT_BINARY_SENSORS: {SENSOR_INPUT: DESCRIPTION_SENSOR_INPUT}, ATTR_INPUT_EVENTS: [EVENT_SINGLE_PUSH, EVENT_DOUBLE_PUSH, EVENT_LONG_PUSH], - ATTR_SENSORS: {SENSOR_WIFI_SIGNAL: DESCRIPTION_SENSOR_WIFI_SIGNAL}, + ATTR_SENSORS: { + SENSOR_LAST_RESTART: DESCRIPTION_SENSOR_LAST_RESTART, + SENSOR_SSID: DESCRIPTION_SENSOR_SSID, + SENSOR_WIFI_SIGNAL: DESCRIPTION_SENSOR_WIFI_SIGNAL, + }, }, MODEL_PRO_1: { ATTR_NAME: "Shelly Pro 1", @@ -319,7 +366,11 @@ ATTR_INPUT_EVENTS: [EVENT_SINGLE_PUSH, EVENT_DOUBLE_PUSH, EVENT_LONG_PUSH], ATTR_RELAYS: 1, ATTR_RELAY_BINARY_SENSORS: {SENSOR_OVERTEMP: DESCRIPTION_SENSOR_OVERTEMP}, - ATTR_SENSORS: {SENSOR_WIFI_SIGNAL: DESCRIPTION_SENSOR_WIFI_SIGNAL}, + ATTR_SENSORS: { + SENSOR_LAST_RESTART: DESCRIPTION_SENSOR_LAST_RESTART, + SENSOR_SSID: DESCRIPTION_SENSOR_SSID, + SENSOR_WIFI_SIGNAL: DESCRIPTION_SENSOR_WIFI_SIGNAL, + }, }, MODEL_PRO_1PM: { ATTR_NAME: "Shelly Pro 1PM", @@ -343,7 +394,11 @@ SENSOR_TEMPERATURE: DESCRIPTION_SENSOR_TEMPERATURE, SENSOR_VOLTAGE: DESCRIPTION_SENSOR_VOLTAGE, }, - ATTR_SENSORS: {SENSOR_WIFI_SIGNAL: DESCRIPTION_SENSOR_WIFI_SIGNAL}, + ATTR_SENSORS: { + SENSOR_LAST_RESTART: DESCRIPTION_SENSOR_LAST_RESTART, + SENSOR_SSID: DESCRIPTION_SENSOR_SSID, + SENSOR_WIFI_SIGNAL: DESCRIPTION_SENSOR_WIFI_SIGNAL, + }, }, MODEL_PRO_2: { ATTR_NAME: "Shelly Pro 2", @@ -356,7 +411,11 @@ ATTR_INPUT_EVENTS: [EVENT_SINGLE_PUSH, EVENT_DOUBLE_PUSH, EVENT_LONG_PUSH], ATTR_RELAYS: 2, ATTR_RELAY_BINARY_SENSORS: {SENSOR_OVERTEMP: DESCRIPTION_SENSOR_OVERTEMP}, - ATTR_SENSORS: {SENSOR_WIFI_SIGNAL: DESCRIPTION_SENSOR_WIFI_SIGNAL}, + ATTR_SENSORS: { + SENSOR_LAST_RESTART: DESCRIPTION_SENSOR_LAST_RESTART, + SENSOR_SSID: DESCRIPTION_SENSOR_SSID, + SENSOR_WIFI_SIGNAL: DESCRIPTION_SENSOR_WIFI_SIGNAL, + }, }, MODEL_PRO_2PM: { ATTR_NAME: "Shelly Pro 2PM", @@ -380,7 +439,11 @@ SENSOR_TEMPERATURE: DESCRIPTION_SENSOR_TEMPERATURE, SENSOR_VOLTAGE: DESCRIPTION_SENSOR_VOLTAGE, }, - ATTR_SENSORS: {SENSOR_WIFI_SIGNAL: DESCRIPTION_SENSOR_WIFI_SIGNAL}, + ATTR_SENSORS: { + SENSOR_LAST_RESTART: DESCRIPTION_SENSOR_LAST_RESTART, + SENSOR_SSID: DESCRIPTION_SENSOR_SSID, + SENSOR_WIFI_SIGNAL: DESCRIPTION_SENSOR_WIFI_SIGNAL, + }, }, MODEL_PRO_4PM: { ATTR_NAME: "Shelly Pro 4PM", @@ -405,7 +468,11 @@ SENSOR_TEMPERATURE: DESCRIPTION_SENSOR_TEMPERATURE, SENSOR_VOLTAGE: DESCRIPTION_SENSOR_VOLTAGE, }, - ATTR_SENSORS: {SENSOR_WIFI_SIGNAL: DESCRIPTION_SENSOR_WIFI_SIGNAL}, + ATTR_SENSORS: { + SENSOR_LAST_RESTART: DESCRIPTION_SENSOR_LAST_RESTART, + SENSOR_SSID: DESCRIPTION_SENSOR_SSID, + SENSOR_WIFI_SIGNAL: DESCRIPTION_SENSOR_WIFI_SIGNAL, + }, }, } @@ -461,7 +528,7 @@ def get_switch(relay_id, relay_type): KEY_UNIQUE_ID: f"{device_id}-{relay_id}".lower(), KEY_QOS: qos, KEY_DEVICE: device_info, - "~": default_topic, + KEY_DEFAULT_TOPIC: default_topic, } return topic, payload @@ -492,7 +559,7 @@ def get_light(relay_id, relay_type): KEY_UNIQUE_ID: f"{device_id}-{relay_id}".lower(), KEY_QOS: qos, KEY_DEVICE: device_info, - "~": default_topic, + KEY_DEFAULT_TOPIC: default_topic, } return topic, payload @@ -517,7 +584,6 @@ def get_sensor(sensor, description, relay_id=None): payload = { KEY_NAME: sensor_name, KEY_VALUE_TEMPLATE: description[KEY_VALUE_TEMPLATE], - KEY_UNIT: description[KEY_UNIT], KEY_ENABLED_BY_DEFAULT: str(description[KEY_ENABLED_BY_DEFAULT]).lower(), # KEY_AVAILABILITY_TOPIC: f"~online", # KEY_PAYLOAD_AVAILABLE: VALUE_TRUE, @@ -525,13 +591,18 @@ def get_sensor(sensor, description, relay_id=None): KEY_UNIQUE_ID: unique_id, KEY_QOS: qos, KEY_DEVICE: device_info, - "~": default_topic, + KEY_DEFAULT_TOPIC: default_topic, } if relay_id is not None: payload[KEY_STATE_TOPIC] = description[KEY_STATE_TOPIC].format(relay=relay_id) else: payload[KEY_STATE_TOPIC] = description[KEY_STATE_TOPIC] + + if description.get(KEY_UNIT): + payload[KEY_UNIT] = description[KEY_UNIT] + if description.get(KEY_ICON): + payload[KEY_ICON] = description[KEY_ICON] if description.get(KEY_DEVICE_CLASS): payload[KEY_DEVICE_CLASS] = description[KEY_DEVICE_CLASS] if description.get(KEY_ENTITY_CATEGORY): @@ -551,7 +622,7 @@ def get_binary_sensor( device_config[f"input:{entity_id}"][ATTR_NAME] or f"{device_name} Input {entity_id}" ) - else: + elif entity_id is not None: name = ( device_config[f"switch:{entity_id}"][ATTR_NAME] or f"{device_name} Relay {entity_id}" @@ -577,7 +648,6 @@ def get_binary_sensor( payload = { KEY_NAME: sensor_name, - KEY_STATE_TOPIC: description[KEY_STATE_TOPIC].format(relay=entity_id), KEY_VALUE_TEMPLATE: description[KEY_VALUE_TEMPLATE], KEY_ENABLED_BY_DEFAULT: str(description[KEY_ENABLED_BY_DEFAULT]).lower(), # KEY_AVAILABILITY_TOPIC: f"~online", @@ -586,9 +656,14 @@ def get_binary_sensor( KEY_UNIQUE_ID: unique_id, KEY_QOS: qos, KEY_DEVICE: device_info, - "~": default_topic, + KEY_DEFAULT_TOPIC: default_topic, } + if entity_id is not None: + payload[KEY_STATE_TOPIC] = description[KEY_STATE_TOPIC].format(relay=entity_id) + else: + payload[KEY_STATE_TOPIC] = description[KEY_STATE_TOPIC] + if description.get(KEY_DEVICE_CLASS): payload[KEY_DEVICE_CLASS] = description[KEY_DEVICE_CLASS] if description.get(KEY_ENTITY_CATEGORY): @@ -638,7 +713,7 @@ def get_button(button, description): # KEY_PAYLOAD_AVAILABLE: VALUE_TRUE, # KEY_PAYLOAD_NOT_AVAILABLE: VALUE_FALSE, KEY_DEVICE: device_info, - "~": default_topic, + KEY_DEFAULT_TOPIC: default_topic, } if description.get(KEY_DEVICE_CLASS): @@ -702,6 +777,10 @@ def configure_device(): topic, payload = get_sensor(sensor, description) config[topic] = payload + for binary_sensor, description in binary_sensors.items(): + topic, payload = get_binary_sensor(binary_sensor, description) + config[topic] = payload + return config @@ -753,6 +832,7 @@ def configure_device(): buttons = SUPPORTED_MODELS[model].get(ATTR_BUTTONS, {}) sensors = SUPPORTED_MODELS[model].get(ATTR_SENSORS, {}) +binary_sensors = SUPPORTED_MODELS[model].get(ATTR_BINARY_SENSORS, {}) config_data = configure_device()