I think I have something for you. The code now listen to UDP Sync port and update devices from it.
I think it need some more testing but it's a good start. Enjoy!
Code: Select all
# WLED Plugin for Domoticz
#
# Author: Frustreermeneer
#
"""
<plugin key="WLED2" name="WLED2" author="frustreermeneer" version="0.0.1" wikilink="http://www.domoticz.com/wiki/plugins/plugin.html" externallink="https://github.com/frustreermeneer/domoticz-wled-plugin">
<description>
<h2>WLED Plugin</h2><br/>
<h3>Features</h3>
<ul style="list-style-type:square">
<li>Switching WLED on/off</li>
<li>Setting brightness</li>
<li>Setting effect from list</li>
<li>Setting effect speed & intensity</li>
<li>Setting presets from list</li>
<li>Setting palette from list</li>
</ul>
<h3>Configuration</h3>
</description>
<params>
<param field="Address" label="WLED IP Address" width="200px" required="true" default=""/>
<param field="Port" label="WLED UDP Sync Port" width="200px" required="true" default=""/>
<param field="Mode6" label="Debug" width="150px">
<options>
<option label="None" value="0" default="true" />
<option label="Python Only" value="2"/>
<option label="Basic Debugging" value="62"/>
<option label="Basic+Messages" value="126"/>
<option label="Connections Only" value="16"/>
<option label="Connections+Queue" value="144"/>
<option label="All" value="-1"/>
</options>
</param>
</params>
</plugin>
"""
import Domoticz
import requests
import json
sAddress = ""
sPort = ""
wledData = None
jsonArray = None
class BasePlugin:
BeaconConn = None
getWLEDStatusConn = None
def __init__(self):
return
def onStart(self):
self.counter = 0
self.Color = {}
self.Level = 100
global sAddress
global sPort
sAddress = Parameters["Address"].strip()
sPort = Parameters["Port"].strip()
if Parameters["Mode6"] != "0":
Domoticz.Debugging(int(Parameters["Mode6"]))
DumpConfigToLog()
if (len(Devices) == 0):
Domoticz.Log("creating devices")
Options = {"LevelActions": "",
"LevelNames": "Loading...",
"LevelOffHidden": "true",
"SelectorStyle": "1"}
Domoticz.Device(Name="Palettes", Unit=1, TypeName="Selector Switch", Options=Options, Image=0).Create()
Domoticz.Device(Name="Effects", Unit=2, TypeName="Selector Switch", Options=Options).Create()
Domoticz.Device(Name="Color & Brightness", Unit=3, Type=241,Subtype=2,Switchtype=7,Options=Options).Create()
Domoticz.Device(Name="Presets", Unit=4, TypeName="Selector Switch", Options=Options).Create()
Domoticz.Device(Name="FX Speed", Unit=5, Type=244,Subtype=62,Switchtype=7,Options=Options).Create()
Domoticz.Device(Name="FX Intensity", Unit=6, Type=244,Subtype=62,Switchtype=7,Options=Options).Create()
else:
Domoticz.Log("devices existed already")
UpdatePresetsInDomoticz()
self.getWLEDStatusConn = Domoticz.Connection(Name="getWLEDStatusConn", Transport="TCP/IP", Protocol="HTTP", Address=sAddress, Port="80" )
self.getWLEDStatusConn.Connect()
self.BeaconConn = Domoticz.Connection(Name="Beacon", Transport="UDP/IP", Address=sAddress, Port=str(sPort))
self.BeaconConn.Listen()
def onConnect(self, Connection, Status, Description):
global sAddress
# er is een externe verbinding gemaakt
# json request doen
if( Connection.Name == "getWLEDStatusConn" ):
sendData = { 'Verb' : 'GET',
'URL' : '/json',
'Headers' : { 'Content-Type': 'application/json; charset=utf-8',
'Connection': 'close',
'Accept': 'Content-Type: text/plain; charset=UTF-8',
'Host': sAddress+":80",
'User-Agent':'Domoticz/1.0' }
}
Connection.Send(sendData)
def onMessage(self, Connection, Data):
global wledData
global jsonArray
try:
# we krijgen antwoord terug op onze request
# json update request afhandelen
if( Connection.Name == "getWLEDStatusConn" ):
Connection.Disconnect()
Status = int(Data["Status"])
if( Status == 200 ):
strData = Data["Data"].decode("utf-8", "ignore")
jsonArray = json.loads( str(strData) )
if( len( jsonArray ) ):
UpdateEffectsInDomoticz()
UpdatePalettesInDomoticz()
if (Connection.Name == "Beacon"):
Domoticz.Debug("Connection detail: "+str(Connection))
# Is it notifier protocol
if ( Data[0] == 0x00 and Data[21] == 0x00 and Data[22] == 0x00 and Data[23] == 0x00 and Data[24] == 0x00):
wledData = {
"callMode": Data[1],
"bri": Data[2],
"red": Data[3],
"green": Data[4],
"blue": Data[5],
"nightlightActive": Data[6],
"nightlightDelayMins": Data[7],
"effectCurrent": Data[8],
"effectSpeed": Data[9],
"white": Data[10],
"redSec": Data[12],
"greenSec": Data[13],
"blueSec": Data[14],
"whiteSec": Data[15],
"effectIntensity": Data[16],
"transitionDelayHi": Data[17],
"transitionDelayLow": Data[18],
"effectPalette": Data[19]
}
UpdateStatusInDomoticz()
except Exception as inst:
Domoticz.Error("Exception detail: '"+str(inst)+"'")
raise
def onCommand(self, Unit, Command, Level, Color):
# Domoticz.Log("onCommand called for Unit " + str(Unit) + ": Command '" + str(Command) + "', Level: " + str(Level) + "', Color: " + str(Color) )
# palettes keuze
if( Unit == 1 ):
if( Command == "Set Level" ):
doWLEDRequest( "&FP="+str(int(Level/10)-1) )
# effect keuze
if( Unit == 2 ):
if( Command == "Set Level" ):
doWLEDRequest( "&T=1&FX="+str(int(Level/10)-1) )
if( Command == "Off" ):
doWLEDRequest( "&T=0" )
# kleurkeuze
if( Unit == 3 ):
if( Command == "Set Level" ):
self.Level = Level if Level < 100 else 100
doWLEDRequest( "/win&A="+str(int(self.Level*2.55)) )
if( Command == "Set Color" ): #set kleur en level
self.Color = Color;
self.Level = Level
Domoticz.Log( "Color:" + str(self.Color) )
parsedColor = json.loads(self.Color)
doWLEDRequest( "/win&FX=0&A="+str(int(self.Level*2.55))+"&R="+str(parsedColor["r"])+"&G="+str(parsedColor["g"])+"&B="+str(parsedColor["b"] ) )
if( Command == "On" ):
doWLEDRequest( "/win&T=1&A="+str(int(self.Level*2.55)) )
if( Command == "Off" ):
doWLEDRequest( "/win&T=0&A="+str(int(self.Level*2.55)) )
# preset keuze
if( Unit == 4 ):
if( Command == "Set Level" ):
Domoticz.Log( "Switching to preset" + str(int(Level/10)))
doWLEDRequest( "/win&PL="+str(int(Level/10)) )
# fx speed
if( Unit == 5 ):
if( Command == "Set Level" ):
Domoticz.Log( "FX Speed: " + str(int(Level*2.55)))
doWLEDRequest( "/win&SX="+str(int(Level*2.55)) )
# fx intensity
if( Unit == 6 ):
if( Command == "Set Level" ):
Domoticz.Log( "FX Intensity: " + str(int(Level*2.55)))
# UpdateDevice(6,1,int(Level))
doWLEDRequest( "/win&IX="+str(int(Level*2.55)) )
global _plugin
_plugin = BasePlugin()
def onStart():
global _plugin
_plugin.onStart()
def onConnect(Connection, Status, Description):
global _plugin
_plugin.onConnect(Connection, Status, Description)
def onMessage(Connection, Data):
global _plugin
_plugin.onMessage(Connection, Data)
def onCommand(Unit, Command, Level, Hue):
global _plugin
_plugin.onCommand(Unit, Command, Level, Hue)
# Generic helper functions
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))
return
def UpdateDevice(Unit, nValue, sValue, Color=""):
# Make sure that the Domoticz device still exists (they can be deleted) before updating it.
if (Unit in Devices):
if (Devices[Unit].nValue != nValue) or (Devices[Unit].sValue != sValue) or (Devices[Unit].Color != Color):
if( Color ):
Devices[Unit].Update(nValue=nValue, sValue=str(sValue), Color=str(Color) )
else:
Devices[Unit].Update(nValue=nValue, sValue=str(sValue) )
return
def UpdateEffectsInDomoticz():
# Domoticz.Log("updateEffects")
LevelNames = "Off|"
LevelActions = "|"
effectsArray = jsonArray["effects"]
for idx,effect in enumerate(effectsArray):
LevelNames = LevelNames + str(idx+1) + " - " + str(effect)
if( idx < len(effectsArray)-1 ):
LevelNames = LevelNames + "|"
LevelActions = LevelActions + "|"
dictOptions = Devices[2].Options
dictOptions["LevelNames"] = LevelNames
dictOptions["LevelActions"] = LevelActions
nValue = Devices[2].nValue;
sValue = Devices[2].sValue;
Devices[2].Update(nValue = nValue, sValue = sValue, Options = dictOptions)
def UpdatePalettesInDomoticz():
global jsonArray
# Domoticz.Log("updatePallettes")
LevelNames = "Off|"
LevelActions = "|"
palettesArray = jsonArray["palettes"]
for idx,palette in enumerate(palettesArray):
LevelNames = LevelNames + str(idx+1) + " - " + str(palette)
if( idx < len(palettesArray)-1 ):
LevelNames = LevelNames + "|"
LevelActions = LevelActions + "|"
dictOptions = Devices[1].Options
dictOptions["LevelNames"] = LevelNames
dictOptions["LevelActions"] = LevelActions
nValue = Devices[1].nValue;
sValue = Devices[1].sValue;
Devices[1].Update(nValue = nValue, sValue = sValue, Options = dictOptions)
def UpdatePresetsInDomoticz():
# Domoticz.Log("updatePresets")
LevelNames = "None|"
LevelActions = "|"
for i in range(1,25):
LevelNames = LevelNames + str(i)
if( i < 24 ):
LevelNames = LevelNames + "|"
LevelActions = LevelActions + "|"
# Domoticz.Log( LevelNames )
dictOptions = Devices[4].Options
dictOptions["LevelNames"] = LevelNames
dictOptions["LevelActions"] = LevelActions
dictOptions["LevelOffHidden"] = "false"
nValue = Devices[4].nValue;
sValue = Devices[4].sValue;
Devices[4].Update(nValue = nValue, sValue = sValue, Options = dictOptions)
def UpdateStatusInDomoticz():
global wledData
brightness = wledData["bri"]
r = wledData["red"]
g = wledData["green"]
b = wledData["blue"]
color = json.dumps({ "b":b, "cw":0, "g":g, "m":3, "r":r, "t":0, "ww":0 })
UpdateDevice(3,1,int(brightness/2.55),color) #Devices[3].sValue)
UpdateDevice(6,1,wledData["effectIntensity"]/2.55)
UpdateDevice(5,1,wledData["effectSpeed"]/2.55)
effect = wledData["effectCurrent"]
UpdateDevice(2,1,(effect+1)*10)
UpdateDevice(1, 1, (wledData["effectPalette"]+1)*10 )
def doWLEDRequest( parameters ):
global sAddress
url = "http://"+sAddress+"/win"+parameters
# Domoticz.Log( url )
resp = requests.get(url=url)
# Domoticz.Log(str(resp.status_code))
# Domoticz.Log(str(resp))