I bought a LogicMachine3 reactor a while back. Here are some photos as reference.
Category Archives: Logic Machine
DMX dimming using the Logic Machine
The following script enables you to dim all channels monitoring a KNX group. The code assumes you have created dummy objects (starting 10/0/1) in the Logic Machine for each DMX dimmer channel. That way we can visualize the status of the dimmer and recall the values from other scripts.
Depending on the group value of the dimming group the DMX full on value gets edited accordingly.
I have commented out the logging of each dimming step, but if you are debugging, that might be helpful.
-- This software may be used and distributed according to the terms of the -- GNU General Public License version 3, incorporated herein by reference. -- config variables dmxchan = 12 -- number of max DMX channels to change dimprefix = '10/0/' -- for dummy groups dimgroup = '1/0/1' -- group that dims all dmxon = 255 dmxoff = 0 -- end config variables -- percentage up/down values of the 03.007 KNX value local percentages = {1,1,0.5,0.25,0.12,0.06,0.03,0.01,1,1,0.5,0.25,0.12,0.06,0.03,0.01} -- read value as of moment of change value = grp.getvalue(dimgroup) -- define the up down as a percentage of the full on value dimstep = math.floor(dmxon * percentages[value]) while (value >= 9 and value < =15) do -- Dimming UP for i = 1, dmxchan, 1 do -- I have created dummy objects in the LM to store the dimming value of each channel. 10/0/x DMXvalue = grp.getvalue(dimprefix .. i) if (DMXvalue >= 0 and DMXvalue < = 255) then DMXvalue = DMXvalue + dimstep if (DMXvalue > 255) then DMXvalue = dmxon end else DMXvalue = dmxon end DMX.set(i, DMXvalue) -- update the dimmer status group for specific channel grp.update(dimprefix .. i, DMXvalue) end -- update the Status group for all Dimmers, helps for visualizations grp.update(dimprefix .. 0, DMXvalue) -- give the device enough time to process os.sleep(0.1) value = grp.getvalue(dimgroup) --log('Dimm up ' .. DMXvalue) end while (value >= 1 and value < = 7) do -- Dimming Down for i = 1, dmxchan, 1 do DMXvalue = grp.getvalue(dimprefix .. i) if (DMXvalue >= 0 and DMXvalue < = 255) then DMXvalue = DMXvalue - dimstep if (DMXvalue < 0) then DMXvalue = dmxoff end else DMXvalue = dmxoff end DMX.set(i, DMXvalue) -- update the dimmer status group for specific channel grp.update(dimprefix .. i, DMXvalue) end -- update the Status group for all Dimmers grp.update(dimprefix .. 0, DMXvalue) -- give the device enough time to process os.sleep(0.1) value = grp.getvalue(dimgroup) --log('Dimm down ' .. DMXvalue) end [/prettify]
The screenshot shows you how I added the status into my visualization.
Here you see the dummy objects I created.
CONTROL DIMMING (4-bit) | |||||||||||||||
9 | 10 | 11 | 12 | 13 | 14 | 15 | 8 | 0 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
100% Increase | 50% Increase | 25% Increase | 12% Increase | 6% Increase | 3% Increase | 1% Increase | Stop | Stop | 1% Decrease | 3% Increase | 6% Increase | 12% Increase | 25% Increase | 50% Increase | 100% Increase |
Turn all DMX LED lights on/off using the Logic Machine reactor
We have quite a few DMX based LED lighting sources. I use the eldoled lineardrive 720D to do the controling part. The following script enables me to turn the LEDs on/off, all at once.
-- This software may be used and distributed according to the terms of the -- GNU General Public License version 3, incorporated herein by reference. -- define group address dmxchan = 12 dmxon = 255 dmxoff = 0 -- address of all on/off group groupvalue = '1/2/0' -- addresses of groups that should be switched including the all on/off group lights = {'1/2/0', '1/1/0', '1/1/2', '1/1/3', '1/1/4', '1/1/5', '1/1/6', '1/1/7', '1/1/8'} -- get value of object with group address value = grp.getvalue(groupvalue) if (value == false) then -- channel value set to 255 for i = 1, dmxchan, 1 do DMX.set(i, dmxon) end -- change groups to true for index, value in ipairs(lights) do grp.write(value, true) end log('Light on') else -- channel 1 value set to 0 for i = 1, dmxchan, 1 do DMX.set(i, dmxoff) end -- change groups to false for index, value in ipairs(lights) do grp.write(value, false) end log('Light off') end
I created an “event based script” in the Logic Machine to add this code. The address I monitor is 1/1/1 which is the group that turns all lights on/off in the KNX push buttons.
DMX on the Logic Machine
To get the DMX control of the Logic Machine one needs to get two scripts running. The first is a “handler” that needs to be added as a resident script:
-- This software may be used and distributed according to the terms of the -- GNU General Public License version 3, incorporated herein by reference. if not d then d = DMX:init({ channels = 16, transition = 1, }) log('DMX initialized') -- reset custom DMX RGB color settings to "off" (0), comment out if not needed storage.set('DMXrgbred', 0) storage.set('DMXrgbgreen', 0) storage.set('DMXrgbblue', 0) log('Reset RGB colors') end d:run()
and the second are the common functions, that you can just add to the end of the current common functions.
-- This code is copyright of openrb.com -- Open Source but != free DMX = { -- default params defaults = { -- storage key skey = 'dmx_chan_', -- RS-485 port port = '/dev/ttyAPP2', -- number of calls per second resolution = 20, -- total number of channels to use channels = 16, -- transition time in seconds, does not include DMX transfer time transition = 2, }, -- value setter set = function(i, v) -- validate channel number if type(i) == 'number' and i >= 1 and i < = 512 then -- validate channel value if type(v) == 'number' and v >= 0 and v < = 255 then storage.set(DMX.defaults.skey .. i, v) end end end } -- DMX init, returns new DMX object function DMX:init(params) log('starting DMX') require('luadmx') local n = setmetatable({}, { __index = DMX }) local k, v -- set user parameters n.params = params -- copy parameters that are set by user for k, v in pairs(DMX.defaults) do if n.params[ k ] == nil then n.params[ k ] = v end end n:reset() return n end function DMX:reset() local err, chan log('resetting DMX') self.dm, err = luadmx.open(self.params.port) -- error while opening if err then os.sleep(1) error(err) end -- set channel count self.dm:setcount(self.params.channels) -- number of transaction ticks self.ticks = math.max(1, self.params.transition * self.params.resolution) -- calculate sleep time self.sleep = 1 / self.params.resolution -- reset channel map self.channels = {} -- fill channel map for chan = 1, self.params.channels do self.channels[ chan ] = { current = 0, target = 0, ticks = 0 } -- turn off by default storage.set(self.params.skey .. chan, 0) self.dm:setchannel(chan, 0) end end -- get new values function DMX:getvalues() local chan, val --log('getting DMX values') -- check for new values for each channel for chan = 1, self.params.channels do val = storage.get(self.params.skey .. chan) -- target value differs, set transcation if val ~= self.channels[ chan ].target then self.channels[ chan ].target = val self.channels[ chan ].delta = (self.channels[ chan ].target - self.channels[ chan ].current) / self.ticks self.channels[ chan ].ticks = self.ticks end end end -- main loop handler function DMX:run() local i, bs, bm, as, am, delta local res = self.params.resolution if not self.calibrated then bs, bm = os.microtime() end self:getvalues() -- transition loop for i = 1, res do self:step() self.dm:send() -- wait until next step os.sleep(self.sleep) end -- calibrate delay loop to match 1 second if not self.calibrated then as, am = os.microtime() delta = (as - bs) + (am - bm) / 1000000 if delta > 1.05 then self.sleep = self.sleep - math.max(10, self.sleep / res) else self.calibrated = true end end end -- single transition step function DMX:step() local chan, t -- transition for each channel for chan = 1, self.params.channels do t = self.channels[ chan ].ticks -- transition is active if t > 0 then t = t - 1 self.channels[ chan ].current = self.channels[ chan ].target - self.channels[ chan ].delta * t self.channels[ chan ].ticks = t self.dm:setchannel(chan, self.channels[ chan ].current) end end end
Logic Machine re:actor videos
I bought a Logic Machine from openrb.com a few weeks ago. At about 1.100€ it is not very cheap, but it contains quite a few features that, if bought separately, would have been a lot more expensive. I am going to use it in our flat to do the following:
-
as a KNX gateway (separate for at least 400€)
-
DMX or DALI controller (separate for at least 600€)
-
Home automation visualization (PC and Touch, go for about 1.700€)
-
Logging
-
Logic
-
Digital/Analog inputs and outputs
Nice to have is the enocean chip. If for any reason I need to add wireless sensors or actuators, this will help a lot.
Right now it is not connected to the KNX bus, but I imported a few objects from the ETS4 software (OPC export). Then I used Sweet Home 3D to create a nice 3D view of the flat. Using GIMP I created some nice transparent lighting elements.
To see what I then did with the re:actor check out the following two videos: