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.

HDL Buspro gateway integration with LM5
#1
Dear Admin,

I found the gateway example for HDL Buspro product.https://openrb.com/example-hdl-integrati...rough-lm2/
I am not sure if LM5 can use this script as a tool to connect the HDL product "HDL-MHRCU.433".
Or some modifications need to be taken for this script?
And I can't find out related "Add the following script in Scripting -> Tools -> User function library"

More details about this product" HDL-MHRCU.433 ", please refer to the PDF attachment .
.pdf   HDL Buspro_Home Control Unit.pdf (Size: 589.44 KB / Downloads: 11)


Thank you very much for your time.

Best regards.
Reply
#2
It should work unless HDL changed their protocol.

The script is slightly outdated, this line:
Code:
require('crc16')
Should be replaced with this:
Code:
crc16 = require('encdec').crc16
Reply
#3
(14.02.2023, 07:53)admin Wrote: It should work unless HDL changed their protocol.

The script is slightly outdated, this line:
Code:
require('crc16')
Should be replaced with this:
Code:
crc16 = require('encdec').crc16

Dear Admin, Thanks a lot. I will test it later.
Reply
#4
Dear Admin,

I have tested the script for several times, but still no response from HDL side.

I am not sure if I put the script at the right way and right place---"Add the following script in Scripting -> Tools -> User function library", more details, please refer to picture.

I use HDL buspro tool to search or scan devices, but I can't find the Device ID for LM5 is 254. ID 254 is default for LM5?

Thanks!

Richard

Attached Files Thumbnail(s)
   
Reply
#5
LM won't be visible as a device on the HDL network. The example only allows to control HDL channels from scripts.
Reply
#6
Dear Admin,

I tried again to use LM5 to send switch on/off signal to HDL IP unit (IP Add.=192.168.1.37, Subnet=1 Device=0).
The HDL device (Subnet=1 Device=61) is 8 channels switch module, which also connects to HDL IP unit.


The script user.hdl is copied from example(openrb.com) , and  "require('crc16')" is replaced by "crc16 = require('encdec').crc16"
The event-based script also set up according to example(openrb.com) .


14/0/220 is created to test the script.
When I turn on 14/0/220, the following error happens
User library hdl:30: bad argument #1 to 'pdecode' (expected 1 argument)
stack traceback:
[C]: in function 'pdecode'
User library hdl:30: in function 'init'
User library hdl:99: in function 'encode'
User library hdl:137: in function 'chanreg'

I don't know what is the root cause and how to slove this problemHuh.

Attached Files Thumbnail(s)
   
Reply
#7
Try this updated library. Let us know if it works so we can update the example on our website.
Code:
local socket = require('socket')
local crc16 = require('encdec').crc16
local ifinfo = require('ifinfo')

HDL = {
  -- destination ip
  dstip = '192.168.0.2',
  -- packet constant data
  magic = 'HDLMIRACLE',
  lcode = string.char(0xAA, 0xAA),
  -- source device settings
  srcsubnet = 1,
  srcdevice = 254,
  devicetype = 0xFFFE,
  -- command types
  cmd = {
    chanreg = 0x0031, -- single channel regulate
    chanregreply = 0x0032, -- single channel regulate answerback
    chanstat = 0x0033, -- read status of single channel targets
    chanstatreply = 0x0034, -- single channel targets status answerback
  }
}

HDL.init = function()
  local info, chunk, chunks

  info = ifinfo()

  if not info or not info.eth0 then
    error('cannot get interface info')
  end

  -- ip header
  HDL.iphdr = ''
  -- broadcast address
  HDL.bcast = info.eth0.bcast

  -- split ip address into chunks
  chunks = info.eth0.inetaddr:split('.')

  -- add ip address chunks
  for i = 1, 4 do
    chunk = tonumber(chunks[ i ])
    HDL.iphdr = HDL.iphdr .. string.char(chunk)
  end
end

HDL.decode = function(packet)
  local len, data, src, crc

  -- primary header
  if packet:sub(5, 14) ~= HDL.magic then
    return nil, 'magic'
  end

  -- leading code
  if packet:sub(15, 16) ~= HDL.lcode then
    return nil, 'lcode'
  end

  -- get data length and check against
  len = packet:byte(17)
  if len and len + 16 ~= packet:len() then
    return nil, 'len'
  end

  -- get packet data and check crc
  data = packet:sub(17, len + 14)
  crc = packet:byte(len + 15) * 0x100 + packet:byte(len + 16)
  if crc16(data) ~= crc then
    return nil, 'crc'
  end

  -- return parsed packet
  return {
    srcip = string.format('%d.%d.%d.%d', packet:byte(1, 4)),
    srcsubnet = packet:byte(18),
    srcdevice = packet:byte(19),
    devicetype = (packet:byte(20) * 0x100 + packet:byte(21)),
    opcode = (packet:byte(22) * 0x100 + packet:byte(23)),
    dstsubnet = packet:byte(24),
    dstdevice = packet:byte(25),
    additional = packet:sub(26, len + 14)
  }
end

HDL.word = function(v)
  return string.char(bit.band(bit.rshift(v, 8), 0xFF), bit.band(v, 0xFF))
end

HDL.encode = function(cmd, dstsubnet, dstdevice, extra)
  local packet, len, crc, data

  -- perform init if required
  if not HDL.iphdr then
    HDL.init()
  end

  -- start packet: ip, magic and leading code
  packet = { HDL.iphdr, HDL.magic, HDL.lcode }
  -- base data
  data = string.char(HDL.srcsubnet, HDL.srcdevice) ..
    HDL.word(HDL.devicetype) ..
    HDL.word(cmd) ..
    string.char(dstsubnet, dstdevice)

  -- add extra data parameters
  if type(extra) == 'string' then
    data = data .. extra
  end

  -- calculate length and crc
  len = string.char(data:len() + 3)
  crc = crc16(len .. data)

  table.insert(packet, len)
  table.insert(packet, data)
  table.insert(packet, HDL.word(crc))

  return table.concat(packet)
end

HDL.send = function(packet)
  local client = socket.udp()
  client:sendto(packet, HDL.dstip, 6000)
end

HDL.chanreg = function(dstsubnet, dstdevice, chan, value, delay)
  local extra, packet
  delay = delay or 0

  if type(value) == 'boolean' then
    value = value and 100 or 0
  end

  extra = string.char(chan, value) .. HDL.word(delay)
  packet = HDL.encode(HDL.cmd.chanreg, dstsubnet, dstdevice, extra)

  HDL.send(packet)
end
Reply
#8
Dear Admin,

Excellent!!!
Problem is solved with this script!
Thanks a lot!

Richard
Reply


Forum Jump: