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:
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:
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:
{
  "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:
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:
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: