diff --git a/alarm_control_panel.py b/alarm_control_panel.py index 3a90313..16d4d88 100644 --- a/alarm_control_panel.py +++ b/alarm_control_panel.py @@ -47,22 +47,28 @@ async def update(self): print("Alarm created / updated : ", self.name, self.id, self.current_state) - async def put_alarm_state(tydom_client, alarm_id, asked_state=None): + + + async def put_alarm_state(tydom_client, alarm_id, home_zone, night_zone, asked_state=None): print(tydom_client, alarm_id, asked_state) - state = None - zone = None + value = None + zone_id = None + if asked_state == 'ARM_AWAY': - state = 'ON' - zone = None - elif asked_state == 'ARM_HOME' or asked_state == 'ARM_NIGHT': #TODO : Separate both and let user specify with zone is what - state = "ON" - zone = "zone1" + value = 'ON' + zone_id = None + elif asked_state == 'ARM_HOME': #TODO : Separate both and let user specify with zone is what + value = "ON" + zone_id = home_zone + elif asked_state == 'ARM_NIGHT': #TODO : Separate both and let user specify with zone is what + value = "ON" + zone_id = night_zone elif asked_state == 'DISARM': - state = 'OFF' - zone = None + value = 'OFF' + zone_id = None - await tydom_client.put_alarm_cdata(alarm_id=alarm_id, asked_state=state, zone=zone) + await tydom_client.put_alarm_cdata(alarm_id=alarm_id, value=value, zone_id=zone_id) # update_pub = '(self.state_topic, self.current_state, qos=0, retain=True)' # return(update_pub) diff --git a/cover.py b/cover.py index 3b07a06..b0b881b 100644 --- a/cover.py +++ b/cover.py @@ -68,13 +68,14 @@ async def update(self): if (self.mqtt != None): self.mqtt.mqtt_client.publish(self.position_topic, self.current_position, qos=0, retain=True) self.mqtt.mqtt_client.publish('homeassistant/sensor/tydom/last_update', str(datetime.fromtimestamp(time.time())), qos=1, retain=True) + self.attributes_topic = cover_attributes_topic.format(id=self.id, attributes=self.attributes) + self.mqtt.mqtt_client.publish(self.attributes_topic, self.attributes, qos=0) + print("Cover created / updated : ", self.name, self.id, self.current_position) # update_pub = '(self.position_topic, self.current_position, qos=0, retain=True)' # return(update_pub) - # self.attributes_topic = cover_attributes_topic.format(id=self.id, attributes=self.attributes) - # hassio.publish(self.attributes_topic, self.attributes, qos=0) - + async def put_position(tydom_client, cover_id, position): print(cover_id, 'position', position) if not tydom_client.connection.open: diff --git a/install.sh b/install.sh index 2b2ec33..d075b95 100644 --- a/install.sh +++ b/install.sh @@ -6,6 +6,9 @@ docker run \ -e TYDOM_MAC='001A25xxxxxx' \ -e TYDOM_IP='192.168.1.xx' \ -e TYDOM_PASSWORD='TYDOM_PASSWORD' \ + -e TYDOM_ALARM_PIN = None \ + -e TYDOM_ALARM_HOME_ZONE = 1 \ + -e TYDOM_ALARM_NIGHT_ZONE = 2 \ -e MQTT_USER='MQTT_USER' \ -e MQTT_PASSWORD='MQTT_PASSWORD' \ -e MQTT_PORT='MQTT_PORT' \ diff --git a/main.py b/main.py index 78c1870..cf67ea5 100644 --- a/main.py +++ b/main.py @@ -10,7 +10,7 @@ ############ HASSIO ADDON -print('STARTING MAIN LOOP TYDOM2MQTT') +print('STARTING TYDOM2MQTT') print('Dectecting environnement......') @@ -22,6 +22,9 @@ MQTT_PORT = 1883 MQTT_SSL = False TYDOM_ALARM_PIN = None +TYDOM_ALARM_HOME_ZONE = 1 +TYDOM_ALARM_NIGHT_ZONE = 2 + try: with open('/data/options.json') as f: @@ -37,6 +40,10 @@ TYDOM_PASSWORD = data['TYDOM_PASSWORD'] #Tydom password TYDOM_ALARM_PIN = data['TYDOM_ALARM_PIN'] + + TYDOM_ALARM_HOME_ZONE = data['TYDOM_ALARM_HOME_ZONE'] + TYDOM_ALARM_NIGHT_ZONE = data['TYDOM_ALARM_NIGHT_ZONE'] + ####### CREDENTIALS MQTT if data['MQTT_HOST'] != '': MQTT_HOST = data['MQTT_HOST'] @@ -60,6 +67,8 @@ TYDOM_IP = os.getenv('TYDOM_IP', 'mediation.tydom.com') # Local ip address, default to mediation.tydom.com for remote connexion if not specified TYDOM_PASSWORD = os.getenv('TYDOM_PASSWORD') #Tydom password TYDOM_ALARM_PIN = os.getenv('TYDOM_ALARM_PIN') + TYDOM_ALARM_HOME_ZONE = os.getenv('TYDOM_ALARM_HOME_ZONE', 1) + TYDOM_ALARM_NIGHT_ZONE = os.getenv('TYDOM_ALARM_NIGHT_ZONE', 2) ####### CREDENTIALS MQTT MQTT_HOST = os.getenv('MQTT_HOST', 'localhost') MQTT_USER = os.getenv('MQTT_USER') @@ -74,11 +83,9 @@ def loop_task(): tydom = None hassio = None - # Creating client object - hassio = MQTT_Hassio(MQTT_HOST, MQTT_PORT, MQTT_USER, MQTT_PASSWORD, MQTT_SSL) - - # Giving MQTT connection to tydom class for updating + hassio = MQTT_Hassio(broker_host=MQTT_HOST, port=MQTT_PORT, user=MQTT_USER, password=MQTT_PASSWORD, mqtt_ssl=MQTT_SSL, home_zone=TYDOM_ALARM_HOME_ZONE, night_zone=TYDOM_ALARM_NIGHT_ZONE) + # Giving MQTT connection to tydom client tydom = TydomWebSocketClient(mac=TYDOM_MAC, host=TYDOM_IP, password=TYDOM_PASSWORD, alarm_pin=TYDOM_ALARM_PIN, mqtt_client=hassio) # Start connection and get client connection protocol diff --git a/mqtt_client.py b/mqtt_client.py index 7d6b40f..e7276a9 100644 --- a/mqtt_client.py +++ b/mqtt_client.py @@ -19,7 +19,7 @@ # STOP = asyncio.Event() class MQTT_Hassio(): - def __init__(self, broker_host, port, user, password, mqtt_ssl, tydom = None, tydom_alarm_pin = None): + def __init__(self, broker_host, port, user, password, mqtt_ssl, home_zone=1, night_zone=2, tydom = None, tydom_alarm_pin = None): self.broker_host = broker_host self.port = port self.user = user @@ -28,7 +28,8 @@ def __init__(self, broker_host, port, user, password, mqtt_ssl, tydom = None, ty self.tydom = tydom self.tydom_alarm_pin = tydom_alarm_pin self.mqtt_client = None - + self.home_zone = home_zone + self.night_zone = night_zone async def connect(self): @@ -121,28 +122,12 @@ async def on_message(self, client, topic, payload, qos, properties): - # elif ('set_alarm_state' in str(topic)) and not ('homeassistant'in str(topic)): - # # print(topic, payload, qos, properties) - # command = str(payload).strip('b').strip("'") - # get_id = (topic.split("/"))[2] #extract id from mqtt - - # await Alarm.put_alarm_state(tydom_client=self.tydom, alarm_id=get_id, asked_state=command) - - # if 'alarmState' in attr and attr['alarmState'] == "ON": - # state = "triggered" - # if 'alarmSOS' in attr and attr['alarmSOS'] == "true": - # state = "triggered" - # sos_state = True - # elif 'alarmMode' in attr and attr ["alarmMode"] == "ON": - # state = "armed_away" - # elif 'alarmMode' in attr and attr["alarmMode"] == "ZONE": - # state = "armed_home" - # elif 'alarmMode' in attr and attr["alarmMode"] == "OFF": - # state = "disarmed" - - - + elif ('set_alarm_state' in str(topic)) and not ('homeassistant'in str(topic)): + # print(topic, payload, qos, properties) + command = str(payload).strip('b').strip("'") + get_id = (topic.split("/"))[2] #extract id from mqtt + await Alarm.put_alarm_state(tydom_client=self.tydom, alarm_id=get_id, asked_state=command, home_zone=self.home_zone, night_zone=self.night_zone) else: pass diff --git a/tydomMessagehandler.py b/tydomMessagehandler.py index c46dbec..3969fd4 100644 --- a/tydomMessagehandler.py +++ b/tydomMessagehandler.py @@ -267,7 +267,6 @@ async def parse_devices_data(self, parsed): if elementName in deviceAlarmDetailsKeywords: attr_alarm_details[elementName] = elementValue else: - attr_alarm[elementName] = elementValue attr_alarm['attributes'] = attr_alarm_details #KEEPING original details for attributes # print(attr_alarm['attributes']) @@ -284,7 +283,7 @@ async def parse_devices_data(self, parsed): # Get last known state (for alarm) # NEW METHOD elif 'device_type' in attr_alarm and attr_alarm['device_type'] == 'alarm_control_panel': - print(attr_alarm) + # print(attr_alarm) state = None sos_state = False maintenance_mode = False diff --git a/tydom_websocket.py b/tydom_websocket.py index 7fe5fe3..b416861 100644 --- a/tydom_websocket.py +++ b/tydom_websocket.py @@ -227,7 +227,20 @@ async def put_devices_data(self, endpoint_id, name, value): print('PUT /devices/data send to Websocket !') return 0 - async def put_alarm_cdata(self, alarm_id, asked_state, zone=None): + async def put_alarm_cdata(self, alarm_id=None, value=None, zone_id=None): + + # Credits to @mgcrea on github ! + # AWAY # "PUT /devices/{}/endpoints/{}/cdata?name=alarmCmd HTTP/1.1\r\ncontent-length: 29\r\ncontent-type: application/json; charset=utf-8\r\ntransac-id: request_124\r\n\r\n\r\n{"value":"ON","pwd":{}}\r\n\r\n" + # HOME "PUT /devices/{}/endpoints/{}/cdata?name=zoneCmd HTTP/1.1\r\ncontent-length: 41\r\ncontent-type: application/json; charset=utf-8\r\ntransac-id: request_46\r\n\r\n\r\n{"value":"ON","pwd":"{}","zones":[1]}\r\n\r\n" + # DISARM "PUT /devices/{}/endpoints/{}/cdata?name=alarmCmd HTTP/1.1\r\ncontent-length: 30\r\ncontent-type: application/json; charset=utf-8\r\ntransac-id: request_7\r\n\r\n\r\n{"value":"OFF","pwd":"{}"}\r\n\r\n" + + # variables: + # id + # Cmd + # value + # pwd + # zones + if not self.connection.open: print('Connection closed, exiting to ensure restart....') @@ -236,33 +249,34 @@ async def put_alarm_cdata(self, alarm_id, asked_state, zone=None): if self.alarm_pin == None: print('TYDOM_ALARM_PIN not set !') pass + try: + Cmd = None + + if zone_id == None: + Cmd = 'alarmCmd' + body="{\"value\":\"" + str(value) + "\",\"pwd\":\""+ str(self.alarm_pin) + "\"}" + # body= {"value":"OFF","pwd":"123456"} + else: + Cmd = 'zoneCmd' + body="{\"value\":\"" + str(value) + "\",\"pwd\":\""+ str(self.alarm_pin) + "\",\"zones\":\"["+ str(zone_id) + "]\"}" + + # str_request = self.cmd_prefix + "PUT /devices/{}/endpoints/{}/cdata?name={},".format(str(alarm_id),str(alarm_id),str(cmd)) + body +");" + str_request = self.cmd_prefix + "PUT /devices/{}/endpoints/{}/cdata?name={} HTTP/1.1\r\nContent-Length: ".format(str(alarm_id),str(alarm_id),str(Cmd))+str(len(body))+"\r\nContent-Type: application/json; charset=UTF-8\r\nTransac-Id: 0\r\n\r\n"+body+"\r\n\r\n" + + + a_bytes = bytes(str_request, "ascii") + # print(a_bytes) + await self.connection.send(a_bytes) + print('PUT alarm cdata send to Websocket !') + return 0 + except Exception as e: + print('put_alarm_cdata ERROR !') + print(e) + print(a_bytes) - if zone == None: - cmd = 'alarmCmd' - body=" "+"{\"pwd\":\"" + str(self.alarm_pin) + "\",\"value\":\""+ asked_state + "\"}" - else: - cmd = 'zoneCmd' - body="{\"pwd\":\"" + str(self.alarm_pin) + "\",\"value\":\""+ 'ON' + "\",\"zones\":\""+ '1' + "\"}" - str_request = self.cmd_prefix + "PUT /devices/{}/endpoints/{}/cdata?name={},".format(str(alarm_id),str(alarm_id),str(cmd)) + body +");" - # str_request = self.cmd_prefix + "PUT /devices/{}/endpoints/{}/cdata?name={} HTTP/1.1\r\nContent-Length: ".format(str(alarm_id),str(alarm_id),str(cmd))+str(len(body))+"\r\nContent-Type: application/json; charset=UTF-8\r\nTransac-Id: 0\r\n\r\n"+body+"\r\n\r\n" - a_bytes = bytes(str_request, "ascii") - print(a_bytes) - await self.connection.send(a_bytes) - print('PUT alarm cdata send to Websocket !',a) - return 0 - # await client.put(`/devices/${deviceId}/endpoints/${endpointId}/cdata?name=alarmCmd`, { - # value: nextValue, - # pwd: pin - # }); - # await client.put(`/devices/${deviceId}/endpoints/${endpointId}/cdata?name=zoneCmd`, { - # value: nextValue, - # pwd: pin, - # zones: targetZones - # }); - # Run scenario async def put_scenarios(self, scenario_id): body="" # scenario_id is the id of scenario got from the get_scenarios command