TP-Link smart plug HS100/HS110
Moderator: leecollings
-
- Posts: 49
- Joined: Thursday 31 March 2016 20:49
- Target OS: Raspberry Pi / ODroid
- Domoticz version: Beta
- Location: Netherlands
- Contact:
Re: TP-Link smart plug HS100/HS110
Ok, it is working again. Strangely, in the old version of the script I had selected HS110V2 (both HS110's are) and then I got data.
As a last resort, I changed the hardware version under the new script to HS110 and I suddenly got all the data again.
Problem is solved, however I do not understand why the hardware version had to change in order to make it work again
Thanks for the help! Much appreciated.
As a last resort, I changed the hardware version under the new script to HS110 and I suddenly got all the data again.
Problem is solved, however I do not understand why the hardware version had to change in order to make it work again
Thanks for the help! Much appreciated.
Pi3 Domoticz | RFXcom 433E | KAKU/COCO |Harmony Hub | Samsung TV | HS100 | HS110| HUE | Tradfri | Tado| Xiaomi |sensors | scripts| Pi3 Node Red | Pi2 SDS_011 + MH-Z19B | PiAware (zero) | Pi2 breadboard with Node red and Domoticz
-
- Posts: 72
- Joined: Monday 07 August 2017 15:01
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.10717
- Location: Victoria, Australia
- Contact:
Re: TP-Link smart plug HS100/HS110
Hi @nosehook, well done for experimenting to get this going. You have picked up a coding error, which I will fix in my GitHub.by nosehook » Thursday 07 May 2020 22:28
Ok, it is working again. Strangely, in the old version of the script I had selected HS110V2 (both HS110's are) and then I got data.
As a last resort, I changed the hardware version under the new script to HS110 and I suddenly got all the data again.
Line 205 in that version
Code: Select all
if Parameters["Mode1"] in "HS110":
Code: Select all
if "HS110" in Parameters["Mode1"]:
Code: Select all
HS110_divider = 1000 # 1000 or 1 depending on your firmware version of HS110
Code: Select all
create_device = False # True if you need to create a device.
Add devices? (Only required on install then can be turned off): True / False
-
- Posts: 49
- Joined: Thursday 31 March 2016 20:49
- Target OS: Raspberry Pi / ODroid
- Domoticz version: Beta
- Location: Netherlands
- Contact:
Re: TP-Link smart plug HS100/HS110
Hi @Ajay100
Good news! Will update asap.
I did notice the system crashes regularly (mostly after 2,5-3,0 hours, sometimes after 0,1 hour) with six times the plugin running. When I disable them, the system runs for hours on end. Any Idea how to fix that? Should I post the crashlog?
Good news! Will update asap.
I did notice the system crashes regularly (mostly after 2,5-3,0 hours, sometimes after 0,1 hour) with six times the plugin running. When I disable them, the system runs for hours on end. Any Idea how to fix that? Should I post the crashlog?
Pi3 Domoticz | RFXcom 433E | KAKU/COCO |Harmony Hub | Samsung TV | HS100 | HS110| HUE | Tradfri | Tado| Xiaomi |sensors | scripts| Pi3 Node Red | Pi2 SDS_011 + MH-Z19B | PiAware (zero) | Pi2 breadboard with Node red and Domoticz
-
- Posts: 72
- Joined: Monday 07 August 2017 15:01
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.10717
- Location: Victoria, Australia
- Contact:
Re: TP-Link smart plug HS100/HS110
@nosehook, yes the crash log would be handy. Also, try starting with one enabled only and build up from there. If the system crashes with only one enabled then it may help to focus the trouble-shooting.
-
- Posts: 166
- Joined: Sunday 26 April 2020 5:27
- Target OS: Linux
- Domoticz version: 2022.1
- Location: Netherlands
- Contact:
Re: TP-Link smart plug HS100/HS110
Mine would crash soon after startup. I know that the HS110's sometimes go offline. I see that in the event log of my Fritzbox. I thought this might be the cause of crashing Domoticz because in the log I would see that a HS110 was being polled. I increased the timeout of the onHeartbeat gradually and noticed that it is crashing less an less. I now have the timeout set to 240 seconds.
Hue | Zigbee2Mqtt | MQTT | P1 | Xiaomi | RFXCom | Modbus | Qlima | Solaredge
TP-Link | Plugwise | Thermosmart | Node-Red | Grafana | Master and 5 remote servers
TP-Link | Plugwise | Thermosmart | Node-Red | Grafana | Master and 5 remote servers
-
- Posts: 166
- Joined: Sunday 26 April 2020 5:27
- Target OS: Linux
- Domoticz version: 2022.1
- Location: Netherlands
- Contact:
Re: TP-Link smart plug HS100/HS110
The timeout is now set to 1200 seconds and it still crashes. The smartswitches aren't very stable in holding a connection and often give errors. This also causes Domoticz to crash. There must be a way to let Domoticz ignore a smartswitch if it isn't responding, instead of crashing.
Hue | Zigbee2Mqtt | MQTT | P1 | Xiaomi | RFXCom | Modbus | Qlima | Solaredge
TP-Link | Plugwise | Thermosmart | Node-Red | Grafana | Master and 5 remote servers
TP-Link | Plugwise | Thermosmart | Node-Red | Grafana | Master and 5 remote servers
-
- Posts: 72
- Joined: Monday 07 August 2017 15:01
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.10717
- Location: Victoria, Australia
- Contact:
Re: TP-Link smart plug HS100/HS110
@Alain, we are happy to help if you can provide more information, such as logs. If you are persisting with the Python Plugin Manager when it is unsupported in Windows, then I'm not sure if anyone can help. However if you are running other Python Plugin Manager plugins successfully in Windows, please let us know. You could also report this in the Python Plugin Manager thread.
The current code should not crash if the HS100/HS110 is not available. You can suppress socket errors after the first one, with This is so that you can turn the device off completely without continuous errors in Domoticz. I am currently doing this, so I know that it works in my setup.
The current code should not crash if the HS100/HS110 is not available. You can suppress socket errors after the first one, with
Code: Select all
suppress_socket_error = True
-
- Posts: 49
- Joined: Thursday 31 March 2016 20:49
- Target OS: Raspberry Pi / ODroid
- Domoticz version: Beta
- Location: Netherlands
- Contact:
Re: TP-Link smart plug HS100/HS110
Hi ajay100,
I have done two days of trouble shooting so far these are the results:
step 1: Disable all 4 x HS-100 and 2 x HS110 on the hardware page -> system runs stable for 24+ Hours
Step 2: Enable 1 x HS110 after about 8 hours -> system remains stable
Step 3: Enable 2 x HS110 after about another 8 hours-> system remains stable
the last domoticz_crash.log is from 8-5-2020, when I had all 6 HS's enabled on the hardware page.
I don't know if the log is helping:
- Spoiler: show
Pi3 Domoticz | RFXcom 433E | KAKU/COCO |Harmony Hub | Samsung TV | HS100 | HS110| HUE | Tradfri | Tado| Xiaomi |sensors | scripts| Pi3 Node Red | Pi2 SDS_011 + MH-Z19B | PiAware (zero) | Pi2 breadboard with Node red and Domoticz
-
- Posts: 166
- Joined: Sunday 26 April 2020 5:27
- Target OS: Linux
- Domoticz version: 2022.1
- Location: Netherlands
- Contact:
Re: TP-Link smart plug HS100/HS110
I installed the plugin with "git clone" in the plugin directory. I'm getting socket errors, so when I get the chance I will add that piece of code. As far as logs go, sometimes I see a timeout error, but often you just see that the log, thus Domoticz, has stopped some time ago. The logs aren't stired for some reason. As soon as I restart Domoticz, the log is cleared and starts over.ajay100 wrote: ↑Monday 11 May 2020 12:25 @Alain, we are happy to help if you can provide more information, such as logs. If you are persisting with the Python Plugin Manager when it is unsupported in Windows, then I'm not sure if anyone can help. However if you are running other Python Plugin Manager plugins successfully in Windows, please let us know. You could also report this in the Python Plugin Manager thread.
The current code should not crash if the HS100/HS110 is not available. You can suppress socket errors after the first one, withThis is so that you can turn the device off completely without continuous errors in Domoticz. I am currently doing this, so I know that it works in my setup.Code: Select all
suppress_socket_error = True
Hue | Zigbee2Mqtt | MQTT | P1 | Xiaomi | RFXCom | Modbus | Qlima | Solaredge
TP-Link | Plugwise | Thermosmart | Node-Red | Grafana | Master and 5 remote servers
TP-Link | Plugwise | Thermosmart | Node-Red | Grafana | Master and 5 remote servers
-
- Posts: 72
- Joined: Monday 07 August 2017 15:01
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.10717
- Location: Victoria, Australia
- Contact:
Re: TP-Link smart plug HS100/HS110
@nosehook, thanks, good patient troubleshooting is the best! If you start getting crashes with the next added device, try increasing the interval from 1 to 2:
The domoticz_crash.log is above my understanding, but if you post it in the General forum under Bugs and Problems, you might get an answer there which may help us. It looks like Domoticz or the Python Plugin Manager is getting muddled:
Code: Select all
interval = 2 # heartbeat in 10 second multiples
Cannot find user-level thread for LWP 30706: generic error
/home/pi/domoticz/30697: No such file or directory.
No threads.
-
- Posts: 49
- Joined: Thursday 31 March 2016 20:49
- Target OS: Raspberry Pi / ODroid
- Domoticz version: Beta
- Location: Netherlands
- Contact:
Re: TP-Link smart plug HS100/HS110
@ajay100 I think I have good news and bad news:ajay100 wrote: ↑Monday 11 May 2020 14:19 @nosehook, thanks, good patient troubleshooting is the best! If you start getting crashes with the next added device, try increasing the interval from 1 to 2:The domoticz_crash.log is above my understanding, but if you post it in the General forum under Bugs and Problems, you might get an answer there which may help us. It looks like Domoticz or the Python Plugin Manager is getting muddled:Code: Select all
interval = 2 # heartbeat in 10 second multiples
Cannot find user-level thread for LWP 30706: generic error
/home/pi/domoticz/30697: No such file or directory.
No threads.
Good news: the script and plugins are not the reason the system crashes.
Bad news: On a RPi2 or older it is not easily fixable (I think).
Let me explain:
On my Rpi 2b+ I looked at my CPU workload and noticed it was always close to and sometimes over 100%.
In the log I noticed a problem when I had 4 of the 6 plugins (2x hs110 and 4x hs100) disabled. I noticed that with all 6 enabled (and together with the rest of the plugins) there were a lot of messages about dzvents.lua and running for more than 10 seconds and dzvents.lua being ran.
I swapped the SD card image to my RPi 3B+ and noticed a lower workload (5-6%)of the CPU and no issues with dzVents.
What I think is happening is that on the Rpi 2 at 700 MHz the system can not cope with all the events and struggles handling them. Together with a lot of calls to dzVents.lua this causes the system to crash. The RPi 3 at 1200 MHz is much faster, handles everything faster and therefore has less issues.
Bit like having an old cell phone and the thing running slower and slower due to the app demands getting bigger and bigger.
I run Domoticz now with 22 items of hardware (including plugins) and 240 devices. Together with Dashticz, Apache webserver and it's own OS, I think it might be too much for a RPi 2.
So far, no issues on the RPi 3 and a quicker and smoother Domoticz and 6 flawlessly running HS100/110 plugins!
Pi3 Domoticz | RFXcom 433E | KAKU/COCO |Harmony Hub | Samsung TV | HS100 | HS110| HUE | Tradfri | Tado| Xiaomi |sensors | scripts| Pi3 Node Red | Pi2 SDS_011 + MH-Z19B | PiAware (zero) | Pi2 breadboard with Node red and Domoticz
-
- Posts: 72
- Joined: Monday 07 August 2017 15:01
- Target OS: Raspberry Pi / ODroid
- Domoticz version: 4.10717
- Location: Victoria, Australia
- Contact:
Re: TP-Link smart plug HS100/HS110
Thanks @nosehook, that is really good to know!
Cheers - Andrew
Cheers - Andrew
-
- Posts: 166
- Joined: Sunday 26 April 2020 5:27
- Target OS: Linux
- Domoticz version: 2022.1
- Location: Netherlands
- Contact:
Re: TP-Link smart plug HS100/HS110
I created a VM running Linux and my crsshing problems have been solved (so far). It has been running for 2 says now, whereas before it would crash a few times a day.
Hue | Zigbee2Mqtt | MQTT | P1 | Xiaomi | RFXCom | Modbus | Qlima | Solaredge
TP-Link | Plugwise | Thermosmart | Node-Red | Grafana | Master and 5 remote servers
TP-Link | Plugwise | Thermosmart | Node-Red | Grafana | Master and 5 remote servers
-
- Posts: 32
- Joined: Wednesday 13 May 2015 9:05
- Target OS: Linux
- Domoticz version: Stable
- Location: Netherlands
- Contact:
Re: TP-Link smart plug HS100/HS110
Hi,
I am trying to install my HS110, but I am having some start-up problems.
I have installed the Plugin Manager succesfully.
I downloaded the plugin.py (from: https://github.com/ajay10000/domoticz_hs110_plugin), and only changed the base_url to match.
Then I placed it in /home/pi/domoticz/plugins/HS110
Now I restart domoticz with: sudo /etc/init.d/domoticz.sh restart
But now the web-interface is no longer working.
Any ideas?
I am trying to install my HS110, but I am having some start-up problems.
I have installed the Plugin Manager succesfully.
I downloaded the plugin.py (from: https://github.com/ajay10000/domoticz_hs110_plugin), and only changed the base_url to match.
Then I placed it in /home/pi/domoticz/plugins/HS110
Now I restart domoticz with: sudo /etc/init.d/domoticz.sh restart
But now the web-interface is no longer working.
Any ideas?
-
- Posts: 49
- Joined: Thursday 31 March 2016 20:49
- Target OS: Raspberry Pi / ODroid
- Domoticz version: Beta
- Location: Netherlands
- Contact:
Re: TP-Link smart plug HS100/HS110
can you post the content of the file? There might be a fault in it.
Regards,
Freek
Regards,
Freek
Pi3 Domoticz | RFXcom 433E | KAKU/COCO |Harmony Hub | Samsung TV | HS100 | HS110| HUE | Tradfri | Tado| Xiaomi |sensors | scripts| Pi3 Node Red | Pi2 SDS_011 + MH-Z19B | PiAware (zero) | Pi2 breadboard with Node red and Domoticz
-
- Posts: 32
- Joined: Wednesday 13 May 2015 9:05
- Target OS: Linux
- Domoticz version: Stable
- Location: Netherlands
- Contact:
Re: TP-Link smart plug HS100/HS110
Hi Freek,
The device is working good in kasa.
It is getting a fixed ip-adres from my dhcp.
the content of this plugin.py:
# Domoticz TP-Link Wi-Fi Smart Plug plugin
#
# Plugin based on reverse engineering of the TP-Link HS110, courtesy of Lubomir Stroetmann and Tobias Esser.
# https://www.softscheck.com/en/reverse-e ... ink-hs110/
#
# Original Author: Dan Hallgren
# Modified by: Andrew P
#
"""
<plugin key="tplinksmartplug" name="TP-Link Wi-Fi Smart Plug HS100/HS110/v2" version="0.2.6">
<description>
<h2>TP-Link Wi-Fi Smart Plug</h2>
<ul style="list-style-type:square">
<li>On/off switching (HS100 and HS110/HS110v2)</li>
<li>Realtime power, current and voltage (HS110/HS110v2 only)</li>
</ul>
<h3>Devices added to Domoticz:</h3>
<ul style="list-style-type:square">
<li>switch - On/Off (All models)</li>
<li>Realtime power in Watts (HS110/HS110v2)</li>
<li>Realtime current in Amps (HS110/HS110v2)</li>
<li>Realtime voltage in Volts (HS110/HS110v2)</li>
</ul>
</description>
<params>
<param field="Address" label="IP Address" width="200px" required="true"/>
<param field="Mode1" label="Model" width="150px" required="false">
<options>
<option label="HS100" value="HS100" default="true"/>
<option label="HS110/HS110v2" value="HS110" default="false" />
</options>
</param>
<param field="Mode2" label="Add devices? (Only required on install then can be turned off)" width="75px">
<options>
<option label="True" value="True"/>
<option label="False" value="False" default="true" />
</options>
</param>
<param field="Mode6" label="Debug" width="75px">
<options>
<option label="True" value="Debug"/>
<option label="False" value="Normal" default="true" />
</options>
</param>
</params>
</plugin>
"""
import json, socket, Domoticz
# Start user editable variables
base_url = "http://172.1.1.150:8080/" # Modify with your IP# or domain
interval = 1 # heartbeat in 10 second multiples
HS110_divider = 1000 # 1000 or 1 depending on your firmware version of HS110
suppress_socket_error = True # Suppress error messages in Domoticz after the first
# End user editable variables
PORT = 9999
STATES = ('off', 'on', 'unknown')
class TpLinkSmartPlugPlugin:
enabled = False
connection = None
def __init__(self):
self.interval = interval # *10 seconds
self.heartbeatcounter = 0
self.socket_error_suppress = suppress_socket_error
self.last_state = STATES[2]
self.state_flag = False
def onStart(self):
if Parameters["Mode6"] == "Debug":
Domoticz.Debugging(1)
DumpConfigToLog()
if len(Devices) == 0:
# Create a switch, suitable for all models
Domoticz.Device(Name="switch", Unit=1, TypeName="Switch", Used=1).Create()
Domoticz.Log("Tp-Link smart plug switch created")
if "HS110" in Parameters["Mode1"] and Parameters["Mode2"] == "True":
# Create measuring devices here
Domoticz.Device(Name="current (A)", Unit=2, Type=243, Subtype=23).Create()
Domoticz.Device(Name="voltage (V)", Unit=3, Type=243, Subtype=8).Create()
Domoticz.Device(Name="power (W)", Unit=4, Type=243, Subtype=29).Create() # Subtype 29 is kWh
Domoticz.Debug("Number of devices: {}".format(str(len(Devices))))
state = self.get_switch_state()
self.last_state = state
self.set_domoticz_state(state)
def onStop(self):
Domoticz.Debug("onStop called")
pass
def onConnect(self, Connection, Status, Description):
Domoticz.Debug("onConnect called")
pass
def onMessage(self, Connection, Data, Status, Extra):
Domoticz.Debug("onMessage called")
pass
def onCommand(self, unit, command, level, hue):
Domoticz.Debug("onCommand called for Unit {}: Parameter {}, Level {}".format(str(unit), str(command), str(level)))
if command.lower() == 'on':
new_state = 1
state = (1, '100')
else:
new_state = 0
state = (0, '0')
cmd = {
"system": {
"set_relay_state": {"state": new_state}
}
}
result = self._send_json_cmd(json.dumps(cmd))
Domoticz.Debug("got response: {}".format(result))
err_code = result.get('system', {}).get('set_relay_state', {}).get('err_code', 1)
if err_code == 0:
# Update Domoticz
Devices[1].Update(*state)
# Reset counter so we trigger emeter poll next heartbeat
self.heartbeatcounter = 0
def onNotification(self, Name, Subject, Text, Status, Priority, Sound, ImageFile):
Domoticz.Debug("Notification: {}, {}, {}, {}, {}, {}, {}".format(Name, Subject, Text, Status, str(Priority), Sound, ImageFile))
def onDisconnect(self, Connection):
Domoticz.Debug("onDisconnect called")
pass
def onHeartbeat(self):
if self.heartbeatcounter % self.interval == 0:
self.update_emeter_values()
state = self.get_switch_state()
Domoticz.Debug("Last state: {}, Switch state: {}, Domoticz device state: {}".format(self.last_state, state, STATES[Devices[1].nValue]))
if (self.last_state == STATES[2]) and (state != STATES[2]):
Domoticz.Log("Switch device is available, state is {}".format(state))
self.state_flag = False
if self.last_state != state:
self.last_state = state
if (state != STATES[2]) and (STATES[Devices[1].nValue] != state):
self.set_domoticz_state(state)
if (state == STATES[2]) and (self.state_flag == False): # device state unknown
self.set_domoticz_state(STATES[0]) # turn off Domoticz switch
Domoticz.Log("Switch device unavailable, Domoticz device switched off")
self.state_flag = True
self.heartbeatcounter += 1
def _encrypt(self, data):
key = 171
result = b"\x00\x00\x00" + chr(len(data)).encode('latin-1')
for i in data.encode('latin-1'):
a = key ^ i
key = a
result += bytes([a])
return result
def _decrypt(self, data):
key = 171
result = ""
for i in data:
a = key ^ i
key = i
result += bytes([a]).decode('latin-1')
return result
def _send_json_cmd(self, cmd):
ret = {}
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1.5)
sock.connect((Parameters["Address"], PORT))
data = self._encrypt(cmd)
sock.send(data)
data = sock.recv(1024)
Domoticz.Debug('data len: {}'.format(len(data)))
self.socket_error_suppress = False
except socket.error as e:
if self.socket_error_suppress == False:
Domoticz.Log('Send command error: {}'.format(str(e)))
if suppress_socket_error == True:
self.socket_error_suppress = True
# Switch is probably off/unavailable, so reflect this in Domoticz
Domoticz.Log("Switching Domoticz device off as hardware is not responding")
self.set_domoticz_state(STATES[2])
self.last_state = STATES[2]
sock.close()
return ret
try:
json_resp = self._decrypt(data[4:])
ret = json.loads(json_resp)
except (TypeError, JSONDecodeError) as e:
Domoticz.Log('Decode error: {}'.format(str(e)))
Domoticz.Log('Data: {}'.format(str(data)))
return ret
def update_emeter_values(self):
if "HS110" in Parameters["Mode1"]:
cmd = {
"emeter": {
"get_realtime": {}
}
}
result = self._send_json_cmd(json.dumps(cmd))
Domoticz.Debug("got response: {}".format(result))
if result != {}:
realtime_result = result.get('emeter', {}).get('get_realtime', {})
err_code = realtime_result.get('err_code', 1)
if err_code == 0:
if HS110_divider == 1000:
Devices[2].Update(nValue=0, sValue=str(round(realtime_result['current_ma'] / 1000,2)))
Devices[3].Update(nValue=0, sValue=str(round(realtime_result['voltage_mv'] / 1000,2)))
Devices[4].Update(nValue=0, sValue=str(round(realtime_result['power_mw'] / 1000,2)) + ";" + str(realtime_result['total_wh']))
else:
Devices[2].Update(nValue=0, sValue=str(round(realtime_result['current'],2)))
Devices[3].Update(nValue=0, sValue=str(round(realtime_result['voltage'],2)))
Devices[4].Update(nValue=0, sValue=str(round(realtime_result['power'],2)) + ";" + str(realtime_result['total']*1000))
def get_switch_state(self):
cmd = {
"system": {
"get_sysinfo": "null"
}
}
result = self._send_json_cmd(json.dumps(cmd))
Domoticz.Debug("Result: {}".format(str(result)))
err_code = result.get('system', {}).get('get_sysinfo', {}).get('err_code', 1)
if err_code == 0:
state = result['system']['get_sysinfo']['relay_state']
else:
state = 2
return STATES[state]
def set_domoticz_state(self, state):
if state in 'off':
Devices[1].Update(0, '0')
elif state in 'on':
Devices[1].Update(1, '100')
else:
Devices[1].Update(0, '50')
global _plugin
_plugin = TpLinkSmartPlugPlugin()
def onStart():
global _plugin
_plugin.onStart()
def onStop():
global _plugin
_plugin.onStop()
def onConnect(Connection, Status, Description):
global _plugin
_plugin.onConnect(Connection, Status, Description)
def onMessage(Connection, Data, Status, Extra):
global _plugin
_plugin.onMessage(Connection, Data, Status, Extra)
def onCommand(Unit, Command, Level, Hue):
global _plugin
_plugin.onCommand(Unit, Command, Level, Hue)
def onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile):
global _plugin
_plugin.onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile)
def onDisconnect(Connection):
global _plugin
_plugin.onDisconnect(Connection)
def onHeartbeat():
global _plugin
_plugin.onHeartbeat()
# Generic helper functions
def DumpConfigToLog():
for x in Parameters:
if Parameters[x] != "":
Domoticz.Debug("'{}:{}'".format(x, str(Parameters[x])))
Domoticz.Debug("Device count: {}".format(str(len(Devices))))
for x in Devices:
Domoticz.Debug("Device: {}-{}".format(str(x), str(Devices[x])))
Domoticz.Debug("Device ID: '{}".format(str(Devices[x].ID)))
Domoticz.Debug("Device Name: '{}".format(Devices[x].Name))
Domoticz.Debug("Device nValue: {}".format(str(Devices[x].nValue)))
Domoticz.Debug("Device sValue: '{}".format(Devices[x].sValue))
Domoticz.Debug("Device LastLevel: {}".format(str(Devices[x].LastLevel)))
return
The device is working good in kasa.
It is getting a fixed ip-adres from my dhcp.
the content of this plugin.py:
# Domoticz TP-Link Wi-Fi Smart Plug plugin
#
# Plugin based on reverse engineering of the TP-Link HS110, courtesy of Lubomir Stroetmann and Tobias Esser.
# https://www.softscheck.com/en/reverse-e ... ink-hs110/
#
# Original Author: Dan Hallgren
# Modified by: Andrew P
#
"""
<plugin key="tplinksmartplug" name="TP-Link Wi-Fi Smart Plug HS100/HS110/v2" version="0.2.6">
<description>
<h2>TP-Link Wi-Fi Smart Plug</h2>
<ul style="list-style-type:square">
<li>On/off switching (HS100 and HS110/HS110v2)</li>
<li>Realtime power, current and voltage (HS110/HS110v2 only)</li>
</ul>
<h3>Devices added to Domoticz:</h3>
<ul style="list-style-type:square">
<li>switch - On/Off (All models)</li>
<li>Realtime power in Watts (HS110/HS110v2)</li>
<li>Realtime current in Amps (HS110/HS110v2)</li>
<li>Realtime voltage in Volts (HS110/HS110v2)</li>
</ul>
</description>
<params>
<param field="Address" label="IP Address" width="200px" required="true"/>
<param field="Mode1" label="Model" width="150px" required="false">
<options>
<option label="HS100" value="HS100" default="true"/>
<option label="HS110/HS110v2" value="HS110" default="false" />
</options>
</param>
<param field="Mode2" label="Add devices? (Only required on install then can be turned off)" width="75px">
<options>
<option label="True" value="True"/>
<option label="False" value="False" default="true" />
</options>
</param>
<param field="Mode6" label="Debug" width="75px">
<options>
<option label="True" value="Debug"/>
<option label="False" value="Normal" default="true" />
</options>
</param>
</params>
</plugin>
"""
import json, socket, Domoticz
# Start user editable variables
base_url = "http://172.1.1.150:8080/" # Modify with your IP# or domain
interval = 1 # heartbeat in 10 second multiples
HS110_divider = 1000 # 1000 or 1 depending on your firmware version of HS110
suppress_socket_error = True # Suppress error messages in Domoticz after the first
# End user editable variables
PORT = 9999
STATES = ('off', 'on', 'unknown')
class TpLinkSmartPlugPlugin:
enabled = False
connection = None
def __init__(self):
self.interval = interval # *10 seconds
self.heartbeatcounter = 0
self.socket_error_suppress = suppress_socket_error
self.last_state = STATES[2]
self.state_flag = False
def onStart(self):
if Parameters["Mode6"] == "Debug":
Domoticz.Debugging(1)
DumpConfigToLog()
if len(Devices) == 0:
# Create a switch, suitable for all models
Domoticz.Device(Name="switch", Unit=1, TypeName="Switch", Used=1).Create()
Domoticz.Log("Tp-Link smart plug switch created")
if "HS110" in Parameters["Mode1"] and Parameters["Mode2"] == "True":
# Create measuring devices here
Domoticz.Device(Name="current (A)", Unit=2, Type=243, Subtype=23).Create()
Domoticz.Device(Name="voltage (V)", Unit=3, Type=243, Subtype=8).Create()
Domoticz.Device(Name="power (W)", Unit=4, Type=243, Subtype=29).Create() # Subtype 29 is kWh
Domoticz.Debug("Number of devices: {}".format(str(len(Devices))))
state = self.get_switch_state()
self.last_state = state
self.set_domoticz_state(state)
def onStop(self):
Domoticz.Debug("onStop called")
pass
def onConnect(self, Connection, Status, Description):
Domoticz.Debug("onConnect called")
pass
def onMessage(self, Connection, Data, Status, Extra):
Domoticz.Debug("onMessage called")
pass
def onCommand(self, unit, command, level, hue):
Domoticz.Debug("onCommand called for Unit {}: Parameter {}, Level {}".format(str(unit), str(command), str(level)))
if command.lower() == 'on':
new_state = 1
state = (1, '100')
else:
new_state = 0
state = (0, '0')
cmd = {
"system": {
"set_relay_state": {"state": new_state}
}
}
result = self._send_json_cmd(json.dumps(cmd))
Domoticz.Debug("got response: {}".format(result))
err_code = result.get('system', {}).get('set_relay_state', {}).get('err_code', 1)
if err_code == 0:
# Update Domoticz
Devices[1].Update(*state)
# Reset counter so we trigger emeter poll next heartbeat
self.heartbeatcounter = 0
def onNotification(self, Name, Subject, Text, Status, Priority, Sound, ImageFile):
Domoticz.Debug("Notification: {}, {}, {}, {}, {}, {}, {}".format(Name, Subject, Text, Status, str(Priority), Sound, ImageFile))
def onDisconnect(self, Connection):
Domoticz.Debug("onDisconnect called")
pass
def onHeartbeat(self):
if self.heartbeatcounter % self.interval == 0:
self.update_emeter_values()
state = self.get_switch_state()
Domoticz.Debug("Last state: {}, Switch state: {}, Domoticz device state: {}".format(self.last_state, state, STATES[Devices[1].nValue]))
if (self.last_state == STATES[2]) and (state != STATES[2]):
Domoticz.Log("Switch device is available, state is {}".format(state))
self.state_flag = False
if self.last_state != state:
self.last_state = state
if (state != STATES[2]) and (STATES[Devices[1].nValue] != state):
self.set_domoticz_state(state)
if (state == STATES[2]) and (self.state_flag == False): # device state unknown
self.set_domoticz_state(STATES[0]) # turn off Domoticz switch
Domoticz.Log("Switch device unavailable, Domoticz device switched off")
self.state_flag = True
self.heartbeatcounter += 1
def _encrypt(self, data):
key = 171
result = b"\x00\x00\x00" + chr(len(data)).encode('latin-1')
for i in data.encode('latin-1'):
a = key ^ i
key = a
result += bytes([a])
return result
def _decrypt(self, data):
key = 171
result = ""
for i in data:
a = key ^ i
key = i
result += bytes([a]).decode('latin-1')
return result
def _send_json_cmd(self, cmd):
ret = {}
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1.5)
sock.connect((Parameters["Address"], PORT))
data = self._encrypt(cmd)
sock.send(data)
data = sock.recv(1024)
Domoticz.Debug('data len: {}'.format(len(data)))
self.socket_error_suppress = False
except socket.error as e:
if self.socket_error_suppress == False:
Domoticz.Log('Send command error: {}'.format(str(e)))
if suppress_socket_error == True:
self.socket_error_suppress = True
# Switch is probably off/unavailable, so reflect this in Domoticz
Domoticz.Log("Switching Domoticz device off as hardware is not responding")
self.set_domoticz_state(STATES[2])
self.last_state = STATES[2]
sock.close()
return ret
try:
json_resp = self._decrypt(data[4:])
ret = json.loads(json_resp)
except (TypeError, JSONDecodeError) as e:
Domoticz.Log('Decode error: {}'.format(str(e)))
Domoticz.Log('Data: {}'.format(str(data)))
return ret
def update_emeter_values(self):
if "HS110" in Parameters["Mode1"]:
cmd = {
"emeter": {
"get_realtime": {}
}
}
result = self._send_json_cmd(json.dumps(cmd))
Domoticz.Debug("got response: {}".format(result))
if result != {}:
realtime_result = result.get('emeter', {}).get('get_realtime', {})
err_code = realtime_result.get('err_code', 1)
if err_code == 0:
if HS110_divider == 1000:
Devices[2].Update(nValue=0, sValue=str(round(realtime_result['current_ma'] / 1000,2)))
Devices[3].Update(nValue=0, sValue=str(round(realtime_result['voltage_mv'] / 1000,2)))
Devices[4].Update(nValue=0, sValue=str(round(realtime_result['power_mw'] / 1000,2)) + ";" + str(realtime_result['total_wh']))
else:
Devices[2].Update(nValue=0, sValue=str(round(realtime_result['current'],2)))
Devices[3].Update(nValue=0, sValue=str(round(realtime_result['voltage'],2)))
Devices[4].Update(nValue=0, sValue=str(round(realtime_result['power'],2)) + ";" + str(realtime_result['total']*1000))
def get_switch_state(self):
cmd = {
"system": {
"get_sysinfo": "null"
}
}
result = self._send_json_cmd(json.dumps(cmd))
Domoticz.Debug("Result: {}".format(str(result)))
err_code = result.get('system', {}).get('get_sysinfo', {}).get('err_code', 1)
if err_code == 0:
state = result['system']['get_sysinfo']['relay_state']
else:
state = 2
return STATES[state]
def set_domoticz_state(self, state):
if state in 'off':
Devices[1].Update(0, '0')
elif state in 'on':
Devices[1].Update(1, '100')
else:
Devices[1].Update(0, '50')
global _plugin
_plugin = TpLinkSmartPlugPlugin()
def onStart():
global _plugin
_plugin.onStart()
def onStop():
global _plugin
_plugin.onStop()
def onConnect(Connection, Status, Description):
global _plugin
_plugin.onConnect(Connection, Status, Description)
def onMessage(Connection, Data, Status, Extra):
global _plugin
_plugin.onMessage(Connection, Data, Status, Extra)
def onCommand(Unit, Command, Level, Hue):
global _plugin
_plugin.onCommand(Unit, Command, Level, Hue)
def onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile):
global _plugin
_plugin.onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile)
def onDisconnect(Connection):
global _plugin
_plugin.onDisconnect(Connection)
def onHeartbeat():
global _plugin
_plugin.onHeartbeat()
# Generic helper functions
def DumpConfigToLog():
for x in Parameters:
if Parameters[x] != "":
Domoticz.Debug("'{}:{}'".format(x, str(Parameters[x])))
Domoticz.Debug("Device count: {}".format(str(len(Devices))))
for x in Devices:
Domoticz.Debug("Device: {}-{}".format(str(x), str(Devices[x])))
Domoticz.Debug("Device ID: '{}".format(str(Devices[x].ID)))
Domoticz.Debug("Device Name: '{}".format(Devices[x].Name))
Domoticz.Debug("Device nValue: {}".format(str(Devices[x].nValue)))
Domoticz.Debug("Device sValue: '{}".format(Devices[x].sValue))
Domoticz.Debug("Device LastLevel: {}".format(str(Devices[x].LastLevel)))
return
-
- Posts: 49
- Joined: Thursday 31 March 2016 20:49
- Target OS: Raspberry Pi / ODroid
- Domoticz version: Beta
- Location: Netherlands
- Contact:
Re: TP-Link smart plug HS100/HS110
Hi Ricvee,
I just checked my file and I realized I have never modified it, and it works like a charm.
What happens if you vhange the file back to it's original state? (in my case: base_url = "http://rpi4:8080/" )
Kind regards,
Freek
I just checked my file and I realized I have never modified it, and it works like a charm.
What happens if you vhange the file back to it's original state? (in my case: base_url = "http://rpi4:8080/" )
Kind regards,
Freek
Pi3 Domoticz | RFXcom 433E | KAKU/COCO |Harmony Hub | Samsung TV | HS100 | HS110| HUE | Tradfri | Tado| Xiaomi |sensors | scripts| Pi3 Node Red | Pi2 SDS_011 + MH-Z19B | PiAware (zero) | Pi2 breadboard with Node red and Domoticz
-
- Posts: 32
- Joined: Wednesday 13 May 2015 9:05
- Target OS: Linux
- Domoticz version: Stable
- Location: Netherlands
- Contact:
Re: TP-Link smart plug HS100/HS110
Hi Freek,
I first installed the Plugin manager, according to this https://www.domoticz.com/wiki/Python_Plugin_Manager.
So I just have to put i in a subdir like ~/domoticz/plugins/HS100
I assume I have to make it executable with chmod +x ?
When I add the HS110 in setup\hardware. domoticz crashes and never comes back to live, even not after a sudo reboot.
When I delete the subdir /domoticz/plugins/HS110, delete the database, restart domoticz and restore a database it is working again,
bit offcourse without the HS110
Thanks,
Richard
I first installed the Plugin manager, according to this https://www.domoticz.com/wiki/Python_Plugin_Manager.
So I just have to put i in a subdir like ~/domoticz/plugins/HS100
I assume I have to make it executable with chmod +x ?
When I add the HS110 in setup\hardware. domoticz crashes and never comes back to live, even not after a sudo reboot.
When I delete the subdir /domoticz/plugins/HS110, delete the database, restart domoticz and restore a database it is working again,
bit offcourse without the HS110
Thanks,
Richard
-
- Posts: 49
- Joined: Thursday 31 March 2016 20:49
- Target OS: Raspberry Pi / ODroid
- Domoticz version: Beta
- Location: Netherlands
- Contact:
Re: TP-Link smart plug HS100/HS110
Hi Ricvee,
Try removing the domoticz-tplink-smartplug folder in the plugins directory, reboot and reinstall the TP-Link Wi-Fi Smart Plug HS100/HS110/v2 plugin via the plugin manager.
Then sudo chmod +x plugin.py and reboot
Here it works like a charm.
Keep me posted.
Freek
Try removing the domoticz-tplink-smartplug folder in the plugins directory, reboot and reinstall the TP-Link Wi-Fi Smart Plug HS100/HS110/v2 plugin via the plugin manager.
Then sudo chmod +x plugin.py and reboot
Here it works like a charm.
Keep me posted.
Freek
Pi3 Domoticz | RFXcom 433E | KAKU/COCO |Harmony Hub | Samsung TV | HS100 | HS110| HUE | Tradfri | Tado| Xiaomi |sensors | scripts| Pi3 Node Red | Pi2 SDS_011 + MH-Z19B | PiAware (zero) | Pi2 breadboard with Node red and Domoticz
-
- Posts: 32
- Joined: Wednesday 13 May 2015 9:05
- Target OS: Linux
- Domoticz version: Stable
- Location: Netherlands
- Contact:
Re: TP-Link smart plug HS100/HS110
Hi Freek,
I tried, but this is not possible.
I cannot install TP-link from within the PP-Manager, because it's not there in the list.
In the list ther are for example Sonos Players, Speedtest etc. but nothing that starts with a T
Are you able to install it, after that you deleted everything about TP-Link?
Thanks,
Richard
I tried, but this is not possible.
I cannot install TP-link from within the PP-Manager, because it's not there in the list.
In the list ther are for example Sonos Players, Speedtest etc. but nothing that starts with a T
Are you able to install it, after that you deleted everything about TP-Link?
Thanks,
Richard
Who is online
Users browsing this forum: No registered users and 1 guest