jasonacox / tuyapower

Python module to read status and energy monitoring data from Tuya based WiFi smart devices. This includes state (on/off), current (mA), voltage (V), and power (wattage).
MIT License
136 stars 20 forks source link

Tuya smart plug keeps reseting on multiple queries #30

Open alexbutoi opened 11 months ago

alexbutoi commented 11 months ago

Hi,

I have created my own Prometheus exporter with the help of your plugjson.py ( big thanks by the way) and I pull metrics every 5 seconds from the plug .

..... ..... responsejson = subprocess.check_output(["python3", "plugjson.py", "7033XXXXXXXXXXXXXXXX", "10.0.XX.XXX"]).decode("utf-8") ..... .....

Everything works fine, Prometheus is reading the metrics but the plug keeps resetting.

alexbutoi commented 11 months ago

this is the JSON response of the script: $ python3 plugjson.py 7033XXXXXXXXXXXXXXXX 10.0.XX.XXX

{ "datetime": "2023-07-27T11:52:55Z", "switch": "{'1': True, '2': True}", "power": "61.0", "current": "570.0", "voltage": "244.3", "error": "OK" }

and for clearance, this is the script I was doing , nothing fancy, just an exporter :

import json
import subprocess
from flask import Flask, Response
from prometheus_client import Gauge, generate_latest, REGISTRY

app = Flask(__name__)

# Create Prometheus metrics
power_gauge = Gauge('power', 'Current power consumption', ['type'])
current_gauge = Gauge('current', 'Current value', ['type'])
voltage_gauge = Gauge('voltage', 'Current voltage', ['type'])

# Function to parse the JSON response and extract relevant data
def parse_json_response(json_str):
    parsed_response = json.loads(json_str)
    power_value = float(parsed_response["power"])
    current_value = float(parsed_response["current"])
    voltage_value = float(parsed_response["voltage"])
    return power_value, current_value, voltage_value

# Route to expose Prometheus metrics
@app.route('/metrics')
def metrics():
    # Read the output of your Python script
    try:
        responsejson = subprocess.check_output(["python3", "plugjson.py", "7033XXXXXXXXXXXXXXXX", "10.0.XX.XXX"]).decode("utf-8")
    except subprocess.CalledProcessError as e:
        return f"Error executing script: {e}"

    power, current, voltage = parse_json_response(responsejson)

    # Set metrics values
    power_gauge.labels(type="current_power").set(power)
    current_gauge.labels(type="current_value").set(current)
    voltage_gauge.labels(type="current_voltage").set(voltage)

    return Response(generate_latest(REGISTRY), content_type='text/plain')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=9442)
alexbutoi commented 11 months ago

I tested the plugjson.py script only and it seems that something is triggering the plug to reset. Not sure if related but it was running for 10 minutes only and then got the reset.

$ while true; do python3 plugjson.py; date; sleep 5; done
{ "datetime": "2023-07-27T13:14:28Z", "switch": "{'1': True, '2': True}", "power": "65.0", "current": "500.0", "voltage": "245.1", "error": "OK" }
Thu Jul 27 13:14:28 UTC 2023
...
...
...
{ "datetime": "2023-07-27T13:24:40Z", "switch": "{'1': True, '2': True}", "power": "57.7", "current": "429.0", "voltage": "246.3", "error": "OK" }
Thu Jul 27 13:24:40 UTC 2023
jasonacox commented 11 months ago

Hi @alexbutoi - what do you mean by "resetting"? Do you mean it seems to disappear?

alexbutoi commented 11 months ago

Hi Jason, thanks for your reply.

I hear the relay inside the KSIX-BXWSP211 flipping from ON to OFF and back ON very fast. This model has 2 power outputs so this happens to both of the relay switches. I have a server in one of the power outputs of the smart plug and a router in the other one, and both of them (server and router) are restarting after I hear the relay clicking sound.

alexbutoi commented 11 months ago

Since I've moved the server out of the smartplug, I can continue to monitor. The plug triggered the restart of my devices plugged in at 2023-07-28T07:11:05 and I don't see the state of switches being "False"

Can I activate some debug for a more verbose logs?

{ "datetime": "2023-07-28T07:11:00Z", "switch": "{'1': True, '2': True}", "power": "93.9", "current": "460.0", "voltage": "243.2", "error": "OK" }
{ "datetime": "2023-07-28T07:11:01Z", "switch": "{'1': True, '2': True}", "power": "93.9", "current": "460.0", "voltage": "243.2", "error": "OK" }
{ "datetime": "2023-07-28T07:11:03Z", "switch": "{'1': True, '2': True}", "power": "93.9", "current": "460.0", "voltage": "243.2", "error": "OK" }
{ "datetime": "2023-07-28T07:11:04Z", "switch": "{'1': True, '2': True}", "power": "93.9", "current": "460.0", "voltage": "243.2", "error": "OK" }
{ "datetime": "2023-07-28T07:11:05Z", "switch": "{'1': True, '2': True}", "power": "69.1", "current": "316.0", "voltage": "241.6", "error": "OK" }
{ "datetime": "2023-07-28T07:11:16Z", "switch": "{'1': True, '2': True}", "power": "69.1", "current": "316.0", "voltage": "241.6", "error": "OK" }
{ "datetime": "2023-07-28T07:11:17Z", "switch": "{'1': True, '2': True}", "power": "69.1", "current": "316.0", "voltage": "241.6", "error": "OK" }
{ "datetime": "2023-07-28T07:11:19Z", "switch": "{'1': True, '2': True}", "power": "69.1", "current": "316.0", "voltage": "241.6", "error": "OK" }
jasonacox commented 11 months ago

You can activate tinytuya debugging by adding this to the plugjson.py python script:

import tinytuya

tinytuya.set_debug(True)

You could also create a tinytuya monitor loop to run to see what the swtich is emitting when this occurs:

import tinytuya

d = tinytuya.OutletDevice('DEVICEID', 'DEVICEIP', 'DEVICEKEY')
d.set_version(3.3)
d.set_socketPersistent(True)

print(" > Send Request for Status < ")
payload = d.generate_payload(tinytuya.DP_QUERY)
d.send(payload)

print(" > Begin Monitor Loop <")
while(True):
    # See if any data is available
    data = d.receive()
    print('Received Payload: %r' % data)

    # Send keyalive heartbeat
    print(" > Send Heartbeat Ping < ")
    payload = d.generate_payload(tinytuya.HEART_BEAT)
    d.send(payload)