CANx library

CANx scripting library #

Load the library:

local canx = require('applibs.canx')

Library functions #

find(alias) #

Returns a single object for the given alias. Object value will be decoded if data type is set. Alias can either be an object name or group address.

object = canx.find('My object')
object = canx.find('1/1/1')

getvalue(alias) #

Returns value for the given alias or nil when the object cannot be found. Alias can either be an object name or group address.

value = canx.getvalue('My object')
value = canx.getvalue('1/1/1')

read(alias) #

Sends а group read request to the given alias. Note: this function returns immediately and cannot be used to return the result of the read request. Use event-based script instead. Alias can either be an object name, group address or direct object address.

canx.read('My object')
canx.read('1/1/1')
canx.read('0.1.2')

write(alias, val [, dpt]) #

Sends а group write request to the given alias. Returns boolean as the result. Alias can either be an object name, group address or direct object address. Data type is required for direct object addressing, otherwise it is taken from the database if not specified as the third parameter

canx.write('My object', 1234)
canx.write('1/1/1', false, 'bool')
canx.write('0.1.2', 12.34, 'float')

response(alias, val [, dpt]) #

Similar to write. Sends а group response request to the given alias.

canx.response('My object', 1234)
canx.response('1/1/1', false, 'bool')
canx.response('0.1.2', 12.34, 'float')

update(alias, val [, dpt]) #

Similar to write. No bus write is performed.


checkwrite(alias, newvalue [, mindelta [, status]) #

checkresponse(alias, newvalue [, mindelta [, status]) #

checkupdate(alias, newvalue [, mindelta [, status]) #

Sends a new value to the given alias but only when the new value differs from the current value. For numeric type minimum delta can be set, the default delta is 0.1. An additional status object alias can be provided, in this case the status object value is compared with the new value.

Low-level functions #

sendrequest(request) #

Sends a request to the bus.

Common request table fields:

  • command – number (0..15, see table below for available command constants)

  • data – optional, possible types:

    • nil – no data is sent
    • boolean – send single byte (1 for true, 0 for false)
    • number – send single byte (0..255)
    • string – send as is, up to 8 bytes
    • table – array of bytes to send (0..255), up to 8 elements

Request table fields for group communication:

  • groupaddress – number (0..65535)
  • filter – boolean, set filter bit for group communication

Request table fields for device communication:

  • lineid – number (0..15)
  • nodeid – number (0..255)
  • objectid – number (0..255)

getlistener([timeout]) #

Creates a new bus listener. Must be done once per app and before any step calls. Timeout is in seconds. By default no timeout is set, calling step blocks until a new CANx message arrives.


step(rx_callback, reload_callback) #

Waits for a new CAN message. rx_callback function is executed when a new CAN message arrives. Function returns after callback has been executed or a timeout occurs. Rx callback receives one argument which is a table in the same format as for sendrequest with additional fields:

  • isgroup – boolean true when communication is group-based
  • frombus – boolean true when message came from the bus, false when other local application sent it
  • fromextbus – boolean true when message came from an external bus
  • frombridge – boolean true when message came from a bridge connection

Note: data field can be nil if message contains no data.

Optional reload_callback is executed if any changes to the internal database have been made.


groupstep(rx_callback, reload_callback) #

Similar to step, but rx callback function is executed only for group requests. Sets type field for callback data depending on request type: either read, write or response.

Examples #

Toggle on-board LED on device 0.1 #

canx = require('applibs.canx')
cmd = canx.cmds.device.ledset
req = {
  lineid = 0,
  nodeid = 1,
  objectid = 0,
  command = cmd
}

while true do
  req.data = not req.data
  canx.sendrequest(req)
  os.sleep(0.5)
end

Group monitor #

canx = require('applibs.canx')
canx.getlistener(1) -- create listener with 1 second timeout
while true do
  canx.groupstep(function(msg)
    -- group communication to address 1, has data
    if msg.groupaddress == 1 and msg.data then
      grp.write('1/1/1', msg.data:byte(1, 1), dt.bool)
    end
  end)
end

CANx command constants #

object.valueread = 0
object.valueresponse = 1
object.valuewrite = 2
object.inforead = 3
object.inforesponse = 4
object.configwrite = 5
object.galistadd = 6
object.galistdel = 7
object.galistclear = 8
object.cmdresponse = 9
object.galistread = 10
object.galistresponse = 11
device.inforead = 0
device.inforesponse = 1
device.addrrequest = 2
device.addrwrite = 3
device.addrresponse = 4
device.modeset = 9
device.moderesponse = 10
device.ledset = 11
device.debug = 12
device.extinforead = 13
device.extinforesponse = 14
group.valueread = 0
group.valueresponse = 1
group.valuewrite = 2
broadcast.securemodeoff = 0
broadcast.securemodegaonly = 1
broadcast.securemodeencrypt = 2
broadcast.lora = 3
broadcast.dali = 3