diff --git a/hass_mqtt_ac_sync.py b/hass_mqtt_ac_sync.py new file mode 100644 index 0000000..0bdd9ef --- /dev/null +++ b/hass_mqtt_ac_sync.py @@ -0,0 +1,203 @@ +import appdaemon.plugins.hass.hassapi as hass +import appdaemon.plugins.mqtt.mqttapi as mqtt +import appdaemon.adbase as base + + +class hass_mqtt_ac_sync_mitsubishi(hass.Hass,mqtt.Mqtt): + + def initialize(self): + self.entity_id = self.args["entity_id"] + self.entity_id_horizontal_vane = self.args["entity_id_horizontal_vane"] + self.entity_id_vertical_vane = self.args["entity_id_vertical_vane"] + self.entity = self.get_entity(self.entity_id) + self.mqtt_topic_mode = self.args["mqtt_topic_mode"] + self.mqtt_topic_set_mode = self.args["mqtt_topic_set_mode"] + self.mqtt_topic_mode_request = self.args["mqtt_topic_mode_request"] + self.mqtt_topic_temperature = self.args["mqtt_topic_temperature"] + self.mqtt_topic_set_temperature = self.args["mqtt_topic_set_temperature"] + self.mqtt_topic_temperature_request = self.args["mqtt_topic_temperature_request"] + self.mqtt_topic_room_temperature = self.args["mqtt_topic_room_temperature"] + self.mqtt_topic_room_temperature_request = self.args["mqtt_topic_room_temperature_request"] + self.mqtt_topic_horizontal_vane = self.args["mqtt_topic_horizontal_vane"] + self.mqtt_topic_set_horizontal_vane = self.args["mqtt_topic_set_horizontal_vane"] + self.mqtt_topic_horizontal_vane_request = self.args["mqtt_topic_horizontal_vane_request"] + self.mqtt_topic_vertical_vane = self.args["mqtt_topic_vertical_vane"] + self.mqtt_topic_set_vertical_vane = self.args["mqtt_topic_set_vertical_vane"] + self.mqtt_topic_vertical_vane_request = self.args["mqtt_topic_vertical_vane_request"] + self.mqtt_topic_fan_speed = self.args["mqtt_topic_fan_speed"] + self.mqtt_topic_set_fan_speed = self.args["mqtt_topic_set_fan_speed"] + self.mqtt_topic_fan_speed_request = self.args["mqtt_topic_fan_speed_request"] + + self.mqtt_subscribe(self.mqtt_topic_set_mode, namespace="mqtt") + self.mqtt_subscribe(self.mqtt_topic_mode_request, namespace="mqtt") + self.mqtt_subscribe(self.mqtt_topic_set_temperature, namespace="mqtt") + self.mqtt_subscribe(self.mqtt_topic_temperature_request, namespace="mqtt") + self.mqtt_subscribe(self.mqtt_topic_room_temperature_request, namespace="mqtt") + self.listen_event(self.handle_set_mode_payload, "MQTT_MESSAGE", topic=self.mqtt_topic_set_mode, namespace="mqtt") + self.listen_event(self.handle_mode_request_payload, "MQTT_MESSAGE", topic=self.mqtt_topic_mode_request, namespace="mqtt") + self.entity.listen_state(self.handle_mode_state_change) + self.listen_event(self.handle_set_temperature_payload, "MQTT_MESSAGE", topic=self.mqtt_topic_set_temperature, namespace="mqtt") + self.listen_event(self.handle_temperature_request_payload, "MQTT_MESSAGE", topic=self.mqtt_topic_temperature_request, namespace="mqtt") + self.entity.listen_state(self.handle_temperature_state_change, attribute="temperature") + self.listen_event(self.handle_room_temperature_request_payload, "MQTT_MESSAGE", topic=self.mqtt_topic_room_temperature_request, namespace="mqtt") + self.entity.listen_state(self.handle_room_temperature_state_change, attribute="current_temperature") + + + self.mqtt_subscribe(self.mqtt_topic_set_horizontal_vane, namespace="mqtt") + self.mqtt_subscribe(self.mqtt_topic_horizontal_vane_request, namespace="mqtt") + self.mqtt_subscribe(self.mqtt_topic_set_vertical_vane, namespace="mqtt") + self.mqtt_subscribe(self.mqtt_topic_vertical_vane_request, namespace="mqtt") + self.listen_event(self.handle_horizontal_vane_payload, "MQTT_MESSAGE", topic=self.mqtt_topic_set_horizontal_vane, namespace="mqtt") + self.listen_state(self.handle_horizontal_vane_change, self.entity_id_horizontal_vane) + self.listen_event(self.handle_vertical_vane_payload, "MQTT_MESSAGE", topic=self.mqtt_topic_set_vertical_vane, namespace="mqtt") + self.listen_state(self.handle_vertical_vane_change, self.entity_id_vertical_vane) + + self.horizontal_vane_map: dict = { + "SWING": "swing", + "←←": "0", + "←": "1", + "|": "2", + "→": "3", + "→→": "4", + "←→": "5" + } + + self.vertical_vane_map: dict = { + "SWING": "swing", + "↑↑": "4", + "↑": "3", + "—": "2", + "↓": "1", + "↓↓": "0", + } + + self.mqtt_subscribe(self.mqtt_topic_set_fan_speed, namespace="mqtt") + self.mqtt_subscribe(self.mqtt_topic_fan_speed_request, namespace="mqtt") + self.listen_event(self.handle_fan_speed_payload, "MQTT_MESSAGE", topic=self.mqtt_topic_set_fan_speed, namespace="mqtt") + self.listen_event(self.handle_fan_speed_request_payload, "MQTT_MESSAGE", topic=self.mqtt_topic_fan_speed_request, namespace="mqtt") + self.entity.listen_state(self.handle_fan_speed_state_change, attribute="fan_mode") + + self.fan_speed_map: dict = { + "auto": "auto", + "quiet": "0", + "low": "1", + "medium": "2", + "middle": "3", + "high": "4", + } + + + self.publish_mode_to_mqtt() + self.publish_temperature_to_mqtt() + self.publish_room_temperature_to_mqtt() + self.publish_horizontal_vane_to_mqtt() + self.publish_vertical_vane_to_mqtt() + self.publish_fan_speed_to_mqtt() + + def publish_mode_to_mqtt(self): + state = self.get_state(self.entity_id) + self.mqtt_publish(self.mqtt_topic_mode, str(state), namespace="mqtt") + + def publish_temperature_to_mqtt(self): + temperature = self.get_state(self.entity_id,attribute="temperature") + self.mqtt_publish(self.mqtt_topic_temperature, str(temperature), namespace="mqtt") + + def handle_set_mode_payload(self, event_name, data, cb_args): + state = data["payload"] + + # Set state alone does not trigger state change event, so we need to call it manually + if state == "cool" or state == "heat" or state == "dry" or state == "fan_only" or state == "off": + self.call_service("climate/set_hvac_mode", entity_id=self.entity_id, hvac_mode = state) + else: + self.entity.set_state(state = data["payload"]) + + def handle_mode_request_payload(self, event_name, data, cb_args): + self.publish_mode_to_mqtt() + + def handle_mode_state_change(self, entity, attribute, old, new, cb_args): + self.publish_mode_to_mqtt() + + def handle_set_temperature_payload(self, event_name, data, cb_args): + temperature = data["payload"] + self.call_service("climate/set_temperature", entity_id=self.entity_id, temperature = temperature) + + def handle_temperature_request_payload(self, event_name, data, cb_args): + self.publish_temperature_to_mqtt() + + def handle_temperature_state_change(self, entity, attribute, old, new, cb_args): + self.publish_temperature_to_mqtt() + + def handle_room_temperature_request_payload(self, event_name, data, cb_args): + self.publish_room_temperature_to_mqtt() + + def handle_room_temperature_state_change(self, entity, attribute, old, new, cb_args): + self.publish_room_temperature_to_mqtt() + + def publish_room_temperature_to_mqtt(self): + temperature = self.get_state(self.entity_id,attribute="current_temperature") + self.mqtt_publish(self.mqtt_topic_room_temperature, str(temperature), namespace="mqtt") + + def handle_horizontal_vane_payload(self, event_name, data, cb_args): + vane = data["payload"] + # Reverse Map the vane to the correct value + for key, value in self.horizontal_vane_map.items(): + if value == vane: + vane = key + break + self.log("Setting horizontal vane to: {}".format(vane)) + self.call_service("select/select_option", entity_id=self.entity_id_horizontal_vane, option = vane) + + def handle_horizontal_vane_change(self, entity, attribute, old, new, cb_args): + self.publish_horizontal_vane_to_mqtt() + + def publish_horizontal_vane_to_mqtt(self): + vane = self.get_state(self.entity_id_horizontal_vane) + # Map the vane to the correct value + if vane in self.horizontal_vane_map: + vane = self.horizontal_vane_map[vane] + self.mqtt_publish(self.mqtt_topic_horizontal_vane, str(vane), namespace="mqtt") + + def handle_vertical_vane_payload(self, event_name, data, cb_args): + vane = data["payload"] + # Reverse Map the vane to the correct value + for key, value in self.vertical_vane_map.items(): + if value == vane: + vane = key + break + self.log("Setting vertical vane to: {}".format(vane)) + self.call_service("select/select_option", entity_id=self.entity_id_vertical_vane, option = vane) + + def handle_vertical_vane_change(self, entity, attribute, old, new, cb_args): + self.publish_vertical_vane_to_mqtt() + + def publish_vertical_vane_to_mqtt(self): + vane = self.get_state(self.entity_id_vertical_vane) + # Map the vane to the correct value + if vane in self.vertical_vane_map: + vane = self.vertical_vane_map[vane] + self.mqtt_publish(self.mqtt_topic_vertical_vane, str(vane), namespace="mqtt") + + def handle_fan_speed_payload(self, event_name, data, cb_args): + fan_speed = data["payload"] + # Reverse Map the fan speed to the correct value + for key, value in self.fan_speed_map.items(): + if value == fan_speed: + fan_speed = key + break + self.log("Setting fan speed to: {}".format(fan_speed)) + self.call_service("climate/set_fan_mode", entity_id=self.entity_id, fan_mode = fan_speed) + + def handle_fan_speed_state_change(self, entity, attribute, old, new, cb_args): + self.log("Fan speed change detected: {} -> {}".format(old, new)) + self.publish_fan_speed_to_mqtt() + + def publish_fan_speed_to_mqtt(self): + fan_speed = self.get_state(self.entity_id,attribute="fan_mode") + # Map the fan speed to the correct value + if fan_speed in self.fan_speed_map: + fan_speed = self.fan_speed_map[fan_speed] + self.log("Publishing fan speed to mqtt: {}".format(fan_speed)) + self.mqtt_publish(self.mqtt_topic_fan_speed, str(fan_speed), namespace="mqtt") + + def handle_fan_speed_request_payload(self, event_name, data, cb_args): + self.publish_fan_speed_to_mqtt() \ No newline at end of file diff --git a/hass_mqtt_light_sync.py b/hass_mqtt_light_sync.py new file mode 100644 index 0000000..2680a1c --- /dev/null +++ b/hass_mqtt_light_sync.py @@ -0,0 +1,42 @@ +import appdaemon.plugins.hass.hassapi as hass +import appdaemon.plugins.mqtt.mqttapi as mqtt +import appdaemon.adbase as base + + +class hass_mqtt_state_sync(hass.Hass,mqtt.Mqtt): + + def initialize(self): + self.entity_id = self.args["entity_id"] + self.entity = self.get_entity(self.entity_id) + self.mqtt_topic_state = self.args["mqtt_topic_state"] + self.mqtt_topic_set_state = self.args["mqtt_topic_set_state"] + self.mqtt_topic_request = self.args["mqtt_topic_request"] + + self.mqtt_subscribe(self.mqtt_topic_set_state, namespace="mqtt") + self.mqtt_subscribe(self.mqtt_topic_request, namespace="mqtt") + self.listen_event(self.handle_set_state_payload, "MQTT_MESSAGE", topic=self.mqtt_topic_set_state, namespace="mqtt") + self.listen_event(self.handle_request_payload, "MQTT_MESSAGE", topic=self.mqtt_topic_request, namespace="mqtt") + self.entity.listen_state(self.handle_hass_state_change) + self.publish_state_to_mqtt() + + def publish_state_to_mqtt(self): + state = self.get_state(self.entity_id) + self.mqtt_publish(self.mqtt_topic_state, str(state), namespace="mqtt") + + def handle_set_state_payload(self, event_name, data, cb_args): + state = data["payload"] + + # Set state alone does not trigger state change event, so we need to call it manually + if state == "on": + self.call_service("homeassistant/turn_on", entity_id=self.entity_id) + elif state == "off": + self.call_service("homeassistant/turn_off", entity_id=self.entity_id) + else: + self.entity.set_state(state = data["payload"]) + + def handle_request_payload(self, event_name, data, cb_args): + self.publish_state_to_mqtt() + + def handle_hass_state_change(self, entity, attribute, old, new, cb_args): + self.log("State change detected: {} -> {}".format(old, new)) + self.publish_state_to_mqtt() \ No newline at end of file diff --git a/hass_mqtt_state_sync.py b/hass_mqtt_state_sync.py new file mode 100644 index 0000000..2680a1c --- /dev/null +++ b/hass_mqtt_state_sync.py @@ -0,0 +1,42 @@ +import appdaemon.plugins.hass.hassapi as hass +import appdaemon.plugins.mqtt.mqttapi as mqtt +import appdaemon.adbase as base + + +class hass_mqtt_state_sync(hass.Hass,mqtt.Mqtt): + + def initialize(self): + self.entity_id = self.args["entity_id"] + self.entity = self.get_entity(self.entity_id) + self.mqtt_topic_state = self.args["mqtt_topic_state"] + self.mqtt_topic_set_state = self.args["mqtt_topic_set_state"] + self.mqtt_topic_request = self.args["mqtt_topic_request"] + + self.mqtt_subscribe(self.mqtt_topic_set_state, namespace="mqtt") + self.mqtt_subscribe(self.mqtt_topic_request, namespace="mqtt") + self.listen_event(self.handle_set_state_payload, "MQTT_MESSAGE", topic=self.mqtt_topic_set_state, namespace="mqtt") + self.listen_event(self.handle_request_payload, "MQTT_MESSAGE", topic=self.mqtt_topic_request, namespace="mqtt") + self.entity.listen_state(self.handle_hass_state_change) + self.publish_state_to_mqtt() + + def publish_state_to_mqtt(self): + state = self.get_state(self.entity_id) + self.mqtt_publish(self.mqtt_topic_state, str(state), namespace="mqtt") + + def handle_set_state_payload(self, event_name, data, cb_args): + state = data["payload"] + + # Set state alone does not trigger state change event, so we need to call it manually + if state == "on": + self.call_service("homeassistant/turn_on", entity_id=self.entity_id) + elif state == "off": + self.call_service("homeassistant/turn_off", entity_id=self.entity_id) + else: + self.entity.set_state(state = data["payload"]) + + def handle_request_payload(self, event_name, data, cb_args): + self.publish_state_to_mqtt() + + def handle_hass_state_change(self, entity, attribute, old, new, cb_args): + self.log("State change detected: {} -> {}".format(old, new)) + self.publish_state_to_mqtt() \ No newline at end of file