Open vladak opened 1 year ago
Experimenting a bit, when changing get_energy_usage
in the payload to something else (get_energy_info
), the response changes to:
{'error_code': -1002}
P100.py
contains:
ERROR_CODES = {
"0": "Success",
"-1010": "Invalid Public Key Length",
"-1012": "Invalid terminalUUID",
"-1501": "Invalid Request or Credentials",
"1002": "Incorrect Request",
"-1003": "JSON formatting error "
}
so the "1002"
should probably be changed to "-1002"
. Anyway, this means that get_energy_usage
is likely correct even in the new firmware.
Using the proposed change #77 and querying my P110 with the example you listed above i get
energy usage: {'result': {'today_runtime': 1366, 'month_runtime': 1648, 'today_energy': 230, 'month_energy': 230, 'local_time': '2022-09-30 22:46:23', 'past24h': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 47, 49, 52, 41], 'past30d': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230], 'past1y': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230], 'past7d': [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 47, 49, 52, 41, 0]], 'current_power': 55598}, 'error_code': 0}
it seems to be working fine?
It does not in my case. To be sure, I cloned https://github.com/tking2/TapoP100.git (the main
branch, used for the PR #77) and:
$ git log --pretty=oneline -2
315929a1e4e79bb622e061dacaca512d4d9cd597 (HEAD -> main, origin/main, origin/HEAD) chg: Pre-emptively move to using cookies
132ae9b4893584a023be69ae497560a928b1c24e fix: Improve parsing of cookie, thus removing trailing ;
$ python3 -m venv env
$ . ./env/bin/activate
$ which pip
/Users/me/Pi/TapoP100/env/bin/pip
$ pip install -e .
Obtaining file:///Users/me/Pi/TapoP100
Preparing metadata (setup.py) ... done
...
$ python3
>>> from PyP100 import PyP110
>>> hostname = "..."
>>> username = "..."
>>> password = "..."
>>> p110 = PyP110.P110(hostname, username, password)
>>> p110.handshake()
>>> p110.login()
>>> p110.getDeviceInfo()
{'result': {'device_id': ...
>>> p110.getEnergyUsage()
{'error_code': -1003}
I'm running 1.0.16 Build 220624 Rel. 171733
on a P110 (uk/ireland)
Pulling from the @tking2 repo (now merged)
FROM python:3.11-rc-alpine3.15
RUN apk --no-cache add git
WORKDIR /usr/src/app
RUN git clone https://github.com/tking2/TapoP100.git && cd TapoP100 && python setup.py install
COPY script.py .
CMD python script.py
p110 = PyP110.P110("192.168.0.214", "username", "passed")
p110.handshake()
p110.login()
payload = json.loads(str(p110.getEnergyUsage()).replace("\'", "\"" ))
milliwatts = payload['result']['current_power']
Thats currently working for me
Interestingly the JSON returned from the device uses single quotes instead of double quotes. I do a find and replace before parsing the payload. It might be a nice enhancement to have getters on the object returned by getEnergyUsage to extract metrics.
Hi @vladak, I can't seem to replicate this either unfortunately. Updated my P110 to the latest and matching firmware as you have, and get the intended response. All looks OK with your payload, correctly formatted JSON. Still persists after a reboot of the plug?
Personally I'm not sure of the significance of the error codes, but as each is unique might be a better idea just to abs
the code and treat all as positive integers
Maybe try replacing requestTimeMils
with a hardcoded value of 0 just to discount as much as possible (P110/P100 does not seem to care about having a valid millisecond time in this field.
@johnflan - The JSON returned form the device is a python dict. Therefore you don't need to cast to a string and reload, simply doing the following would suffice:
p110 = PyP110.P110("192.168.0.214", "username", "passed")
p110.handshake()
p110.login()
payload = p110.getEnergyUsage()
milliwatts = payload['result']['current_power']
Building getters could be an idea however, which would also allow you to convert into kWh or any other unit, which would also help to satisfy #78
I think historical data is cleared by the firmware update, but should there be empty fields (or zeros) in the data returned? Using the proposed change #77 and calling getEnergyUsage() I get two different results, depending on the firmware version.
For devices running the older firmware (v1.0.16 Build 220624 Rel.171733), I get 'result' which shows historical data populated as:
{'today_runtime': 1213, 'month_runtime': 42966, 'today_energy': 1414, 'month_energy': 56071, 'local_time': '2022-10-22 20:13:00', 'past24h': [72, 42, 167, 134, 54, 37, 72, 88, 37, 38, 85, 77, 40, 62, 98, 105, 65, 87, 62, 36, 88, 74, 46, 29], 'past30d': [1916, 1766, 1825, 1788, 2050, 2037, 1919, 2081, 1858, 1783, 2044, 1922, 1852, 1907, 1790, 1762, 1851, 1896, 2072, 2046, 1796, 1848, 1941, 1940, 1839, 1894, 1792, 1765, 1677, 1414], 'past1y': [0, 0, 0, 0, 0, 0, 0, 0, 0, 29890, 56387, 40689], 'past7d': [[75, 60, 65, 54, ....<snipped to save space>....]], 'current_power': 129899}, 'error_code': 0}
For devices running the newer firmware (v1.1.2 Build 220930 Rel.144500), I get 'result' populated with no historical data fields as:
'result': {'today_runtime': 165, 'month_runtime': 9314, 'today_energy': 33, 'month_energy': 1891, 'local_time': '2022-10-22 20:13:01', 'electricity_charge': [0, 0, 0], 'current_power': 12173}, 'error_code': 0}
Hi @bacheshrew, I'll try to test if this has changed on mine soon.
I'd suggest raising a new issue for this, these are two different issues
Hey guys, Tapo is using a new way to get energy data from the P110.
So now to get energy data for 12 months in one year you can do this:
{ "method": "get_energy_data", "params": { "end_timestamp": 1667260800, "interval": 43200, "start_timestamp": 1640995200 } }
Response:
{ "energy_data": { "local_time": "2022-10-22 20:17:12", "data": [ 32148, 36482, 28707, 14642, 16811, 9126, 12986, 7617, 13833, 14733, 0, 0 ], "start_timestamp": 1640995200, "end_timestamp": 1667260800, "interval": 43200 } }
Interval is in minutes and from what I saw in my tests the minimum interval is 60 minutes
@tking2 New issue (#86) raised. Thanks for testing this
Tested successfully with PyP100==0.1.2 and a P110 device (no load on it) with FW 1.1.2 Build 220930 Rel.144500
>>> from PyP100 import PyP110
>>> p110 = PyP110.P110("192.168.178.43","zoidl@web.de","Jimmy,Fly,Luke2016")
>>> p110.handshake()
>>> p110.login()
>>> print(f"device info: {p110.getDeviceInfo()}")
device info: {'result': {'device_id': '80222C6333A86CD79FCD8057FC20EE341FF0AA16', 'fw_ver': '1.1.2 Build 220930 Rel.144500', 'hw_ver': '1.0', 'type': 'SMART.TAPOPLUG', 'model': 'P110', 'mac': '34-60-F9-56-86-A7', 'hw_id': '2FB30EF5BF920C44099401D396C6B55B', 'fw_id': '00000000000000000000000000000000', 'oem_id': '18BDC6C734AF8407B3EF871EACFCECF5', 'ip': '192.168.178.43', 'time_diff': 60, 'ssid': '<removed>', 'rssi': -40, 'signal_level': 3, 'latitude':<removed>, 'longitude':<removed>, 'lang': 'de_DE', 'avatar': 'plug', 'region': 'Europe/Berlin', 'specs': '', 'nickname': '<removed>', 'has_set_location_info': True, 'device_on': True, 'on_time': 263685, 'default_states': {'type': 'last_states', 'state': {}}, 'overheated': False, 'power_protection_status': 'normal'}, 'error_code': 0}
>>> print(f"energy usage: {p110.getEnergyUsage()}")
energy usage: {'result': {'today_runtime': 1075, 'month_runtime': 4397, 'today_energy': 0, 'month_energy': 0, 'local_time': '2022-11-01 17:55:41', 'electricity_charge': [0, 0, 0], 'current_power': 0}, 'error_code': 0}
>>>
Tested successfully with PyP100==0.1.2 and a P110 device (no load on it) with FW 1.1.2 Build 220930 Rel.144500
My experience with the same PyP100 version on a P110 without load and same firmware differs:
>>> from PyP100 import PyP110
>>> p110 = PyP110.P110("192.168.6.43","someone@somewhere.de","totalgeheim")
>>> p110.handshake()
>>> p110.login()
>>> print(f"device info: {p110.getDeviceInfo()}")
device info: {'result': {'device_id': '802236EAA26BB507FA119D2EB9E2186820564901', 'fw_ver': '1.1.2 Build 220930 Rel.144500', 'hw_ver': '1.0', 'type': 'SMART.TAPOPLUG', 'model': 'P110', 'mac': '9C-A2-F4-7A-A7-3B', 'hw_id': '2FB30EF5BF920C44099401D396C6B55B', 'fw_id': '00000000000000000000000000000000', 'oem_id': '18BDC6C734AF8407B3EF871EACFCECF5', 'ip': '192.168.6.43', 'time_diff': 60, 'ssid': 'removed', 'rssi': -38, 'signal_level': 3, 'latitude': 515900, 'longitude': 103900, 'lang': 'de_DE', 'avatar': 'sound', 'region': 'Europe/Berlin', 'specs': '', 'nickname': 'U3dpdGNoLVRyb2NrbmVy', 'has_set_location_info': True, 'device_on': True, 'on_time': 25144, 'default_states': {'type': 'last_states', 'state': {}}, 'overheated': False, 'power_protection_status': 'normal'}, 'error_code': 0}
>>> print(f"energy usage: {p110.getEnergyUsage()}")
energy usage: {'error_code': -1003}
Initially it works. The error shows up after some runtime if the P110 doesn't have an internet connection. Any suggestions?
Updated 7Nov22: After some initial fails the P110 seems to work stable when regularly polled by Node Red. Has anyone else seen intermittent failures with this firmware/software combo?
Tested successfully with PyP100==0.1.2 and a P110 device (no load on it) with FW 1.1.2 Build 220930 Rel.144500
My experience with the same PyP100 version on a P110 without load and same firmware differs:
>>> from PyP100 import PyP110 >>> p110 = PyP110.P110("192.168.6.43","someone@somewhere.de","totalgeheim") >>> p110.handshake() >>> p110.login() >>> print(f"device info: {p110.getDeviceInfo()}") device info: {'result': {'device_id': '802236EAA26BB507FA119D2EB9E2186820564901', 'fw_ver': '1.1.2 Build 220930 Rel.144500', 'hw_ver': '1.0', 'type': 'SMART.TAPOPLUG', 'model': 'P110', 'mac': '9C-A2-F4-7A-A7-3B', 'hw_id': '2FB30EF5BF920C44099401D396C6B55B', 'fw_id': '00000000000000000000000000000000', 'oem_id': '18BDC6C734AF8407B3EF871EACFCECF5', 'ip': '192.168.6.43', 'time_diff': 60, 'ssid': 'removed', 'rssi': -38, 'signal_level': 3, 'latitude': 515900, 'longitude': 103900, 'lang': 'de_DE', 'avatar': 'sound', 'region': 'Europe/Berlin', 'specs': '', 'nickname': 'U3dpdGNoLVRyb2NrbmVy', 'has_set_location_info': True, 'device_on': True, 'on_time': 25144, 'default_states': {'type': 'last_states', 'state': {}}, 'overheated': False, 'power_protection_status': 'normal'}, 'error_code': 0} >>> print(f"energy usage: {p110.getEnergyUsage()}") energy usage: {'error_code': -1003}
Initially it works. The error shows up after some runtime if the P110 doesn't have an internet connection. Any suggestions?
Updated 7Nov22: After some initial fails the P110 seems to work stable when regularly polled by Node Red. Has anyone else seen intermittent failures with this firmware/software combo?
Hey @ErnstAhlers , how did you manage to solve the issue? I am running the P110 ("fw_ver": "1.1.5 Build 221109 Rel.125117") without internet connection and I am getting the same error when trying to query the energy usage {'error_code': -1003}
Hi 6661620a, I didn't resolve the issue but switched to a different make that works more reliably with Node Red. Best Ernst
Hi,
I've the same issue with my P110 , Firmware version : 1.1.6 Build 221114 Rel.203339
I'm getting error 1003 when call get_energy_data {'error_code': -1003}
Do you have some workaround ?
A sibling to #76 - after firmware update to 1.0.16, the
get_enery_usage()
request returns error.The code looks like this:
in case of P110 running older firmware (1.0.7),
getEnergyUsage()
produces expected reply. When the program is run against P110 with the newer firmware (using code patched with #77 so thatlogin()
works) it reports this (with sensitive values redacted with...
):Looking into
ERROR_CODES
,-1003
corresponds to 'JSON formatting error'. Printing the payload before encryption looks to be correctly formed JSON:Similarly for the request payload:
and
jq
seems to agree.