X10 dimmer control script CM11 and CM15Pro

Others (MiLight, Hue, Toon etc...)

Moderator: leecollings

Post Reply
franzelare
Posts: 141
Joined: Thursday 19 February 2015 21:48
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

X10 dimmer control script CM11 and CM15Pro

Post by franzelare »

I have been using X10 devices for years, starting with the CM11 and later the CM15Pro controlled from domoticz.
I have mainly 2 way swtiches and dimmers but it is a pitty that mochad cannot decode the dimmer signals and keep track of the dimmer status in domoticz. (and runing on a synology gave me even more trouble with mochad, so added a RasPi3 to run my X10 PL devices)

Recently I got my old CM11 out again and also hooked it up to domotiz next to the CM15Pro, advantage of the CM11 is that with Heyu you can request the RAW dimmer setting from the command line. so with Lua you can store this value and use this in domotizc.
The engine only tracks this properly for the dimmers in the housecode, so i re-asigned the dimmers all to G as the housecode to track the dimmer status.
You have to track this in raw mode, since the % mode is not linear with the raw mode, i.e. Raw 0=0% , 1 = 12%, raw 61=98% and raw 63=100% so you cannot just map the range with a math function.. you need to track the raw but need to keep the dimmer in % for domoticz

I now use 1 switch directly controlled by the CM15Pro, a virtual dimmer to use on my frontpage so I can control it as a normall dimmer, and an additional switch to track if the dimmer was changed manually, otherwise the scripts start acting on changes from one script to the other

in this example the dimmer is called Keuken (kitchen in dutch) what is the real X10 device on G1
I added 2 swtiches:
KeukenVirtual = a virtual dimmer that is used on my frontpage to control the light
KeukenManuel = a on / off switch to track if the switch is changed by the scripts or not
KeukenDim = a user variable to store the RAW dimmer value when setting through domoticz and when reading back

here the lua scripts for the dimmer
Spoiler: show
commandArray = {}

PRINT_MODE = true -- when true wil print output to log and send notifications

-- for swtiches with dimmer function
-- commbining a virtual dimmer for Heyu control and a mochad swtich for the status readback of 2 way dimmers

if (devicechanged['Keuken'] == 'On') and (otherdevices['KeukenVirtual'] ~= 'On') and (otherdevices['KeukenManual'] == 'Off') then
if PRINT_MODE == true then
print('Keuken manually changed to on')
end
commandArray['KeukenVirtual'] = 'On'
commandArray['KeukenManual'] = 'On'
end
if (devicechanged['Keuken'] == 'Off') and (otherdevices['KeukenVirtual'] ~= 'Off') and (otherdevices['KeukenManual'] == 'Off') then
commandArray['KeukenVirtual'] = 'Off'
commandArray['KeukenManual'] = 'On'
if PRINT_MODE == true then
print('Keuken manually changed to off')
end
end
if (devicechanged['KeukenVirtual'] == 'On') and (otherdevices['KeukenManual'] == 'Off') then
if PRINT_MODE == true then
print('KeukenVirtual changed to on')
end
commandArray['Keuken'] = 'On'
commandArray['KeukenManual'] = 'On'
Dimprecent = math.ceil(tonumber(uservariables["KeukenDim"])*1.613)
DimHeyu = uservariables["KeukenDim"]
if PRINT_MODE == true then
print('DimmerVirtual set to :' .. Dimprecent)
print('DimmerHeyu set to :' .. DimHeyu)
end
commandArray['KeukenVirtual']='Set Level ' .. Dimprecent
execcommand="sudo /usr/local/bin/heyu xpreset g1" .. DimHeyu
os.execute(execcommand)
end
if (devicechanged['KeukenVirtual'] == 'Off') and (otherdevices['KeukenManual'] == 'Off') then
local f = io.popen("/usr/local/bin/heyu rawlevel g1")
local Dimstand = f:read()
commandArray['Variable:KeukenDim'] = tostring(Dimstand)
if PRINT_MODE == true then
print('Dimmer was at off :' .. Dimstand)
end
commandArray['Keuken'] = 'Off'
commandArray['KeukenManual'] = 'On'
if PRINT_MODE == true then
print('KeukenVirtual manually changed to off')
end
end
if (devicechanged['KeukenVirtual']) and (otherdevices['KeukenManual'] == 'Off') and (otherdevices['KeukenVirtual'] ~= 'Off') then
DimstandNew=(otherdevices_svalues['KeukenVirtual'])
DimHeyu=math.ceil(DimstandNew/1.613)
if PRINT_MODE == true then
print('Keuken changed')
svalue=otherdevices_svalues['KeukenVirtual']
DimstandDelta = DimHeyu - tonumber(uservariables["KeukenDim"])
print('S value new Keuken: ' .. svalue)
print('Dimmer level new Keuken: ' .. DimstandNew)
print('Dimmer level Raw new Keuken: ' .. DimHeyu)
print('Dimmer level RAW old Keuken: ' .. uservariables["KeukenDim"])
print('Dimmer level RAW verschil Keuken: ' .. DimstandDelta)
end
if (DimHeyu~=tostring(uservariables["KeukenDim"])) then
execcommand="sudo /usr/local/bin/heyu xpreset g1 " .. DimHeyu
os.execute(execcommand)
commandArray['Variable:KeukenDim'] = tostring(DimHeyu)
if PRINT_MODE == true then
print('Updating dimmer value')
print('Dimmer RAW level changed to: ' .. DimHeyu)
end
end
end
return commandArray
I have a blocky scripts that when the KeukenManual is switched on, will switch it off after 5 seconds (but this might be shorter and still work properly)

