Skip to content

Commit

Permalink
shelly button in Smarthome
Browse files Browse the repository at this point in the history
Neu kann jedem Smarthomedevice ein Shelly Button zugeordnet werden.
Dieser muss mit mqtt parametrisiert werden und eine fest IP Adresse haben. Mit einmal drücken kann man das zugeordnete Device in Manual Modus setzen. Dann wird mit dem Leuchtring angezeigt wie der Status ist:
Dauern an : Device off
Langsam blinkend : Device on
Zweimaliges drücken setzt das Device in den Automatic Modus
Im Automatic Modus erlischt der Leuchtring. Bei den Smarthome Settings sollte die IP Adresse vom Button nur bei der Auswahl erscheinen, das wird noch korrigiert. Sofern ein Device in einer Einschaltgruppe  ist, wird es nur durch die Ausschaltgruppe angeschaltet wenn es nicht in im Standbystatus der Anlauferkennung ist .
  • Loading branch information
okaegi committed Jun 5, 2022
1 parent 49ea306 commit 65981dc
Show file tree
Hide file tree
Showing 5 changed files with 253 additions and 13 deletions.
29 changes: 23 additions & 6 deletions runs/mqttsub.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,23 @@ def on_message(client, userdata, msg):
if ( 1 <= int(devicenumb) <= numberOfSupportedDevices and len(str(msg.payload.decode("utf-8"))) > 6 and bool(re.match(ipallowed, msg.payload.decode("utf-8")))):
writetoconfig(shconfigfile,'smarthomedevices','device_ip_'+str(devicenumb), msg.payload.decode("utf-8"))
client.publish("openWB/config/get/SmartHome/Devices/"+str(devicenumb)+"/device_ip", msg.payload.decode("utf-8"), qos=0, retain=True)
if (( "openWB/config/set/SmartHome/Device" in msg.topic) and ("device_pbip" in msg.topic)):
devicenumb=re.sub(r'\D', '', msg.topic)
if ( 1 <= int(devicenumb) <= numberOfSupportedDevices and len(str(msg.payload.decode("utf-8"))) > 6 and bool(re.match(ipallowed, msg.payload.decode("utf-8")))):
writetoconfig(shconfigfile,'smarthomedevices','device_pbip_'+str(devicenumb), msg.payload.decode("utf-8"))
client.publish("openWB/config/get/SmartHome/Devices/"+str(devicenumb)+"/device_pbip", msg.payload.decode("utf-8"), qos=0, retain=True)
if (( "openWB/config/set/SmartHome/Device" in msg.topic) and ("device_pbtype" in msg.topic)):
devicenumb=re.sub(r'\D', '', msg.topic)
validDeviceTypespb = ['none','shellypb']
if ( 1 <= int(devicenumb) <= numberOfSupportedDevices and len(str(msg.payload.decode("utf-8"))) > 2):
try:
# just check vor payload in list, deviceTypeIndex is not used
deviceTypeIndex = validDeviceTypespb.index(msg.payload.decode("utf-8"))
except ValueError:
pass
else:
writetoconfig(shconfigfile,'smarthomedevices','device_pbtype_'+str(devicenumb), msg.payload.decode("utf-8"))
client.publish("openWB/config/get/SmartHome/Devices/"+str(devicenumb)+"/device_pbtype", msg.payload.decode("utf-8"), qos=0, retain=True)
if (( "openWB/config/set/SmartHome/Device" in msg.topic) and ("device_measureip" in msg.topic)):
devicenumb=re.sub(r'\D', '', msg.topic)
if ( 1 <= int(devicenumb) <= numberOfSupportedDevices and len(str(msg.payload.decode("utf-8"))) > 6 and bool(re.match(ipallowed, msg.payload.decode("utf-8")))):
Expand Down Expand Up @@ -185,13 +202,13 @@ def on_message(client, userdata, msg):
if ( 1 <= int(devicenumb) <= numberOfSupportedDevices and -100000 <= int(msg.payload) <= 100000):
writetoconfig(shconfigfile,'smarthomedevices','device_einschaltschwelle_'+str(devicenumb), msg.payload.decode("utf-8"))
client.publish("openWB/config/get/SmartHome/Devices/"+str(devicenumb)+"/device_einschaltschwelle", msg.payload.decode("utf-8"), qos=0, retain=True)

if (( "openWB/config/set/SmartHome/Device" in msg.topic) and ("device_deactivateper" in msg.topic)):
devicenumb=re.sub(r'\D', '', msg.topic)
if ( 1 <= int(devicenumb) <= numberOfSupportedDevices and 0 <= int(msg.payload) <= 100):
writetoconfig(shconfigfile,'smarthomedevices','device_deactivateper_'+str(devicenumb), msg.payload.decode("utf-8"))
client.publish("openWB/config/get/SmartHome/Devices/"+str(devicenumb)+"/device_deactivateper", msg.payload.decode("utf-8"), qos=0, retain=True)

if (( "openWB/config/set/SmartHome/Device" in msg.topic) and ("device_deactivateWhileEvCharging" in msg.topic)):
devicenumb=re.sub(r'\D', '', msg.topic)
if ( 1 <= int(devicenumb) <= numberOfSupportedDevices and 0 <= int(msg.payload) <= 2):
Expand Down Expand Up @@ -421,16 +438,16 @@ def on_message(client, userdata, msg):
client.publish("openWB/config/get/SmartHome/Devices/"+str(devicenumb)+"/device_nonewatt", msg.payload.decode("utf-8"), qos=0, retain=True)
else:
print( "invalid payload for topic '" + msg.topic + "': " + msg.payload.decode("utf-8"))

if (( "openWB/config/set/SmartHome/Device" in msg.topic) and ("device_idmnav" in msg.topic)):
devicenumb=re.sub(r'\D', '', msg.topic)
if ( 1 <= int(devicenumb) <= numberOfSupportedDevices and 1 <= int(msg.payload) <= 2 ):
writetoconfig(shconfigfile,'smarthomedevices','device_idmnav_'+str(devicenumb), msg.payload.decode("utf-8"))
client.publish("openWB/config/get/SmartHome/Devices/"+str(devicenumb)+"/device_idmnav", msg.payload.decode("utf-8"), qos=0, retain=True)
else:
print( "invalid payload for topic '" + msg.topic + "': " + msg.payload.decode("utf-8"))
print( "invalid payload for topic '" + msg.topic + "': " + msg.payload.decode("utf-8"))


if (( "openWB/config/set/SmartHome/Device" in msg.topic) and ("device_standbyDuration" in msg.topic)):
devicenumb=re.sub(r'\D', '', msg.topic)
if ( 1 <= int(devicenumb) <= numberOfSupportedDevices and 0 <= int(msg.payload) <= 86400 ):
Expand Down
17 changes: 17 additions & 0 deletions runs/smarthomemq.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ def getdevicevalues():
# dyn daten einschaltgruppe
Sbase.ausschaltwatt = 0
Sbase.einrelais = 0
Sbase.eindevstatus = 0
mqtt_all = {}
for mydevice in mydevices:
mydevice.getwatt(uberschuss, uberschussoffset)
Expand Down Expand Up @@ -429,6 +430,8 @@ def resetmaxeinschaltdauerfunc():
readmq()
while True:
# update_devices()
mqtt_man = {}
sendmess = 0
loadregelvars()
resetmaxeinschaltdauerfunc()
getdevicevalues()
Expand All @@ -449,4 +452,18 @@ def resetmaxeinschaltdauerfunc():
logDebug(LOGLEVELDEBUG, "(" + str(i) + ") " +
mydevice.device_name +
" manueller Modus aktiviert, keine Regelung")
for i in range(1, (numberOfSupportedDevices+1)):
pref = 'openWB/config/set/SmartHome/Devices/' + str(i) + '/'
for mydevice in mydevices:
if (str(i) == str(mydevice.device_nummer)):
mydevice.updatebutton()
if (mydevice.btchange == 1):
sendmess = 1
mqtt_man[pref + 'mode'] = mydevice.newdevice_manual
if (mydevice.btchange == 2):
sendmess = 1
workman = mydevice.newdevice_manual_control
mqtt_man[pref + 'device_manual_control'] = workman
if (sendmess == 1):
sendmq(mqtt_man)
time.sleep(5)
192 changes: 189 additions & 3 deletions runs/usmarthome/smartbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import json
import time
import os
import urllib.request
from datetime import datetime, timezone


Expand Down Expand Up @@ -510,6 +511,132 @@ def sepwattread(self):
return self.newwatt, self.newwattk


class Spbase(Sbase0):
def __init__(self):
#
# setting
print('__init__ Spbase executed')
self._device_pbip = 'none'
self.device_nummer = 0

def updatepar(self, input_param):
self._smart_param = input_param.copy()
self.device_nummer = int(self._smart_param.get('device_nummer', '0'))
for key, value in self._smart_param.items():
if (key == 'device_pbip'):
self._device_pbip = value
else:
self.logClass(2, "(" + str(self.device_nummer) + ") "
+ __class__.__name__ + " überlesen " + key +
" " + value)

def showstat(self, manual, relais):
pass


class Sbshelly(Spbase):
def __init__(self):
# setting
super().__init__()
print('__init__ Sbshelly excuted')
self.counter = 0
self.led = 9
self.event_cnt = 0
self.event = 'none'
self.oldevent_cnt = 0
self.oldevent = 'none'

def showstat(self, manual, relais):
if (manual == 0): # automatic mode
self.pboff()
else: # manual mode
if (relais == 0):
self.pbon()
else:
self.pbblink()

def checkbut(self, manual, relais, manual_control):
newmanual = manual
newmanual_control = manual_control
at = str(urllib.request.urlopen("http://" +
str(self._device_pbip)
+ "/status",
timeout=3).read().decode("utf-8"))
a = json.loads(at)
with open(self._basePath+'/ramdisk/smarthome_device_ret' +
str(self.device_nummer) + '_shelly_bp', 'w') as f:
f.write(str(a))
self.oldevent_cnt = self.event_cnt
self.oldevent = self.event
self.event_cnt = int(a['inputs'][0]['event_cnt'])
self.event = str(a['inputs'][0]['event'])
if (self.oldevent == 'none'):
return newmanual, newmanual_control
if ((self.event == self.oldevent) and
(self.event_cnt == self.oldevent_cnt)):
return newmanual, newmanual_control
self.logClass(2, "Shelly button pressed (%d) %s %s"
% (self.device_nummer,
self._device_pbip, self.event))
# im automatic modus -> ein mal Drücken wechselen auf manual
if (manual == 0):
newmanual = 1
return newmanual, newmanual_control
# im manual modus -> ein mal Drücken wechselen zwischen on und off
if (self.event == 'S'):
if (manual_control == 1):
newmanual_control = 0
else:
newmanual_control = 1
return newmanual, newmanual_control
# im manual modus -> mehrmals drücken wechselen auf automat
newmanual = 0
return newmanual, newmanual_control

def pboff(self):
if (self.led == 0):
return
try:
urllib.request.urlopen("http://" + str(self._device_pbip) +
"/settings?led_status_disable=true",
timeout=3)
self.logClass(2, "Shelly button led off (%d) %s"
% (self.device_nummer,
self._device_pbip))

except Exception as e1:
self.logClass(2, "Shelly button off (%d) %s Fehlermeldung: %s "
% (self.device_nummer,
self._device_pbip, str(e1)))
self.led = 0

