This is an old revision of the document!
Helvar light control communication protocol
Please refer to the HelvarNet communication protocol for usage. This protocol is using ASCII messaging. According to the documentation the routers in the lighting system support either ASCII or RAW format.
Message Format Any message sent to, or received from, a router can be in either ASCII or raw binary form (see Command Format for more information). Messages must not exceed the maximum length of 1500 bytes. The format of the data contained within messages is defined by the protocol. A query reply message from the router will be in the same format as the query command message sent i.e. if a query message is sent in ASCII form then the reply will also be in ASCII.
The usage of this protocol is as follows:
- Your application logic, e.g. recipe selection boxes on the dashboards chooses scenario id and writes it to the register
- Lua script monitors scenes ids written and converts them to the strings according to the HelvarNet protocol
For example, in the command Recall Group 1234, Block 5, Scene 6, Fade Time 32 s, the string is sent as follows, including the delimiters and the start character '>' and stop character '#': “>V:1,C:11,G:1234,B:5,S:6,F:3200#”
- So the string like “>V:1,C:11,G:1234,B:5,S:6,F:3200#” should be written to the register named CMD0 in the project.
- Once the string is written to the CMD0 register, it is sent to the remote device to the TCP port assigned in the connection settings.
- The response (which can be multipart) is stored in the same register
-- delimiters PARTIAL_ETX = '$' FULL_ETX = '#' function onScanStart () now = os.time() end function createDevices () addDevice{name = "CMD", shift = 0, base = 10, xtraFields = {} } end function readRegister (reg, device, unitId) if (not readBuffer) then readBuffer = 'no data' end return readBuffer -- will be assinged in writeRegister end function writeRegister (reg, device, unitId, newValue) sendString_(newValue) -- expects string to be written externally local buf = {} repeat local currentFrame = readUntil(PARTIAL_ETX, FULL_ETX) local lastChar if currentFrame then table.insert(buf, currentFrame) lastChar = currentFrame[#currentFrame] end until (not lastChar or (lastChar == FULL_ETX)) if (#buf > 0) then for i, row in ipairs (buf) do readBuffer[i] = table.concat(row) end readBuffer = table.concat(readBuffer) end return true end -------------------------- Helpers -------------------------- function sendString_(s) -- new sendString version local sendBuf = {} for i = 1, #s do table.insert(sendBuf, s : byte(i) ) end sendBytes(sendBuf) end function readUntil(endByte1, endByte2) -- read input buffer untils endByte(s) or timeout local ONE_BYTE = 1 local buf = {} repeat local rb = readBytes(ONE_BYTE) if rb then rb = rb[ONE_BYTE] table.insert(buf, rb) end until (not rb or (rb == endByte1 or rb == endByte2)) return ((#buf >= ONE_BYTE) and buf) or false end