next there I added a script to check the status of the dimmer when it is on, so in case you change it manually by the push buttons it will also store the value. this is a time base lua script.
checks if the timmer is not off and if so stores the RAW value in the uservariable KeukenDim
Spoiler: show
commandArray = {}

PRINT_MODE = true -- when true wil print output to log and send notifications

-- for 2 way swtiches with dimmer function
-- reading the dimmer level of the 2 way dimmers to store as user varaible

-- Keuken dimmer code
if (otherdevices['Keuken'] ~= 'Off') and (otherdevices['KeukenManual'] == 'Off') then
local f = io.popen("/usr/local/bin/heyu rawlevel g1")
local Dimstand = f:read()
commandArray['Variable:KeukenDim'] = tostring(Dimstand)
if PRINT_MODE == true then
print("Keuken RAWlevel ontvangen:" .. Dimstand)
DimPrecentage=math.ceil(Dimstand*1.613)
print("Keuken level percentage calculated:" .. DimPrecentage)
end
end

return commandArray
with the readback script the only issue is that the displayed percentage will not match the virtual dimmer status since the mapping is not linear.
I will expand this to all my dimmers at home and if still working properly, it could be added to the wiki.
improvement needs to be made to not have all names hardcoded but put them in an overview at the start of the scripts so they are easier to change for other users
Xavier82
Posts: 178
Joined: Tuesday 07 June 2016 22:09
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Location: Netherlands
Contact:

Re: X10 dimmer control script CM11 and CM15Pro

Post by Xavier82 »

Hi franzelare,

Did you come any closer to a proper and working solution.
I would like to control my X10 shutters with CM15PRO via Mochad with Domoticz.
This works but only problem is that I can't "dim" the shutter to for example 25% or 50%. The only possibility now is open or closed.

Hope to hear from you!
franzelare
Posts: 141
Joined: Thursday 19 February 2015 21:48
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: X10 dimmer control script CM11 and CM15Pro

Post by franzelare »

got closer, only issue that i have that sometimes when i use the manual light switch the light first starts, than dimmes again and raises back up to the set level.
problem is that it doesn't happen all the time, only sporadically, so must be a timing issue within domoticz and with combining scripts or setting dummy switches I must be able to get around this timing issue.
franzelare
Posts: 141
Joined: Thursday 19 February 2015 21:48
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: X10 dimmer control script CM11 and CM15Pro

Post by franzelare »

got the sollution working for a while now.
I have a few scripts runing and use dummy devices plus a user variable per switch
for every 2way X10 dimmer, i have the unit as switch through the CM15pro connected to domoticz to monitor on and off status
besides that i have 2 virtual switches: one to register if the dimmer is operated in manual and one to display the dimmer value on my app (custom domoticz frontpage) and a uservariable to store the dimmer value when the switch is off

so for one room (Badkamer is dutch for bathroom)
CM15pro on/off switch--> Badkamer
Virtual on/off switch --> BadkamerManual
virtual dimmer --> BadkamerVirtual
user variable --> BadkamerDim

first i have script that checks if the dimmer is operated manually or the virtual dimmer is operated through the app

Code: Select all

-- Badkamer dimmer code    
if (devicechanged['Badkamer'] == 'On') and (otherdevices['BadkamerVirtual'] ~= 'On') and (otherdevices['BadkamerManual'] == 'Off') and (Manual == 0) and (Auto == 0) then
    if PRINT_MODE == true then
        print('Badkamer manually changed to on')
    end
    Manual = 1
	commandArray['BadkamerVirtual'] = 'On'
	commandArray['BadkamerManual'] = 'On'
end
if (devicechanged['Badkamer'] == 'Off') and (otherdevices['BadkamerVirtual'] ~= 'Off') and (otherdevices['BadkamerManual'] == 'Off') and (Manual == 0) and (Auto == 0) then
	Manual = 1
	commandArray['BadkamerVirtual'] = 'Off'
	commandArray['BadkamerManual'] = 'On'
    if PRINT_MODE == true then
        print('Badkamer manually changed to off')
    end
end

if (devicechanged['BadkamerVirtual'] == 'On') and (otherdevices['BadkamerManual'] == 'Off') and (Manual == 0) and (Auto == 0) then
    if PRINT_MODE == true then
        print('BadkamerVirtual changed to on')
    end
    Auto = 1
	commandArray['Badkamer'] = 'On'
	commandArray['BadkamerManual'] = 'On'
    Dimprecent = math.ceil(tonumber(uservariables["BadkamerDim"])*1.613)
    DimHeyu = uservariables["BadkamerDim"]
    if PRINT_MODE == true then
        print('DimmerVirtual set to :' .. Dimprecent)
        print('DimmerHeyu set to :' .. DimHeyu)
    end
    commandArray['BadkamerVirtual']='Set Level ' .. Dimprecent
    execcommand="sudo /usr/local/bin/heyu xpreset g8" .. DimHeyu
    os.execute(execcommand)
end
if (devicechanged['BadkamerVirtual'] == 'Off') and (otherdevices['BadkamerManual'] == 'Off') and (Manual == 0) and (Auto == 0) then
    local f = io.popen("/usr/local/bin/heyu rawlevel g8")
    local Dimstand = f:read()
    commandArray['Variable:BadkamerDim'] = tostring(Dimstand)
    if PRINT_MODE == true then
        print('Dimmer was at off :' .. Dimstand)
    end
    Auto = 1
	commandArray['Badkamer'] = 'Off'
	commandArray['BadkamerManual'] = 'On'
	if PRINT_MODE == true then
        print('BadkamerVirtual manually changed to off')
    end
end
if (devicechanged['BadkamerVirtual']) and (otherdevices['BadkamerManual'] == 'Off') and (otherdevices['BadkamerVirtual'] ~= 'Off') and (Manual == 0) and (Auto == 0) then
        DimstandNew=(otherdevices_svalues['BadkamerVirtual']) 
        DimHeyu=math.ceil(DimstandNew/1.613)
        Auto = 1
        if PRINT_MODE == true then
            print('Badkamer changed')
            svalue=otherdevices_svalues['BadkamerVirtual']
	        DimstandDelta = DimHeyu - tonumber(uservariables["BadkamerDim"])
            print('S value new Badkamer: ' .. svalue)
            print('Dimmer level new Badkamer: ' .. DimstandNew)
            print('Dimmer level Raw new Badkamer: ' .. DimHeyu)
            print('Dimmer level RAW old Badkamer: ' .. uservariables["BadkamerDim"])
            print('Dimmer level RAW verschil Badkamer: ' .. DimstandDelta)
        end
        if (DimHeyu~=tostring(uservariables["BadkamerDim"])) then
            execcommand="sudo /usr/local/bin/heyu xpreset g8 " .. DimHeyu
            os.execute(execcommand)
            commandArray['Variable:BadkamerDim'] = tostring(DimHeyu)
            if PRINT_MODE == true then
                print('Updating dimmer value')
                print('Dimmer RAW level changed to: ' .. DimHeyu)
            end
        end
end   
I have a blocky scripts that when a manual for one of the dimmers is switched on, it switches off after 5 seconds, blocky is a bit easier for that than lua

Code: Select all

if BadkamerManual == 'On' then BadkamerManual == 'Off' after 5 seconds
secondly i have a time based script runing to check the level of the dimmer unit when it is on, so when you manually change the dimmer level it will be recorded and stored by domotics with max 1 minute delay.
this works for max 16 units on the housecode you have set for the CM11, so i have all dimmers on one housecode and switches grouped per function on other house codes.

Code: Select all

-- Badkamer dimmer code
if (otherdevices['Badkamer'] ~= 'Off') and (otherdevices['BadkamerManual'] == 'Off') then
    local f = io.popen("/usr/local/bin/heyu rawlevel g8")
    local Dimstand = f:read()
    commandArray['Variable:BadkamerDim'] = tostring(Dimstand)
    if PRINT_MODE == true then
        print("Badkamer Dimmer staat aan:")
        print("Badkamer RAWlevel ontvangen:" .. Dimstand)
        DimPrecentage=math.ceil(Dimstand*1.613)
        print("Badkamer level percentage calculated:" .. DimPrecentage)
    end
end
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest