![]() |
|
Modbus mappings automation - 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: Modbus mappings automation (/showthread.php?tid=6054) |
Modbus mappings automation - pawel200388 - 21.07.2025 Hi, I strive to add a funtion to automatically map modbus registers to selected group addresses. Code: function mapModbusRegisterToKnx(knxGA, regNum, regType, valueBitmask)
local sql = string.format(
"SELECT id FROM modbus_mapping WHERE type='%s' AND address=%d",
regType, reg
)
local rows = db:getall(sql)
if not rows or #rows == 0 then
return false
end
local updateFields = {
bus_address = gaDec,
bus_write = 1,
value_delta = 0.1,
value_custom = "rfid"
}
if valueBitmask ~= nil then
updateFields.value_bitmask = valueBitmask
end
for _, rec in ipairs(rows) do
db:update("modbus_mapping", updateFields, { id = rec.id })
log(("✅ Zaktualizowano Modbus %s[%d] → KNX %s (id=%d)%s")
:format(
regType, reg, knxGA, rec.id,
valueBitmask and (", bitmask=" .. tostring(valueBitmask)) or ""
)
)
end
endThe problem it works for registers without bitmask: Code: mapModbusRegisterToKnx("60/0/93",1299,"register")but I can't figure out how to make it to work with bitmasks: Code: mapModbusRegisterToKnx("60/0/94",1300,"register", "0x01")
mapModbusRegisterToKnx("60/0/95",1300,"register", "0x02")RE: Modbus mappings automation - admin - 21.07.2025 1. Don't modify value_bitmask, change the SELECT statement to look for a specific value_bitmask if specified. 2. Remove quotes around hexadecimal numbers (0x01 instead of "0x01"). 3. value_custom = "rfid"[/b] is not a valid custom value. 4. If you have multiple Modbus devices then all devices with matching registers will be mapped to the same group address. RE: Modbus mappings automation - pawel200388 - 21.07.2025 Hello admin, thank you for your fast response. This code is part of a larger solution, in which in the first step I add group addresses, in the second I create a modbus device and attach a status object to it, and in the third I map selected points. It's a kind of "wizard" for my customers. 1. Ok, perfect. I changed it to: Code: (...)
if valueBitmask ~= nil then
sql = string.format(
"SELECT id FROM modbus_mapping WHERE type='%s' AND address=%d AND value_bitmask='%s'",
regType, regNum, valueBitmask
)
else
sql = string.format(
"SELECT id FROM modbus_mapping WHERE type='%s' AND address=%d",
regType, regNum
)
end
(...)
local rows = db:getall(sql)2. In fact I tried it as a hex. Now I have conversions, so both versions are OK ![]() 3. I know, it was temporary. It's a kind of note that shows me where changes in the database have been saved and where they haven't. 4. Unfortunately I know. For now 1 device is enough, but in the future I'l have to rebuild the code to support more modbus devices. I assume I'll use the device column somehow. Lastly... 5. Is there any simple way to clear modbus_mapping table? I have some rubbish left there.6. As I can see modbus doesn't start on its own. For now my solution was to automatically reboot it, but maybe there is other way? RE: Modbus mappings automation - admin - 21.07.2025 5. Run this once: Code: db:query('DELETE FROM modbus_mapping')6. You can send reload signal to Modbus daemon after making changes to the modbus_mapping DB table: Code: pid = os.checkproc('gs-modbus')
if pid then
os.kill(pid, signal.SIGUSR1)
end |