setup modbus tcp slave
#1
Can i setup  HL as  aslave by using a json file  under the modbus menu? or most i go true the lua script way?

i want to read out 4 tempatures from my knx, to the ventilation system via modbus.
if it possible iwant to trigger a forced vetliation command in the knx to the modbus to.
Reply
#2
Hi
Slave is only available as a script. Modbus tab works only as master.
https://forum.logicmachine.net/showthread.php?tid=181
BR
Reply
#3
it is enough just to add this script to "resident script", or do i have to add something in "common functions" ?
when i have this setup, i just add a event script like this ? and link it to my 0/1/0 (outdoortemp) :

value = event.getvalue()
mb = mbproxy.new()
mbConfusedetregisters(3, value)
Reply
#4
It is resident script with 0s interval, no need for event script. Yes just copy, setup all coils/registry/regdt/
Reply
#5
Modbus proxy works only in master mode. It is meant to share serial port between mapper and scripts. You don't need any additional scripts for that slave example, mapping between objects is done via configuration table.
Reply
#6
thanks for all answers!

So if want to read out the outdoortemp ga 0/1/0 (2 byte float value), to the modbus, should i type in to the coil mapping or register mapping?
Is there anything more i have to change except the ip-adress port, slavenumber ?

-- list of coil mapping, starting from 0
coils = { '1/1/1', '1/1/2' }

-- list of register mapping, starting from 0
registers = { '2/2/2', '3/3/3' }

-- list of register data types, element count must match registers table
regdt = { dt.int8, dt.uint16 }
Reply
#7
You don't need to change IP on LM side, script will automatically use whichever IP LM has. Port is set to 502 and no slave id is used by default, this can be adjusted as needed.

Coils are boolean values, so for temperature you need to use registers. You need to adjust regdt table, but keep in mind that float16 is KNX-specific data type and your Modbus master might not support it. Instead, you can use int16 value with a certain precision, either x10 or x100. For this, you need a simple script which multiplies float16 value and writes to int16 object.
Reply
#8
Ok, so i add int16 to the regdt.

How this little script look like? i have found some examples in the forum but its just for json profile.
sorry for all the questions.
Reply
#9
Attach event script to your float16 objects, change 1/2/3 to your int16 object
Code:
value = event.getvalue()
grp.update('1/2/3', value * 100)
Reply
#10
in the resident script? or make a new event script add the 0/1/0 and put the script there? i tried that and the temp value went crazy in the object view.
Reply
#11
(12.02.2018, 13:16)Patrik1985 Wrote: in the resident script? or make a new event script add the 0/1/0  and put the script there? i tried that and the temp value went crazy in the object view.

Crate new event based script which will be triggered by your outdoor temp. Paste this script there and create new object 1/2/3 as int16 and this new object should be in your modbus resident script.
Reply
#12
Hey! thanks for the help yesterday ! now the first 3 temps working fine not the 2 last, when i restart the script its gets all temps. But when the knx doing a update every 20min the last 2 values turn to 0 ?
Reply
#13
this is the script, its updating the 3 first register mapping data but not the 2 last. if i change order in them the values works. but still change the 2 last value to 0 after the update from knx. if i deactivate and activte the script, it shows again in the modbus till the next update. 



Code:
if not mb then
 require('genohm-scada.eibdgm')
 require('luamodbus')

 -- list of coil mapping, starting from 0
 coils = { '4/1/3', '6/1/3', '5/1/3' }

 -- list of register mapping, starting from 0
 registers = { '0/1/7', '0/1/8', '6/1/4', '4/1/7', '15/1/4' }

 -- list of register data types, element count must match registers table
 regdt = { dt.int8, dt.uint16, dt.int16, dt.bool }

 -- knx group write callback
 function knxgroupwrite(event)
   local value

   -- try to find matching coil
   for id, addr in ipairs(coils) do
     if event.dst == addr then
       value = knxdatatype.decode(event.datahex, dt.bool)
       mb:setcoils(id - 1, value)
     end
   end

   -- try to find matching register
   for id, addr in ipairs(registers) do
     if event.dst == addr then
       value = knxdatatype.decode(event.datahex, regdt[ id ])
       mb:setregisters(id - 1, value)
     end
   end
 end

 -- coil write callback
 function mbwritecoils(coil, value)
   local addr = coils[ coil + 1 ]
   if addr then
     grp.write(addr, value, dt.bool)
   end
 end

 -- register write callback
 function mbwriteregisters(register, value)
   local addr = registers[ register + 1 ]
   if addr then
     grp.write(addr, value, regdt[ register + 1])
   end
 end

 -- knx group monitor, handles group writes
 knxclient = eibdgm:new({ timeout = 0.1 })
 knxclient:sethandler('groupwrite', knxgroupwrite)

 -- modbus slave, listen on all interfaces and default port 502
 mb = luamodbus.tcp()
 mb:open('0.0.0.0', 502)

 -- setting slave id is optional
 -- mb:setslave(1)

 mb:setreceivetimeout(0,1)
 mb:setmapping(#coils, 0, #registers, 0)

 -- init coils
 for id, addr in ipairs(coils) do
   value = grp.getvalue(addr)
   mb:setcoils(id - 1, value)
 end

 -- init registers
 for id, addr in ipairs(registers) do
   value = grp.getvalue(addr)
   mb:setregisters(id - 1, value)
 end

 -- set callbacks for coil and register write
 mb:setwritecoilcb(mbwritecoils)
 mb:setwriteregistercb(mbwriteregisters)
end

-- handle modbus and knx
mb:handleslave()
knxclient:step()
Reply
#14
Hi
In line 12 you have dt.bool for the 4th registry. Boolean should be done as coil. If 4/1/7 is bool then move it to coil. For the 15/1/4 you didn't specify regdt at all.
BR
Reply
#15
okey, i tought i just put in what diffrent type data its could read .
So if all the is values is the same data ishould put in it like this ? one typ for every GA.

-- list of register data types, element count must match registers table
regdt = { dt.int16, dt.int16, dt.int16, dt.int16, dt.int16 }
Reply
#16
(13.02.2018, 11:39)Patrik1985 Wrote: okey, i tought i just put in what diffrent type data its could read .
So if all the is values is the same data ishould put in it like this ? one typ for every GA.

 -- list of register data types, element count must match registers table
 regdt = { dt.int16, dt.int16, dt.int16, dt.int16, dt.int16 }

yes
Reply
#17
thanks a lot ! now everything works fine Smile
Reply


Forum Jump: