diff --git a/Zigbee_Doorlock.py b/tuyactl/Zigbee_Doorlock.py similarity index 97% rename from Zigbee_Doorlock.py rename to tuyactl/Zigbee_Doorlock.py index 833078e..ed8ad07 100644 --- a/Zigbee_Doorlock.py +++ b/tuyactl/Zigbee_Doorlock.py @@ -1,77 +1,77 @@ -#!/usr/bin/env python3 - -import paho.mqtt.client as mqtt -import paho.mqtt.publish as publish -import json - -from env import * - -from tuya_iot import * -from Crypto.Util.Padding import pad, unpad -from Crypto.Cipher import AES - -pad_pkcs7 = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * \ - chr(BLOCK_SIZE - len(s) % BLOCK_SIZE) -unpad_pkcs7 = lambda s: s[:-ord(s[len(s) - 1:])] - -class AESCipher: - """ - Usage: - c = AESCipher('secret_key').encrypt('message') - m = AESCipher('secret_key').decrypt(c) - """ - - def __init__(self, hex_key): - self.key = hex_key.encode('utf-8') - - def __pad(self, s): - return s + (self.BLOCK_SIZE - len(s) % self.BLOCK_SIZE) \ - * chr(self.BLOCK_SIZE - len(s) % self.BLOCK_SIZE) - - def __unpad(self, s): - return s[:-ord(s[len(s) - 1:])] - - def encrypt(self, raw): - raw = self.__pad(raw) - cipher = AES.new(self.key, AES.MODE_ECB) - return cipher.encrypt(raw).hex().upper() - - def decrypt(self, enc): - cipher = AES.new(self.key, AES.MODE_ECB) - return self.__unpad(cipher.decrypt(enc)).decode('utf8') - -def on_connect(client, userdata, flags, rc): - client.subscribe(DOORLOCK_TOPIC + "/#") - -def on_message(client, userdata, msg): - - if msg.topic == DOORLOCK_TOPIC_CMD and msg.payload.decode() == "unlock_door": - afd = openapi.post('/v1.0/devices/' + ZIGBEE_LOCK + '/door-lock/password-ticket') - x = json.dumps(afd) - check_token = json.loads(x) - PasswordTicket = check_token["result"]["ticket_key"] - TICKETID = check_token["result"]["ticket_id"] - encrypted_ticket = bytes.fromhex(PasswordTicket) - decrypted_ticket = AESCipher(ACCESS_KEY).decrypt(encrypted_ticket) - decrypted_msg = decrypted_ticket # result from Erol - lock_pincode = pad(LOCKPINCODE.encode('UTF-8'), BLOCK_SIZE) - cipher = AES.new(decrypted_msg.encode('utf8'), AES.MODE_ECB) - ready_password = cipher.encrypt(lock_pincode) - opendoor_password = ready_password.hex() - openapi.post('/v1.0/devices/' + ZIGBEE_LOCK + '/door-lock/open-door', { - 'password_type': 'ticket', - 'password': opendoor_password, - 'ticket_id': TICKETID, - }) - -openapi = TuyaOpenAPI(ENDPOINT, ACCESS_ID, ACCESS_KEY, ProjectType.SMART_HOME) -openapi.login(USERNAME, PASSWORD, COUNTRY_CODE, SCHEMA) - -client = mqtt.Client(MQTT_CLIENT_ID) -client.username_pw_set(MQTT_USERNAME, MQTT_PASSWORD) -client.on_connect = on_connect -client.on_message = on_message - -client.connect(MQTT_BROKER, MQTT_PORT) - +#!/usr/bin/env python3 + +import paho.mqtt.client as mqtt +import paho.mqtt.publish as publish +import json + +from env import * + +from tuya_iot import * +from Crypto.Util.Padding import pad, unpad +from Crypto.Cipher import AES + +pad_pkcs7 = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * \ + chr(BLOCK_SIZE - len(s) % BLOCK_SIZE) +unpad_pkcs7 = lambda s: s[:-ord(s[len(s) - 1:])] + +class AESCipher: + """ + Usage: + c = AESCipher('secret_key').encrypt('message') + m = AESCipher('secret_key').decrypt(c) + """ + + def __init__(self, hex_key): + self.key = hex_key.encode('utf-8') + + def __pad(self, s): + return s + (self.BLOCK_SIZE - len(s) % self.BLOCK_SIZE) \ + * chr(self.BLOCK_SIZE - len(s) % self.BLOCK_SIZE) + + def __unpad(self, s): + return s[:-ord(s[len(s) - 1:])] + + def encrypt(self, raw): + raw = self.__pad(raw) + cipher = AES.new(self.key, AES.MODE_ECB) + return cipher.encrypt(raw).hex().upper() + + def decrypt(self, enc): + cipher = AES.new(self.key, AES.MODE_ECB) + return self.__unpad(cipher.decrypt(enc)).decode('utf8') + +def on_connect(client, userdata, flags, rc): + client.subscribe(DOORLOCK_TOPIC + "/#") + +def on_message(client, userdata, msg): + + if msg.topic == DOORLOCK_TOPIC_CMD and msg.payload.decode() == "unlock_door": + afd = openapi.post('/v1.0/devices/' + ZIGBEE_LOCK + '/door-lock/password-ticket') + x = json.dumps(afd) + check_token = json.loads(x) + PasswordTicket = check_token["result"]["ticket_key"] + TICKETID = check_token["result"]["ticket_id"] + encrypted_ticket = bytes.fromhex(PasswordTicket) + decrypted_ticket = AESCipher(ACCESS_KEY).decrypt(encrypted_ticket) + decrypted_msg = decrypted_ticket # result from Erol + lock_pincode = pad(LOCKPINCODE.encode('UTF-8'), BLOCK_SIZE) + cipher = AES.new(decrypted_msg.encode('utf8'), AES.MODE_ECB) + ready_password = cipher.encrypt(lock_pincode) + opendoor_password = ready_password.hex() + openapi.post('/v1.0/devices/' + ZIGBEE_LOCK + '/door-lock/open-door', { + 'password_type': 'ticket', + 'password': opendoor_password, + 'ticket_id': TICKETID, + }) + +openapi = TuyaOpenAPI(ENDPOINT, ACCESS_ID, ACCESS_KEY, ProjectType.SMART_HOME) +openapi.login(USERNAME, PASSWORD, COUNTRY_CODE, SCHEMA) + +client = mqtt.Client(MQTT_CLIENT_ID) +client.username_pw_set(MQTT_USERNAME, MQTT_PASSWORD) +client.on_connect = on_connect +client.on_message = on_message + +client.connect(MQTT_BROKER, MQTT_PORT) + client.loop_forever() \ No newline at end of file diff --git a/env.py b/tuyactl/env.py similarity index 95% rename from env.py rename to tuyactl/env.py index 57e097b..3a4978e 100644 --- a/env.py +++ b/tuyactl/env.py @@ -1,64 +1,64 @@ -#!/usr/bin/env python3 - -# online -ACCESS_ID = "" -ACCESS_KEY = "" -## Mobile APP -USERNAME = "" -PASSWORD = "" -COUNTRY_CODE = "31" -SCHEMA = "smartlife" -ASSET_ID = "" -DEVICE_ID = "" -ENDPOINT = "https://openapi.tuyaeu.com" - -TUYA_UID = "" -### Devices UUID -ZIGBEE_LOCK = "" -WIFI_LOCK = "" -BECK_LOCK = "" -WIFI_SCALE = "" -LOCKPINCODE = "123456" - -### MQTT Broker -MQTT_BROKER = '' -MQTT_PORT = 1883 -MQTT_CLIENT_ID = 'TuyaLock' -MQTT_USERNAME = '' -MQTT_PASSWORD = '' -MQTT_TOPIC = 'TuyaLock' - -MQTT_ZIGBEELOCK_TOPIC = "Doorlock" -MQTT_WIFI_SCALE_TOPIC = "WiFi_Scale" - -MQTT_TOPIC_CMD = "cmd" -MQTT_TOPIC_LWT = "lwt" -MQTT_TOPIC_STATUS = "status" - -### HA Autodiscovery MQTT-Topics -HA_DISCOVERY = "false" -HA_DISCOVERY_TOPIC = "" -HA_DISCOVERY_MSG = '' - -### WiFi Scale Users_ID -SCALE_USER_ID = '' - -expired_token = "token is expired" -DOORLOCK_TOPIC = MQTT_TOPIC + "/" + MQTT_ZIGBEELOCK_TOPIC -DOORLOCK_TOPIC_CMD = DOORLOCK_TOPIC + "/" + MQTT_TOPIC_CMD -DOORLOCK_TOPIC_STATUS = DOORLOCK_TOPIC + "/" + MQTT_TOPIC_STATUS -WIFI_SCALE_TOPIC = MQTT_TOPIC + "/" + MQTT_WIFI_SCALE_TOPIC -WIFI_SCALE_TOPIC_CMD = WIFI_SCALE_TOPIC + "/" + MQTT_TOPIC_CMD -WIFI_SCALE_TOPIC_STATUS = WIFI_SCALE_TOPIC + "/" + MQTT_TOPIC_STATUS -WIFI_SCALE_TOPIC_LWT = WIFI_SCALE_TOPIC + "/" + MQTT_TOPIC_LWT -BLOCK_SIZE = 16 -PAGE_NO = '1' -PAGE_SIZE = '999' -FAKE_HEIGHT = '180' -FAKE_WEIGHT = '666' -FAKE_AGE = '35' -FAKE_SEX = '1' -FAKE_RESISTANCE = '683' -MQTT_KEEP_ALIE_INTERVAL = 60 -TUYA_IMG_URL = "https://images.tuyacn.com/smart/" +#!/usr/bin/env python3 + +# online +ACCESS_ID = "" +ACCESS_KEY = "" +## Mobile APP +USERNAME = "" +PASSWORD = "" +COUNTRY_CODE = "31" +SCHEMA = "smartlife" +ASSET_ID = "" +DEVICE_ID = "" +ENDPOINT = "https://openapi.tuyaeu.com" + +TUYA_UID = "" +### Devices UUID +ZIGBEE_LOCK = "" +WIFI_LOCK = "" +BECK_LOCK = "" +WIFI_SCALE = "" +LOCKPINCODE = "123456" + +### MQTT Broker +MQTT_BROKER = '' +MQTT_PORT = 1883 +MQTT_CLIENT_ID = 'TuyaLock' +MQTT_USERNAME = '' +MQTT_PASSWORD = '' +MQTT_TOPIC = 'TuyaLock' + +MQTT_ZIGBEELOCK_TOPIC = "Doorlock" +MQTT_WIFI_SCALE_TOPIC = "WiFi_Scale" + +MQTT_TOPIC_CMD = "cmd" +MQTT_TOPIC_LWT = "lwt" +MQTT_TOPIC_STATUS = "status" + +### HA Autodiscovery MQTT-Topics +HA_DISCOVERY = "false" +HA_DISCOVERY_TOPIC = "" +HA_DISCOVERY_MSG = '' + +### WiFi Scale Users_ID +SCALE_USER_ID = '' + +expired_token = "token is expired" +DOORLOCK_TOPIC = MQTT_TOPIC + "/" + MQTT_ZIGBEELOCK_TOPIC +DOORLOCK_TOPIC_CMD = DOORLOCK_TOPIC + "/" + MQTT_TOPIC_CMD +DOORLOCK_TOPIC_STATUS = DOORLOCK_TOPIC + "/" + MQTT_TOPIC_STATUS +WIFI_SCALE_TOPIC = MQTT_TOPIC + "/" + MQTT_WIFI_SCALE_TOPIC +WIFI_SCALE_TOPIC_CMD = WIFI_SCALE_TOPIC + "/" + MQTT_TOPIC_CMD +WIFI_SCALE_TOPIC_STATUS = WIFI_SCALE_TOPIC + "/" + MQTT_TOPIC_STATUS +WIFI_SCALE_TOPIC_LWT = WIFI_SCALE_TOPIC + "/" + MQTT_TOPIC_LWT +BLOCK_SIZE = 16 +PAGE_NO = '1' +PAGE_SIZE = '999' +FAKE_HEIGHT = '180' +FAKE_WEIGHT = '666' +FAKE_AGE = '35' +FAKE_SEX = '1' +FAKE_RESISTANCE = '683' +MQTT_KEEP_ALIE_INTERVAL = 60 +TUYA_IMG_URL = "https://images.tuyacn.com/smart/" TUYA_OLD_IMG_URL = "smart/" \ No newline at end of file