This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

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
------------------------------
Ctrl+F5
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/
------------------------------
Ctrl+F5
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:
12
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.
------------------------------
Ctrl+F5
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:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
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
------------------------------
Ctrl+F5
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
------------------------------
Ctrl+F5
Reply
#17
thanks a lot ! now everything works fine Smile
Reply
#18
I've tried to use this modbus TCP slave script and it works perfectly but only when other LM which is master reads by a script it doesn't work via mapper.
The minimum version of profile which I've tested:

Code:
1234567
{   "manufacturer": "PEGO", "description": "LM4",   "mapping": [     { "bus_address": "32/2/0", "name": "Room humidity", "bus_datatype": "uint16", "type": "register", "datatype": "uint16", "address": 0, "units": "%" }   ] }


This is the first part of slave script from LM4:
Code:
123456789101112
if not mb then  require('genohm-scada.eibdgm')  require('luamodbus')  -- list of coil mapping, starting from 0  coils = {  }  -- list of register mapping, starting from 0  registers = { '32/2/0' }       -- list of register data types, element count must match registers table  regdt = { dt.uint16 }

This is currently used master script (it is working very nice, i let only 1 address):
Code:
123456789101112131415161718192021222324252627282930313233343536373839404142434445
require('json') require('luamodbus') mb = luamodbus.tcp() mb:open('192.168.2.17') mb:connect() -- verbose output and select slave number 1 mb:setdebug(true) mb:setslave(1) pego_1_profile_json = [[{  "manufacturer": "PEGO", "description": "PEGO_Goscinna",  "mapping": [     { "bus_address": "32/2/0", "name": "Room humidity", "bus_datatype": "uint16", "type": "register", "datatype": "uint16", "address": 0, "units": "%" } ]}]] function readAndUpdatePEGOGAs(pego_profiles)   for i, profile in ipairs(pego_profiles) do     pego_profile = json.decode(profile)     for k,v in ipairs(pego_profile.mapping) do              value, err = mb:readregistervalue(v.address, v.datatype, 'n')              if v.value_multiplier == 0.1 then delta = 0.1 else delta = 1 end       grp.checkwrite(v.bus_address, value, delta)            end   end end pego_profiles = {pego_1_profile_json} readAndUpdatePEGOGAs(pego_profiles) -- close serial connection mb:close() -- wait 5 seconds before next read os.sleep(5)


So currently I am working with above script but I want switch it to the mapper. But in above mapper settings it's not working e.g. when I change value on slave it isn't changed by new read on master. Maybe some advice from some experienced Modbus TCP user? Wink

P.S. No, two scripts don't working in same timeWink

Attached Files Thumbnail(s)
   
Done is better than perfect
Reply
#19
Do you have mb:setslave(1) call in slave script? Anyway, I would not use modbus to connect two LMs :)
Reply
#20
(01.03.2018, 08:20)admin Wrote: Do you have mbConfusedetslave(1) call in slave script? Anyway, I would not use modbus to connect two LMs Smile

I've tried both with and without defining slave ID. It works by script but not mapper.

I also not preferring but unfortunately, for some time I cannot use KNX IP because I have also some others KNX routers which could pass telegrams to KNX TP and now I am working on integration with PEGO humidifiers and I have round about 140 new GAs and perfectly is when they are in virtual GAs range on 2 LMs. I thinked about BACNET but I have LM LB and currently I haven't BACNET library on it. But BACNET would be another system... I've sent you yesterday ask about BACNET library, if you can please send meWink

But what is your solution when you want sent some maybe bigger data(in 2 ways) between LMs and you don't want use normal KNX?
Done is better than perfect
Reply


Forum Jump: