LogicMachine Forum
DMX.set with more options - Printable Version

+- LogicMachine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8)
+--- Thread: DMX.set with more options (/showthread.php?tid=2786)



DMX.set with more options - Christian_EWW - 11.08.2020

I'm trying to modify the DMX sample my goal would be to create a set method where I have a parameter for the transition time.
I could use dmxhandler.channels in the resident script and manipulate the target and ticks value, but I don't like this idea.
I would be nicer to have a function within the user.dmx.
What I don't understand is how the data from storage.exec('lset', key, chan - 1, val) gets processed to land in the self.channels, so that I can modify it to pass not only the target value but also a transition time?


Thank's
Christian


RE: DMX.set with more options - admin - 11.08.2020

Try this, untested so might not work Smile
Use DMX.settransition to set value and transition time for a given channel.
Code:
local luadmx = require('luadmx') module('DMX', package.seeall) local DMX = {} -- default params local defaults = {   -- storage key   skey = 'dmx_line_1',   -- RS-485 port   port = '/dev/RS485',   -- number of calls per second   resolution = 20,   -- total number of channels to use   channels = 3,   -- default transition time in seconds, does not include DMX transfer time   transition = 2, } local tsuffix = '_transition' -- match range local function range(val, min, max)   return min <= val and val <= max end -- value setter function set(chan, val, skey)   skey = skey or defaults.skey   chan = tonumber(chan) or 0   val = tonumber(val) or -1   -- validate channel number and value   if range(chan, 1, 512) and range(val, 0, 255) then     storage.exec('lset', skey, chan - 1, val)   end end -- value setter function settransition(chan, val, tr, skey)   local tkey   skey = skey or defaults.skey   chan = tonumber(chan) or 0   val = tonumber(val) or -1   tr = tonumber(val) or -1   -- validate channel number and value   if range(chan, 1, 512) and range(val, 0, 255) and range(tr, 0, 255) then     tkey = skey .. tsuffix     storage.exec('lset', skey, chan - 1, val)     storage.exec('lset', tkey, chan - 1, tr)   end end -- value getter function get(chan, skey)   local res, val   skey = skey or defaults.skey   chan = tonumber(chan) or 0   -- validate channel number and value   if chan >= 1 and chan <= 512 then     res = storage.exec('lrange', skey, chan - 1, chan - 1)     if type(res) == 'table' then       val = tonumber(res[ 1 ])     end   end   return val end -- DMX init, returns new DMX object function init(params)   local n, k, v, _   -- create metatable and set user parameters   n = setmetatable({}, { __index = DMX })   n.params = params or {}   _, n.conn = pcall(require('redis').connect)   -- merge parameters that are set by user   for k, v in pairs(defaults) do     if n.params[ k ] == nil then       n.params[ k ] = v     end   end   n:reset()   return n end function DMX:reset()   local params, skey, tkey, transition, err   params = self.params   skey = params.skey   tkey = skey .. tsuffix   transition = params.transition   self.dm, err = luadmx.open(params.port)   -- error while opening   if err then     os.sleep(1)     error(err)   end   -- set channel count   self.dm:setcount(params.channels)   -- calculate sleep time   self.sleep = 1 / params.resolution   -- reset channel map   self.channels = {}   -- empty channel value map   self.conn:ltrim(skey, 1, 0)   self.conn:ltrim(tkey, 1, 0)   -- fill channel map   for chan = 1, params.channels do     self.channels[ chan ] = { current = 0, target = 0, ticks = 0 }     -- turn off by default, set default transition     self.conn:lpush(skey, 0)     self.conn:lpush(tkey, transition)     self.dm:setchannel(chan, 0)   end end -- get new values function DMX:getvalues()   local skey, tkey, max, channels, values, transition, val, tr, ticks   skey = self.params.skey   tkey = skey .. tsuffix   max = self.params.channels   channels = self.channels   values = self.conn:lrange(skey, 0, max - 1) or {}   transitions = self.conn:lrange(tkey, 0, max - 1) or {}   -- check for new values for each channel   for chan = 1, max do     val = tonumber(values[ chan ]) or 0     tr = tonumber(transitions[ chan ]) or 0     ticks = math.max(1, tr * self.params.resolution)     -- target value differs, set transcation     if val ~= channels[ chan ].target then       channels[ chan ].target = val       channels[ chan ].delta = (channels[ chan ].target - channels[ chan ].current) / ticks       channels[ chan ].ticks = ticks     end   end end -- main loop handler function DMX:run()   self:getvalues()   -- transition loop   for i = 1, self.params.resolution do     self:step()     self.dm:send()     os.sleep(self.sleep)   end end -- single transition step function DMX:step()   local chan, channels, t   channels = self.channels   -- transition for each channel   for chan = 1, self.params.channels do     t = channels[ chan ].ticks     -- transition is active     if t > 0 then       t = t - 1       channels[ chan ].current = channels[ chan ].target - channels[ chan ].delta * t       channels[ chan ].ticks = t       self.dm:setchannel(chan, channels[ chan ].current)     end   end end



RE: DMX.set with more options - Christian_EWW - 11.08.2020

Thanks a lot, sems to work.
Line 150 should be: ticks = math.max(1, tr * self.params.resolution)