def pbon(self):
if (self.led == 1):
return
try:
urllib.request.urlopen("http://" + str(self._device_pbip) +
"/settings?led_status_disable=false",
timeout=3)
self.logClass(2, "Shelly button led on (%d) %s"
% (self.device_nummer,
self._device_pbip))
except Exception as e1:
self.logClass(2, "Shelly button on (%d) %s Fehlermeldung: %s "
% (self.device_nummer,
self._device_pbip, str(e1)))
self.led = 1

def pbblink(self):
self.counter = self.counter + 1
if (self.counter < 1):
return
self.counter = 0
if (self.led == 0):
self.pbon()
else:
self.pboff()


class Sbase(Sbase0):
# Instance variablen für ein und Auschaltgruppe
einschwelle = 0
Expand All @@ -520,6 +647,7 @@ class Sbase(Sbase0):
ausschaltwatt = 0
einrelais = 0
nureinschaltinsec = 0
eindevstatus = 0

def __init__(self):
# setting
Expand Down Expand Up @@ -547,6 +675,9 @@ def __init__(self):
self.abschalt = 0
self.device_homeconsumtion = 0
self.device_manual = 0
self.device_manual_control = 0
self.newdevice_manual = 0
self.newdevice_manual_control = 0
self.device_type = 'none'
self._smart_param = {}
self._uberschussoffset = 0
Expand Down Expand Up @@ -578,9 +709,10 @@ def __init__(self):
self._device_ontime = '00:00'
self._device_onuntiltime = '00:00'
self._device_nonewatt = 0
self.device_manual_control = 0
self._device_deactivateper = 0

self._device_pbtype = 'none'
self._old_pbtype = 'none'
self._mydevicepb = 'none'
self._oldrelais = '2'
self._oldwatt = 0
# mqtt per
Expand Down Expand Up @@ -608,6 +740,7 @@ def __init__(self):
self._c_einverz_f = 'N'
self._dynregel = 0
self.gruppe = 'none'
self.btchange = 0

def __del__(self):

Expand Down Expand Up @@ -745,6 +878,7 @@ def postwatt(self):
elif (self.gruppe == 'E'):
if (self.relais == 1):
Sbase.einrelais = 1
Sbase.eindevstatus = max(Sbase.eindevstatus, self.devstatus)

def updatepar(self, input_param):
self._smart_param = input_param.copy()
Expand Down Expand Up @@ -828,6 +962,10 @@ def updatepar(self, input_param):
self.device_manual_control = valueint
elif (key == 'device_deactivateper'):
self._device_deactivateper = valueint
elif (key == 'device_pbtype'):
self._device_pbtype = value


# openWB/config/set/SmartHome/Devices/<ID>/mode auf 1 setzen -> Gerät wird
# als 'Manuell' in der Geräteliste geführt
# openWB/config/set/SmartHome/Devices/<ID>/device_manual_control -> 0
Expand Down Expand Up @@ -887,6 +1025,24 @@ def updatepar(self, input_param):
self.gruppe = 'none'
if (self.device_type == 'none'):
self.device_canswitch = 0
if (self._device_pbtype == 'shellypb'):
if (self._old_pbtype == 'none'):
self._mydevicepb = Sbshelly()
self._old_pbtype = 'shelly'
self.logClass(2, "(" + str(self.device_nummer) +
") control Button. Neues Button" +
" device erzeugt Shelly")
else:
self.logClass(2, "(" + str(self.device_nummer) +
") Control Button. Nur Parameter " +
" update ")
self._mydevicepb.updatepar(input_param)
if ((self._device_pbtype == 'none') and
(self._old_pbtype == 'shelly')):
del self._mydevicepb
self._old_pbtype = 'none'
self.logClass(2, "(" + str(self.device_nummer) +
") Control Button gelöscht")
if (self._device_differentmeasurement == 1):
if (self._oldmeasuretype1 == self._device_measuretype):
self.logClass(2, "(" + str(self.device_nummer) +
Expand Down Expand Up @@ -1382,7 +1538,8 @@ def conditions(self, speichersoc):
str(Sbase.einschwelle) + " Überschuss " +
str(self._uberschuss))
if (((Sbase.ausschaltwatt + self._uberschuss) >
Sbase.einschwelle) and Sbase.einrelais == 0):
Sbase.einschwelle) and Sbase.einrelais == 0 and
Sbase.eindevstatus == 10):
self.logClass(2, "(" + str(self.device_nummer) +
") " + self.device_name +
" erfolgreich, schalte aus ")
Expand Down Expand Up @@ -1643,3 +1800,32 @@ def getwatt(self, uberschuss, uberschussoffset):

def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt):
pass

def updatebutton(self):
self.newdevice_manual = self.device_manual
self.newdevice_manual_control = self.device_manual_control
if (self._old_pbtype == 'none'):
return
self._mydevicepb.showstat(self.device_manual, self.relais)
(newmanual, newmanual_control) = self._mydevicepb.checkbut(
self.device_manual, self.relais,
self.device_manual_control)
if ((self.newdevice_manual == newmanual) and
self.newdevice_manual_control == newmanual_control):
self.btchange = 0 # keine Änderung
return
self.newdevice_manual = newmanual
self.newdevice_manual_control = newmanual_control
self.logClass(2, "(" + str(self.device_nummer) + ") " +
self.device_name +
" Umschaltung manual modus alt/neu " +
str(self.device_manual) + "/" +
str(self.newdevice_manual) +
" on off alt/neu " + str(self.device_manual_control) +
"/" + str(self.newdevice_manual_control))
if (self.newdevice_manual == self.device_manual):
# Änderung bezüglich on off
self.btchange = 2
else:
# Änderung bezüglich mode
self.btchange = 1
20 changes: 19 additions & 1 deletion web/settings/smarthomeconfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,24 @@
</div>
</div>
<hr class="border-secondary">
<div class="form-group">
<div class="form-row mb-1">
<label class="col-md-4 col-form-label">Steuerung über Smart Button</label>
<div class="col">
<select class="form-control" name="device_pbtype" id="device_pbtypeDevices<?php echo $devicenum; ?>" data-default="none" data-topicprefix="openWB/config/get/SmartHome/" data-topicsubgroup="Devices/<?php echo $devicenum; ?>/">
<option value="none" data-option="none" selected="selected">Kein Button</option>
<option value="shellypb" data-option="shellypb">Shelly Button 1</option>
</select>
</div>
</div>
<div class="form-row mb-1">
<label for="device_pbipDevices<?php echo $devicenum; ?>" class="col-md-4 col-form-label">IP Adresse vom Button</label>
<div class="col">
<input id="device_pbipDevices<?php echo $devicenum; ?>" name="device_pbip" class="form-control" type="text" pattern="^((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$" data-default="192.168.1.1" value="192.168.1.1" inputmode="text" data-topicprefix="openWB/config/get/SmartHome/" data-topicsubgroup="Devices/<?php echo $devicenum; ?>/">
</div>
</div>
</div>
<hr class="border-secondary">
<div class="form-group">
<div class="form-row mb-1">
<label class="col-md-4 col-form-label">Separate Leistungsmessung für das Gerät</label>
Expand Down Expand Up @@ -649,7 +667,7 @@
<option value="mystrom" data-option="mystrom">MyStrom</option>
<option value="sdm630" data-option="sdm630">SDM630</option>
<option value="shelly" data-option="shelly">Shelly oder Shelly plus</option>
<option value="tasmota" data-option="tasmota">tasmota</option>
<option value="tasmota" data-option="tasmota">tasmota</option>
<option value="we514" data-option="we514">WE514</option>
<option value="avm" data-option="avm">AVM</option>
<option value="mqtt" data-option="mqtt">Mqtt</option>
Expand Down
Loading

0 comments on commit 65981dc

Please sign in to comment.