I just got this working. Notes:
- It’s still a bit ugly and hacked up, but posting so that you can have a starting point
- I’m just learning python, so be nice
I have set up the following:
- Link M1 with tuya app
- Setup app with iot.tuya per these instructions: https://pypi.org/project/tinytuya/#modal-close
** Note I had to contact iot.tuya support to get “registered as a company…” what a pain…
- Use tinytuya to get the local M1 key
- Note: You have to go through the app/cloud stuff to get the local key. Once you have that, the polling is local. However, I think you must keep the M1 attached to the tuya app.
- Created a polling python script to pull the data from the M1, filter bad data etc.
- use MQTT to publish the availability and
- create an MQTT sensor in HA
My Python script for polling:
#!/usr/bin/env python
import paho.mqtt.client as mqtt
import paho.mqtt.publish as publish
import tinytuya
import json
import time
import threading
connected = False
topic = "pooltemp"
availtopic = "pooltemp/available"
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
global connected
print("Connected with result code "+str(rc))
connected = True
def on_disconnect(client, userdata, rc):
global connected
print("Disconnected")
connected = False
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload))
def sendloop():
global topic
global availtopic
while True:
time.sleep(10)
print("checking send")
print(connected)
x = {
"available": False
}
available = "offline"
if connected:
try:
d = tinytuya.OutletDevice(<apikey from tinytuya>, <M1 ip address>, <M1 local key from tinytuya>)
d.set_version(3.3)
data = d.status()
dpsdata = data["dps"]
print(dpsdata)
celc100s = (dpsdata["108"])# just looking through the M1 JSON data to find the correct value
if (celc100s == 30000): # The M1 returns 30000 for unconnected devices
degf = 0
else:
available = "online"
degf = ((celc100s / 100)*9/5) + 32
degf = round(degf, 1)
print(degf)
battery= dpsdata["107"]
x = {
"temperature": degf,
"battery": battery,
"available": True
}
except Exception as e:
print("Exception")
print(e)
x = {
"available": False
}
y = json.dumps(x)
print(y)
if (available == "online"):
print("device online: ",y)
client.publish(topic, payload=y, qos=0, retain=False)
else:
print("Device offline")
client.publish(availtopic, payload=available, qos=0, retain=False)
time.sleep(20)
print("Starting sendloop")
sendthread = threading.Thread(target=sendloop)
sendthread.start()
print("Creating client")
client = mqtt.Client(client_id="", clean_session=True, userdata=None, protocol=mqtt.MQTTv311, transport="tcp")
print("Setting up callbacks")
client.on_connect = on_connect
client.on_message = on_message
client.on_disconnect = on_disconnect
print("Setting up will message")
client.will_set(availtopic, payload="offline", qos=0, retain=True)
print("Setting up creds")
client.username_pw_set(username=<your mqtt user id>, password=<your mqtt server PW>)
print("about to connect")
client.connect(<your MQTT server IP address>, 1883, 60)
print ("connecting...")
client.loop_forever()
My HA configuration for the sensors:
sensor:
- platform: mqtt
state_topic: "pooltemp"
name: inkbirdpooltemp
unit_of_measurement: '°F'
value_template: "{{ value_json.temperature }}"
expire_after: 600
payload_available: "available"
availability:
- topic: "pooltemp/available"
- platform: mqtt
state_topic: "pooltemp"
name: inkbirdpoolbattery
unit_of_measurement: '%'
value_template: "{{ value_json.battery }}"
expire_after: 600
payload_available: "available"
availability:
- topic: "pooltemp/available"