Not sure as you can leave the web page open and that updates itself as it goes

Moderator: leecollings
I can see the logic in the code but I still get the 0° blips so not sure how it's getting them.MikeF wrote:I guess you could do something like:Haven't tried it though.Code: Select all
if [ $temp != "0" ]; then domoTemp=$(curl -s "http://<DOMO IP:PORT>/json.htm?type=command¶m=udevice&nvalue=0&idx=<IDX>&svalue=${temp}") fi
Code: Select all
Traceback (most recent call last):
File "/home/pi/domoticz/scripts/hive2domo.py", line 70, in <module>
makeRequest(url,payload)
File "/home/pi/domoticz/scripts/hive2domo.py", line 41, in makeRequest
print e.code
AttributeError: 'URLError' object has no attribute 'code'
I must have some kind of bash config problem. Added the configs into it and now have:
Code: Select all
-bash: $'\nPython script to send data from Hive to Domoticz.\n\nReplace XXXs with your values.\n': command not found
-bash: import: command not found
-bash: import: command not found
-bash: insideIdx: command not found
-bash: targetIdx: command not found
-bash: thermIdx: command not found
-bash: heatingIdx: command not found
-bash: DomoReadURL: command not found
-bash: DomoWriteURL: command not found
-bash: DomoSwitchURL: command not found
-bash: hive.bash: line 25: syntax error near unexpected token `def'
-bash: hive.bash: line 25: `def domoticzread(idx, var):''
Code: Select all
Traceback (most recent call last):
File "./hive.sh", line 58, in <module>
temp = r.json()["nodes"][2]["attributes"]["temperature"]["reportedValue"]
KeyError: 'temperature'
Code: Select all
Traceback (most recent call last):
File "./hive.sh", line 71, in <module>
last_temp = domoticzread(insideIdx, 'Temp')
File "./hive.sh", line 28, in domoticzread
jsonData = json.loads(response.text)
File "/usr/lib/python2.7/json/__init__.py", line 339, in loads
return _default_decoder.decode(s)
File "/usr/lib/python2.7/json/decoder.py", line 364, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
Setup as described, in fact i removed the dummy device and set it up from scratch.MikeF wrote: ↑Tuesday 14 November 2017 19:59 I think the problem here may be that you have not set up dummy devices in Domoticz to receive the values from this script - see lines 13 to 16. The first two are temperature devices, the third is a thermostat / setpoint, and the last is an on/off switch. (I may have mentioned this originally - it was a while ago when I first published this script.)
Code: Select all
"targetHeatTemperature": {
"targetExpiryTime": 1510697424984,
"reportReceivedTime": 1510698605897,
"propertyStatus": "COMPLETE",
"targetSetTXId": "e56e60fa-0d45-4c52-9f76-7029377109ae",
"reportedValue": 11.5,
"targetSetTime": 1510697124984,
"displayValue": 11.5,
"targetValue": 11.5,
"reportChangedTime": 1510697125488
},
"minHeatTemperature": {
"displayValue": 5.0,
"reportReceivedTime": 1510698605897,
"reportChangedTime": 1508372857836,
"reportedValue": 5.0
},
"holidayMode": {
"displayValue": {
"targetHeatTemperature": 1.0
},
"reportReceivedTime": 1510698605897,
"reportChangedTime": 1509790193862,
"reportedValue": {
"targetHeatTemperature": 1.0
}
},
"failureStatus": {
"displayValue": "NORMAL",
"reportReceivedTime": 1510698605897,
"reportChangedTime": 1509633035417,
"reportedValue": "NORMAL"
},
"nodeType": {
"displayValue": "http://alertme.com/schema/json/node.class.thermostat.json#",
"reportReceivedTime": 1510699203908,
"reportChangedTime": 1508372853584,
"reportedValue": "http://alertme.com/schema/json/node.class.thermostat.json#"
},
"activeScheduleLock": {
"targetExpiryTime": 1510605381449,
"reportReceivedTime": 1510698605897,
"propertyStatus": "COMPLETE",
"targetSetTXId": "7cbb4270-0380-4963-b7ed-2fdef9de06ea",
"reportedValue": true,
"targetSetTime": 1510605081449,
"displayValue": true,
"targetValue": true,
"reportChangedTime": 1510656121698
},
"activeHeatCoolMode": {
"targetExpiryTime": 1510605381449,
"reportReceivedTime": 1510698605897,
"propertyStatus": "COMPLETE",
"targetSetTXId": "7cbb4270-0380-4963-b7ed-2fdef9de06ea",
"reportedValue": "HEAT",
"targetSetTime": 1510605081449,
"displayValue": "HEAT",
"targetValue": "BOOST",
"reportChangedTime": 1510608681517
},
"frostProtectTemperature": {
"displayValue": 7.0,
"reportReceivedTime": 1510698605897,
"reportChangedTime": 1508372857836,
"reportedValue": 7.0
}
Code: Select all
#!/usr/bin/env python
'''
Python script to send data from Hive to Domoticz.
Replace XXX's with your values.
'''
import requests
import json
import sys
# Replace with your Domoticz idx's
domoHost = 'XXX'
domoPort = 'XXX'
insideIdx = 'XXX'
targetIdx = 'XXX'
thermIdx = 'XXX'
heatingIdx = 'XXX'
# Replace with your Hive credentials
hiveUser = 'XXX'
hivePass = 'XXX'
# Domoticz URL & port
DomoReadURL = 'http://'+domoHost+':'+domoPort+'/json.htm?type=devices&rid='
DomoWriteURL = 'http://'+domoHost+':'+domoPort+'/json.htm?type=command¶m=udevice&nvalue=0&idx='
DomoSwitchURL = 'http://'+domoHost+':'+domoPort+'/json.htm?type=command¶m=switchlight&idx='
requests.packages.urllib3.disable_warnings()
def domoticzread(idx, var):
url = DomoReadURL + idx
response = requests.get(url)
jsonData = json.loads(response.text)
result = jsonData['result'][0][var]
return result;
def find_key_in_list(d, value):
if isinstance(d, list):
t = list(d)
for v in d:
if isinstance(v, dict):
p = find_key(v, value)
if not p:
t.remove(v)
return t
def find_key(d, value):
for k,v in d.items():
if isinstance(v, dict):
p = find_key(v, value)
if p:
return [k] + p
elif v == value:
return [k]
# Hive
# log on to Hive
payload = {'username':hiveUser, 'password':hivePass}
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
url = 'https://beekeeper-uk.hivehome.com/1.0/gateway/login'
r = requests.post(url, headers=headers, data=json.dumps(payload), verify=False)
sessionId = r.json()["token"]
headers = {'Content-Type': 'application/vnd.alertme.zoo-6.2+json', 'Accept': 'application/vnd.alertme.zoo-6.2+json', \
'X-AlertMe-Client': 'swagger', 'X-Omnia-Access-Token': sessionId}
url = 'https://api.prod.bgchprod.info:443/omnia/nodes'
r = requests.get(url, headers=headers, verify=False)
# Find thermostat node
d = r.json()["nodes"]
x = find_key_in_list(d,"http://alertme.com/schema/json/node.class.thermostat.json#")
if x:
if x[0]["id"] == x[1]["parentNodeId"]:
thermostat = x[1]
elif x[1]["id"] == x[0]["parentNodeId"]:
thermostat = x[0]
else:
print("No thermostat found")
thermostat = False
# get values from Hive
if thermostat:
temp = thermostat["attributes"]["temperature"]["reportedValue"]
targetTemp = thermostat["attributes"]["targetHeatTemperature"]["reportedValue"]
heating = thermostat["attributes"]["stateHeatingRelay"]["reportedValue"]
# log out from Hive
headers = {'Content-Type': 'application/vnd.alertme.zoo-6.1+json', 'Accept': 'application/vnd.alertme.zoo-6.2+json', \
'X-AlertMe-Client': 'Hive Web Dashboard', 'X-Omnia-Access-Token': sessionId}
url = 'https://api.prod.bgchprod.info:443/omnia/auth/sessions/' + sessionId
r = requests.delete(url, headers=headers, verify=False)
if not thermostat:
sys.exit() # Quit if there is no thermostat found
# Domoticz
# get last values from Domoticz
last_temp = domoticzread(insideIdx, 'Temp')
last_target = domoticzread(targetIdx, 'Temp')
last_heating = domoticzread(heatingIdx, 'Status')
# change some values
temp = round(temp, 1)
if targetTemp < 7.0: targetTemp = 7.0
if heating == "ON":
heating="On"
else:
heating="Off"
print 'new','old'
print temp, last_temp
print targetTemp, last_target
print heating, last_heating
# send values to Domoticz (only send some if changed)
url = DomoWriteURL + insideIdx + '&svalue=' + str(temp)
r = requests.get(url)
url = DomoWriteURL + targetIdx + '&svalue=' + str(targetTemp)
r = requests.get(url)
if targetTemp != last_target:
url = DomoWriteURL + thermIdx + '&svalue=' + str(targetTemp)
r = requests.get(url)
if heating != last_heating:
url = DomoSwitchURL + heatingIdx + '&switchcmd=' + heating
r = requests.get(url)
Code: Select all
if x[0]["id"] == x[1]["parentNodeId"]:
thermostat = x[1]
elif x[1]["id"] == x[0]["parentNodeId"]:
thermostat = x[0]
Code: Select all
#!/usr/bin/env python
'''
Python script to send data from Hive to Domoticz.
Replace XXX's with your values.
'''
import requests
import json
import sys
# Replace with your Domoticz idx's
domoHost = 'XXX'
domoPort = 'XXX'
insideIdx = 'XXX'
targetIdx = 'XXX'
thermIdx = 'XXX'
heatingIdx = 'XXX'
# Dictionary of on/off light names and idx's don't include dimmers
lights = {}
# Dictionary of dimmable light names and idx's
# e.g. dimmers = {"Bedroom":5,"Porch":6,"Stairwell":7}
dimmers = {}
# Replace with your Hive credentials
hiveUser = 'XXX'
hivePass = 'XXX'
# Domoticz URL & port
DomoReadURL = 'http://'+domoHost+':'+domoPort+'/json.htm?type=devices&rid='
DomoWriteURL = 'http://'+domoHost+':'+domoPort+'/json.htm?type=command¶m=udevice&nvalue=0&idx='
DomoSwitchURL = 'http://'+domoHost+':'+domoPort+'/json.htm?type=command¶m=switchlight&idx='
requests.packages.urllib3.disable_warnings()
def domoticzread(idx, var):
url = DomoReadURL + idx
response = requests.get(url)
jsonData = json.loads(response.text)
result = jsonData['result'][0][var]
return result;
def find_key_in_list(d, value):
if isinstance(d, list):
t = list(d)
for v in d:
if isinstance(v, dict):
p = find_key(v, value)
if not p:
t.remove(v)
return t
def find_key(d, value):
for k,v in d.items():
if isinstance(v, dict):
p = find_key(v, value)
if p:
return [k] + p
elif v == value:
return [k]
def merge_dicts(*dict_args):
"""
Given any number of dicts, shallow copy and merge into a new dict,
precedence goes to key value pairs in latter dicts.
"""
result = {}
for dictionary in dict_args:
result.update(dictionary)
return result
# Hive
# log on to Hive
payload = {'username':hiveUser, 'password':hivePass}
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
url = 'https://beekeeper-uk.hivehome.com/1.0/gateway/login'
r = requests.post(url, headers=headers, data=json.dumps(payload), verify=False)
sessionId = r.json()["token"]
headers = {'Content-Type': 'application/vnd.alertme.zoo-6.2+json', 'Accept': 'application/vnd.alertme.zoo-6.2+json', \
'X-AlertMe-Client': 'swagger', 'X-Omnia-Access-Token': sessionId}
url = 'https://api.prod.bgchprod.info:443/omnia/nodes'
r = requests.get(url, headers=headers, verify=False)
# Find thermostat node
d = r.json()["nodes"]
x = find_key_in_list(d,"http://alertme.com/schema/json/node.class.thermostat.json#")
if x:
if x[0]["id"] == x[1]["parentNodeId"]:
thermostat = x[1]
elif x[1]["id"] == x[0]["parentNodeId"]:
thermostat = x[0]
else:
print("No thermostat found")
thermostat = False
# get values from Hive
if thermostat:
temp = thermostat["attributes"]["temperature"]["reportedValue"]
targetTemp = thermostat["attributes"]["targetHeatTemperature"]["reportedValue"]
heating = thermostat["attributes"]["stateHeatingRelay"]["reportedValue"]
x = find_key_in_list(d,"http://alertme.com/schema/json/node.class.thermostatui.json#")
if x:
battery = x[0]["attributes"]["batteryLevel"]["reportedValue"]
rawRssi = 0-x[0]["attributes"]["RSSI"]["reportedValue"]
rssi = 12*rawRssi/100
state = {}
brightness = {}
x = find_key_in_list(d,"http://alertme.com/schema/json/node.class.light.json#")
if x:
for l in x:
# On/Off
try:
idx = merge_dicts(lights, dimmers)[l["name"]]
except:
idx = False
if idx:
state[idx] = "O" + l["attributes"]["state"]["reportedValue"][1:3].lower()
# Brightness
try:
idx = dimmers[l["name"]]
except:
idx = False
if idx:
if state[idx] == "Off":
brightness[idx] = 0
else:
brightness[idx] = l["attributes"]["brightness"]["reportedValue"]
else:
print("No lights found")
# log out from Hive
headers = {'Content-Type': 'application/vnd.alertme.zoo-6.1+json', 'Accept': 'application/vnd.alertme.zoo-6.2+json', \
'X-AlertMe-Client': 'Hive Web Dashboard', 'X-Omnia-Access-Token': sessionId}
url = 'https://api.prod.bgchprod.info:443/omnia/auth/sessions/' + sessionId
r = requests.delete(url, headers=headers, verify=False)
if not thermostat:
sys.exit() # Quit if there is no thermostat found
#sys.exit()
# Domoticz
# get last values from Domoticz
last_temp = domoticzread(insideIdx, 'Temp')
last_target = domoticzread(targetIdx, 'Temp')
last_heating = domoticzread(heatingIdx, 'Status')
# change some values
temp = round(temp, 1)
if targetTemp < 7.0: targetTemp = 7.0
if heating == "ON":
heating="On"
else:
heating="Off"
print 'new','old'
print temp, last_temp
print targetTemp, last_target
print heating, last_heating
print 'battery: ' + str(battery)
print 'rssi: ' + str(rssi)
print state
print brightness
# send values to Domoticz (only send some if changed)
url = DomoWriteURL + insideIdx + '&svalue=' + str(temp)
r = requests.get(url)
url = DomoWriteURL + targetIdx + '&svalue=' + str(targetTemp)
r = requests.get(url)
if targetTemp != last_target:
url = DomoWriteURL + thermIdx + '&svalue=' + str(targetTemp) + '&battery=' + str(battery) + '&rssi=' + str(rssi)
print url
r = requests.get(url)
if heating != last_heating:
url = DomoSwitchURL + heatingIdx + '&switchcmd=' + heating
r = requests.get(url)
for k,v in brightness.items():
url = DomoSwitchURL + str(k) + '&switchcmd=Set%20Level&level=' + str(v)
r = requests.get(url)
for k,v in state.items():
url = DomoSwitchURL + str(k) + '&switchcmd=' + v
r = requests.get(url)
Code: Select all
if x:
y = x[0]["attributes"]
z = x[1]["attributes"]
k = "stateHeatingRelay"
if k in y:
thermostat = y
elif k in z:
thermostat = z
else:
thermostat = False
In my system, these can be found under ["nodes"][1] - where "name" = "Hive2".
Code: Select all
x = find_key_in_list(d,"Hive2")
if x:
print x[0]["attributes"]["batteryVoltage"]["reportedValue"]
print x[0]["attributes"]["RSSI"]["reportedValue"]
Code: Select all
'''
<plugin key="HivePlug" name="Hive Plugin" author="imcfarla and mikef" version="0.1" wikilink="http://www.domoticz.com/wiki/plugins/plugin.html" externallink="https://www.google.com/">
<params>
<param field="Username" label="Hive Username" width="200px" required="true" default=""/>
<param field="Password" label="Hive Password" width="200px" required="true" default=""/>
<param field="Mode1" label="Heartbeat Multiplier" width="30px" required="true" default="6"/>
<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 Domoticz
import sys
import json
sys.path.append('/usr/lib/python3/dist-packages')
from urllib.request import Request, urlopen
from urllib.parse import urlencode
def find_key_in_list(d, value):
if isinstance(d, list):
t = list(d)
for v in d:
if isinstance(v, dict):
p = find_key(v, value)
if not p:
t.remove(v)
return t
def find_key(d, value):
for (k, v) in d.items():
if isinstance(v, dict):
p = find_key(v, value)
if p:
return [k] + p
elif v == value:
return [k]
def merge_dicts(*dict_args):
'''
Given any number of dicts, shallow copy and merge into a new dict,
precedence goes to key value pairs in latter dicts.
'''
result = { }
for dictionary in dict_args:
result.update(dictionary)
return result
class BasePlugin:
enabled = False
def __init__(self):
self.sessionId = ''
self.counter = 0
self.multiplier = 10
def onStart(self):
Domoticz.Log('Staring')
if Parameters["Mode6"] == "Debug":
Domoticz.Debugging(1)
self.multiplier = int(Parameters['Mode1'])
self.counter = self.multiplier #update immediately
if self.sessionId == '':
Domoticz.Debug('Creating Session')
payload = {'username':Parameters["Username"], 'password':Parameters["Password"]}
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
url = 'https://beekeeper-uk.hivehome.com/1.0/gateway/login'
print(urlencode(payload).encode('ascii'))
req = Request(url, data = json.dumps(payload).encode('ascii'), headers = headers, unverifiable = True)
r = urlopen(req).read().decode('utf-8')
self.sessionId = json.loads(r)['token']
Domoticz.Debug(self.sessionId)
d = self.GetDevices()
thermostat = self.GetThermostat(d)
if len(Devices) == 0:
Domoticz.Log('Creating Devices')
if thermostat:
Domoticz.Device(Name = 'Thermostat', Unit = 1, Type = 242, Subtype = 1, DeviceID = thermostat['id']).Create()
Domoticz.Device(Name = 'Heating', Unit = 2, TypeName = 'Switch', Switchtype = 0, DeviceID ='Hive_Heating').Create()
Domoticz.Device(Name = 'Inside', Unit = 3, TypeName = 'Temperature', DeviceID = 'Hive_Inside').Create()
Domoticz.Device(Name = 'Target', Unit = 6, TypeName = 'Temperature', DeviceID = 'Hive_Target').Create()
else:
Domoticz.Log(str(len(Devices)) + ' Devices')
for unit in Devices:
Domoticz.Debug(Devices[unit].Name)
def onStop(self):
Domoticz.Log('Stop')
headers = {'Content-Type': 'application/vnd.alertme.zoo-6.1+json', 'Accept': 'application/vnd.alertme.zoo-6.2+json', \
'X-AlertMe-Client': 'Hive Web Dashboard', 'X-Omnia-Access-Token': self.sessionId }
url = 'https://api.prod.bgchprod.info:443/omnia/auth/sessions/' + self.sessionId
req = Request(url, headers = headers)
req.get_method = lambda : 'PUT'
try:
r = urlopen(req).read()
except Exception as e:
Domoticz.Debug(str(e))
def onConnect(self, Connection, Status, Description):
Domoticz.Debug('onConnect called')
def onMessage(self, Connection, Data, Status, Extra):
Domoticz.Debug('onMessage called')
def onCommand(self, Unit, Command, Level, Hue):
Domoticz.Debug('onCommand called for Unit ' + str(Unit) + ": Parameter '" + str(Command) + "', Level: " + str(Level))
def onNotification(self, Name, Subject, Text, Status, Priority, Sound, ImageFile):
Domoticz.Debug('Notification: ' + Name + ',' + Subject + ',' + Text + ',' + Status + ',' + str(Priority) + ',' + Sound + ',' + ImageFile)
def onDisconnect(self, Connection):
Domoticz.Debug('onDisconnect called')
def onHeartbeat(self):
Domoticz.Debug('onHeartbeat called')
if self.counter >= self.multiplier:
Domoticz.Log('Getting Data')
self.counter = 0
d = self.GetDevices()
Domoticz.Debug('Getting Temperatures')
thermostat = self.GetThermostat(d)
# get the temperature and heating states
temp = thermostat["attributes"]["temperature"]["reportedValue"]
Domoticz.Debug('Temp = ' + str(temp))
targetTemp = thermostat["attributes"]["targetHeatTemperature"]["reportedValue"]
if targetTemp < 7.0: targetTemp = 7.0
Domoticz.Debug('Target = ' + str(targetTemp))
heating = thermostat["attributes"]["stateHeatingRelay"]["reportedValue"]
Domoticz.Debug('Heating = ' + heating)
Domoticz.Debug('Getting Battery Status')
thermostatui = self.GetThermostatUI(d)
# get the battery and rssi values
thermostat_battery = thermostatui["attributes"]["batteryLevel"]["reportedValue"]
Domoticz.Debug('Battery = ' + str(thermostat_battery))
thermostat_rssi = 12*((0 - thermostatui["attributes"]["RSSI"]["reportedValue"])/100)
Domoticz.Debug('RSSI = ' + str(thermostat_rssi))
# Loop through the devices and update temperatures
Domoticz.Debug('Updating Devices')
for unit in Devices:
if Devices[unit].DeviceID == "Hive_Inside":
Devices[unit].Update(nValue=int(temp), sValue=str(temp))
if Devices[unit].DeviceID == "Hive_Target":
Devices[unit].Update(nValue=int(targetTemp), sValue=str(targetTemp))
if Devices[unit].DeviceID == "Hive_Heating":
if heating == 'ON':
if Devices[unit].nValue == 0:
Devices[unit].Update(nValue=1, sValue='On')
else:
if Devices[unit].nValue == 1:
Devices[unit].Update(nValue=0, sValue='Off')
# Loop through the devices from Hive and update statuses where appropriate
Domoticz.Debug('Checking Nodes')
for node in d:
#Domoticz.Debug('Node = ' + node['id'])
for unit in Devices.keys():
#Domoticz.Debug('Unit ' + str(unit))
#Domoticz.Debug('Device ' + Devices[unit].DeviceID)
if node['id'] == Devices[unit].DeviceID:
Domoticz.Debug('Found ' + Devices[unit].Name)
if Devices[unit].Type == 242: #Thermostat
Devices[unit].Update(nValue = int(targetTemp), sValue = str(targetTemp), BatteryLevel = int(thermostat_battery), SignalLevel = int(thermostat_rssi))
else:
self.counter += 1
Domoticz.Debug('Counter = ' + str(self.counter))
def GetDevices(self):
headers = {'Content-Type': 'application/vnd.alertme.zoo-6.2+json', 'Accept': 'application/vnd.alertme.zoo-6.2+json', \
'X-AlertMe-Client': 'swagger', 'X-Omnia-Access-Token': self.sessionId}
url = 'https://api.prod.bgchprod.info:443/omnia/nodes'
req = Request(url, headers = headers, unverifiable = True)
try:
r = urlopen(req).read().decode('utf-8')
except Exception:
print('Exception')
return json.loads(r)['nodes']
def GetThermostat(self, d):
x = find_key_in_list(d, 'http://alertme.com/schema/json/node.class.thermostat.json#')
if x:
k = 'stateHeatingRelay'
if k in x[0]['attributes']:
thermostat = x[0]
elif k in x[1]['attributes']:
thermostat = x[1]
else:
thermostat = False
else:
thermostat = False
return thermostat
def GetThermostatUI(self, d):
thermostatui = False
x = find_key_in_list(d, 'http://alertme.com/schema/json/node.class.thermostatui.json#')
if x:
thermostatui = x[0]
else: # Try a Hive2 thermostat
x = find_key_in_list(d,"Hive2")
if x:
thermostatui = x[0]
return thermostatui
_plugin = BasePlugin()
def onStart():
_plugin.onStart()
def onStop():
_plugin.onStop()
def onConnect(Connection, Status, Description):
_plugin.onConnect(Connection, Status, Description)
def onMessage(Connection, Data, Status, Extra):
_plugin.onMessage(Connection, Data, Status, Extra)
def onCommand(Unit, Command, Level, Hue):
_plugin.onCommand(Unit, Command, Level, Hue)
def onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile):
_plugin.onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile)
def onDisconnect(Connection):
_plugin.onDisconnect(Connection)
def onHeartbeat():
_plugin.onHeartbeat()
def DumpConfigToLog():
for x in Parameters:
if Parameters[x] != '':
Domoticz.Debug("'" + x + "':'" + str(Parameters[x]) + "'")
Domoticz.Debug('Device count: ' + str(len(Devices)))
for x in Devices:
Domoticz.Debug('Device: ' + str(x) + ' - ' + str(Devices[x]))
Domoticz.Debug("Device ID: '" + str(Devices[x].ID) + "'")
Domoticz.Debug("Device Name: '" + Devices[x].Name + "'")
Domoticz.Debug('Device nValue: ' + str(Devices[x].nValue))
Domoticz.Debug("Device sValue: '" + Devices[x].sValue + "'")
Domoticz.Debug('Device LastLevel: ' + str(Devices[x].LastLevel))
Code: Select all
'''
<plugin key="HivePlug" name="Hive Plugin" author="imcfarla and mikef" version="0.2" wikilink="http://www.domoticz.com/wiki/plugins/plugin.html" externallink="https://www.google.com/">
<params>
<param field="Username" label="Hive Username" width="200px" required="true" default=""/>
<param field="Password" label="Hive Password" width="200px" required="true" default=""/>
<param field="Mode1" label="Heartbeat Multiplier" width="30px" required="true" default="1"/>
<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 Domoticz
import sys
import json
sys.path.append('/usr/lib/python3/dist-packages')
from urllib.request import Request, urlopen
from urllib.parse import urlencode
def find_key_in_list(d, value):
if isinstance(d, list):
t = list(d)
for v in d:
if isinstance(v, dict):
p = find_key(v, value)
if not p:
t.remove(v)
return t
def find_key(d, value):
for (k, v) in d.items():
if isinstance(v, dict):
p = find_key(v, value)
if p:
return [k] + p
elif v == value:
return [k]
def merge_dicts(*dict_args):
'''
Given any number of dicts, shallow copy and merge into a new dict,
precedence goes to key value pairs in latter dicts.
'''
result = { }
for dictionary in dict_args:
result.update(dictionary)
return result
class BasePlugin:
enabled = False
def __init__(self):
self.sessionId = ''
self.counter = 0
self.multiplier = 10
self.lightsSet = set()
def onStart(self):
Domoticz.Log('Starting')
if Parameters["Mode6"] == "Debug":
Domoticz.Debugging(1)
self.multiplier = int(Parameters['Mode1'])
self.counter = self.multiplier #update immediately
if self.sessionId == '':
Domoticz.Log('Creating Session')
payload = {'username':Parameters["Username"], 'password':Parameters["Password"]}
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
url = 'https://beekeeper-uk.hivehome.com/1.0/gateway/login'
req = Request(url, data = json.dumps(payload).encode('ascii'), headers = headers, unverifiable = True)
r = urlopen(req).read().decode('utf-8')
self.sessionId = json.loads(r)['token']
Domoticz.Debug(self.sessionId)
def onStop(self):
Domoticz.Log('Deleting Session')
headers = {'Content-Type': 'application/vnd.alertme.zoo-6.1+json', 'Accept': 'application/vnd.alertme.zoo-6.2+json', \
'X-AlertMe-Client': 'Hive Web Dashboard', 'X-Omnia-Access-Token': self.sessionId }
url = 'https://api.prod.bgchprod.info:443/omnia/auth/sessions/' + self.sessionId
req = Request(url, headers = headers)
req.get_method = lambda : 'DELETE'
try:
r = urlopen(req).read()
except Exception as e:
Domoticz.Log(str(e))
def onConnect(self, Connection, Status, Description):
Domoticz.Debug('onConnect called')
def onMessage(self, Connection, Data, Status, Extra):
Domoticz.Debug('onMessage called')
def onCommand(self, Unit, Command, Level, Hue):
Domoticz.Log('onCommand called for Unit ' + str(Unit) + ": Parameter '" + str(Command) + "', Level: " + str(Level))
Domoticz.Debug(str(Devices[Unit].Type))
Domoticz.Debug(str(Devices[Unit].SubType))
Domoticz.Debug(Devices[Unit].DeviceID)
Domoticz.Debug(str(Devices[Unit].sValue))
headers = {'Content-Type': 'application/vnd.alertme.zoo-6.2+json', 'Accept': 'application/vnd.alertme.zoo-6.2+json', \
'X-AlertMe-Client': 'swagger', 'X-Omnia-Access-Token': self.sessionId}
url = 'https://api.prod.bgchprod.info:443/omnia/nodes/' + Devices[Unit].DeviceID
if self.isLight(Unit):
Domoticz.Log("Setting Light Parameters")
if str(Command) == "Set Level":
payload = self.CreateLightPayload("ON", Level)
if str(Command) == "On":
payload = self.CreateLightPayload("ON", Devices[Unit].LastLevel)
if str(Command) == "Off":
payload = self.CreateLightPayload("OFF", Devices[Unit].LastLevel)
elif self.isThermostat(Unit):
payload = self.CreateThermostatPayload(Level)
elif self.isActivePlug(Unit):
payload = self.CreateActivePlugPayload(Level)
else:
payload = ""
Domoticz.Log("Unknown Device Type")
if payload != "":
req = Request(url, data = json.dumps(payload).encode('ascii'), headers = headers, unverifiable = True)
req.get_method = lambda : 'PUT'
try:
r = urlopen(req).read().decode('utf-8')
except Exception as e:
Domoticz.Log(str(e))
def onNotification(self, Name, Subject, Text, Status, Priority, Sound, ImageFile):
Domoticz.Debug('Notification: ' + Name + ',' + Subject + ',' + Text + ',' + Status + ',' + str(Priority) + ',' + Sound + ',' + ImageFile)
def onDisconnect(self, Connection):
Domoticz.Debug('onDisconnect called')
def onHeartbeat(self):
Domoticz.Debug('onHeartbeat called')
if self.counter >= self.multiplier:
foundInsideDevice = False
foundTargetDevice = False
foundHeatingDevice = False
foundThermostatDevice = False
Domoticz.Debug('Getting Data')
self.counter = 1
d = self.GetDevices()
Domoticz.Debug('Getting Temperatures')
thermostat = self.GetThermostat(d)
if thermostat:
# get the temperature and heating states
temp = thermostat["attributes"]["temperature"]["reportedValue"]
Domoticz.Debug('Temp = ' + str(temp))
targetTemp = thermostat["attributes"]["targetHeatTemperature"]["reportedValue"]
if targetTemp < 7.0: targetTemp = 7.0
Domoticz.Debug('Target = ' + str(targetTemp))
heating = thermostat["attributes"]["stateHeatingRelay"]["reportedValue"]
Domoticz.Debug('Heating = ' + heating)
Domoticz.Debug('Getting Battery Status')
thermostatui = self.GetThermostatUI(d)
# get the battery and rssi values
thermostat_battery = thermostatui["attributes"]["batteryLevel"]["reportedValue"]
Domoticz.Debug('Battery = ' + str(thermostat_battery))
thermostat_rssi = 12*((0 - thermostatui["attributes"]["RSSI"]["reportedValue"])/100)
Domoticz.Debug('RSSI = ' + str(thermostat_rssi))
# Loop through the devices and update temperatures
Domoticz.Debug('Updating Devices')
for unit in Devices:
if Devices[unit].DeviceID == "Hive_Inside":
Devices[unit].Update(nValue=int(temp), sValue=str(temp))
foundInsideDevice = True
if Devices[unit].DeviceID == "Hive_Target":
Devices[unit].Update(nValue=int(targetTemp), sValue=str(targetTemp))
foundTargetDevice = True
if Devices[unit].DeviceID == "Hive_Heating":
foundHeatingDevice = True
if heating == 'ON':
if Devices[unit].nValue == 0:
Devices[unit].Update(nValue=1, sValue='On')
else:
if Devices[unit].nValue == 1:
Devices[unit].Update(nValue=0, sValue='Off')
if Devices[unit].DeviceID == thermostat['id']:
foundThermostatDevice = True
if Devices[unit].Type == 242: #Thermostat
Devices[unit].Update(nValue = int(targetTemp), sValue = str(targetTemp), BatteryLevel = int(thermostat_battery), SignalLevel = int(thermostat_rssi))
if foundInsideDevice == False:
Domoticz.Device(Name = 'Inside', Unit = self.GetNextUnit(False), TypeName = 'Temperature', DeviceID = 'Hive_Inside').Create()
self.counter = self.multiplier
if foundTargetDevice == False:
Domoticz.Device(Name = 'Target', Unit = self.GetNextUnit(False), TypeName = 'Temperature', DeviceID = 'Hive_Target').Create()
self.counter = self.multiplier
if foundHeatingDevice == False:
Domoticz.Device(Name = 'Heating', Unit = self.GetNextUnit(False), TypeName = 'Switch', Switchtype = 0, DeviceID ='Hive_Heating').Create()
self.counter = self.multiplier
if foundThermostatDevice == False:
Domoticz.Device(Name = 'Thermostat', Unit = self.GetNextUnit(False), Type = 242, Subtype = 1, DeviceID = thermostat['id']).Create()
self.counter = self.multiplier
lights = self.GetLights(d)
if lights:
for node in lights:
for unit in Devices:
if node['id'] == Devices[unit].DeviceID:
if unit not in set(self.lightsSet):
self.lightsSet.add(unit)
if node["attributes"]["state"]["reportedValue"] == "OFF":
if Devices[unit].nValue != 0:
Devices[unit].Update(nValue=0, sValue='Off')
else:
Domoticz.Debug("State: " + Devices[unit].sValue)
Domoticz.Debug("Brightness Target: " + str(Devices[unit].LastLevel))
Domoticz.Debug("Brightness: " + str(node["attributes"]["brightness"]["reportedValue"]))
if Devices[unit].LastLevel != int(node["attributes"]["brightness"]["reportedValue"]) or Devices[unit].sValue == 'Off':
Devices[unit].Update(nValue=2, sValue=str(node["attributes"]["brightness"]["reportedValue"])) # 2 = Set Level
break
else:
Domoticz.Log("Light not found " + node["name"])
newUnit = self.GetNextUnit(False)
Domoticz.Device(Name = node["name"], Unit = newUnit, Type=244, Subtype=73, Switchtype=7, DeviceID = node['id']).Create()
if node["attributes"]["state"]["reportedValue"] == "OFF":
Devices[newUnit].Update(nValue=0, sValue='Off')
else:
Devices[newUnit].Update(nValue=2, sValue=str(node["attributes"]["brightness"]["reportedValue"])) # 2 = Set Level
activeplugs = self.GetActivePlugs(d)
if activeplugs:
for node in activeplugs:
for unit in Devices:
if node['id'] == Devices[unit].DeviceID:
if node["attributes"]["state"]["reportedValue"] == "OFF":
if Devices[unit].nValue != 0:
Devices[unit].Update(nValue=0, sValue='Off')
else:
Domoticz.Debug("State: " + Devices[unit].sValue)
if Devices[unit].nValue != 1:
Devices[unit].Update(nValue=1, sValue='On')
break
else:
Domoticz.Log("ActivePlug not found " + node["name"])
newUnit = self.GetNextUnit(False)
Domoticz.Device(Name = node["name"], Unit = newUnit, Type=244, Subtype=73, Switchtype=0, DeviceID = node['id']).Create()
if node["attributes"]["state"]["reportedValue"] == "OFF":
Devices[newUnit].Update(nValue=0, sValue='Off')
else:
Devices[unit].Update(nValue=1, sValue='On')
else:
self.counter += 1
Domoticz.Debug('Counter = ' + str(self.counter))
def GetDevices(self):
headers = {'Content-Type': 'application/vnd.alertme.zoo-6.2+json', 'Accept': 'application/vnd.alertme.zoo-6.2+json', \
'X-AlertMe-Client': 'swagger', 'X-Omnia-Access-Token': self.sessionId}
url = 'https://api.prod.bgchprod.info:443/omnia/nodes'
req = Request(url, headers = headers, unverifiable = True)
try:
r = urlopen(req).read().decode('utf-8')
except Exception as e:
Domoticz.Log(str(e))
return json.loads(r)['nodes']
def GetThermostat(self, d):
x = find_key_in_list(d, 'http://alertme.com/schema/json/node.class.thermostat.json#')
if x:
k = 'stateHeatingRelay'
if k in x[0]['attributes']:
thermostat = x[0]
elif k in x[1]['attributes']:
thermostat = x[1]
else:
thermostat = False
else:
thermostat = False
return thermostat
def GetThermostatUI(self, d):
thermostatui = False
x = find_key_in_list(d, 'http://alertme.com/schema/json/node.class.thermostatui.json#')
if x:
thermostatui = x[0]
else: # Try a Hive2 thermostat
x = find_key_in_list(d,"Hive2")
if x:
thermostatui = x[0]
return thermostatui
def GetLights(self, d):
lights = False
x = find_key_in_list(d,"http://alertme.com/schema/json/node.class.light.json#")
if x:
lights = x
return lights
def GetActivePlugs(self, d):
plugs = False
x = find_key_in_list(d,"http://alertme.com/schema/json/node.class.smartplug.json#")
if x:
lights = x
return plugs
def GetNextUnit(self, unit):
if not unit:
nextUnit = len(Devices) + 1
else:
nextUnit = unit +1
if nextUnit in Devices or nextUnit <= 1:
nextUnit = self.GetNextUnit(nextUnit)
return nextUnit
def CreateLightPayload(self, State, Brightness):
response = {}
nodes = []
attributes = {}
state = {}
brightness = {}
brightness["targetValue"] = Brightness
state["targetValue"] = State
attributes["attributes"] = {"brightness":brightness,"state":state}
nodes.append(attributes)
response["nodes"] = nodes
return response
def CreateThermostatPayload(self, Temperature):
response = {}
nodes = []
attributes = {}
targetHeatTemperature = {}
targetHeatTemperature["targetValue"] = Temperature
attributes["attributes"] = {"targetHeatTemperature":targetHeatTemperature}
nodes.append(attributes)
response["nodes"] = nodes
return response
def CreateActivePlugPayload(self, State):
response = {}
nodes = []
attributes = {}
state = {}
state["targetValue"] = State
attributes["attributes"] = {"state":state}
nodes.append(attributes)
response["nodes"] = nodes
return response
def isLight(self, Unit):
Domoticz.Debug(str(self.lightsSet))
if Devices[Unit].Type == 244 and Devices[Unit].SubType == 73 and Unit in self.lightsSet:
return True
else:
return False
def isThermostat(self, Unit):
if Devices[Unit].Type == 242:
return True
else:
return False
def isActivePlug(self, Unit):
if Devices[Unit].Type == 244 and Devices[Unit].SubType == 73 and Unit not in self.lightsSet and Devices[Unit].DeviceID != "Hive_Heating":
return True
else:
return False
_plugin = BasePlugin()
def onStart():
_plugin.onStart()
def onStop():
_plugin.onStop()
def onConnect(Connection, Status, Description):
_plugin.onConnect(Connection, Status, Description)
def onMessage(Connection, Data, Status, Extra):
_plugin.onMessage(Connection, Data, Status, Extra)
def onCommand(Unit, Command, Level, Hue):
_plugin.onCommand(Unit, Command, Level, Hue)
def onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile):
_plugin.onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile)
def onDisconnect(Connection):
_plugin.onDisconnect(Connection)
def onHeartbeat():
_plugin.onHeartbeat()
def DumpConfigToLog():
for x in Parameters:
if Parameters[x] != '':
Domoticz.Debug("'" + x + "':'" + str(Parameters[x]) + "'")
Domoticz.Debug('Device count: ' + str(len(Devices)))
for x in Devices:
Domoticz.Debug('Device: ' + str(x) + ' - ' + str(Devices[x]))
Domoticz.Debug("Device ID: '" + str(Devices[x].ID) + "'")
Domoticz.Debug("Device Name: '" + Devices[x].Name + "'")
Domoticz.Debug('Device nValue: ' + str(Devices[x].nValue))
Domoticz.Debug("Device sValue: '" + Devices[x].sValue + "'")
Domoticz.Debug('Device LastLevel: ' + str(Devices[x].LastLevel))
Users browsing this forum: No registered users and 1 guest