class LXP::Packet::Base
Attributes
chksum[RW]
2 bytes
data[RW]
usually 16 bytes?
header[RW]
20 bytes
Public Class Methods
new()
click to toggle source
# File lib/lxp/packet/base.rb, line 18 def initialize @header ||= [0] * 20 @data ||= [0] * 16 @chksum ||= [0, 0] # prefix @header[0] = 161 @header[1] = 26 self.protocol = 1 self.packet_length = 32 @header[6] = 1 # unsure, always seems to be 1 end
parse(ascii)
click to toggle source
# File lib/lxp/packet/base.rb, line 43 def self.parse(ascii) # array of integers bdata = ascii.unpack('C*') raise 'invalid packet' if bdata[0] != 161 || bdata[1] != 26 i = new # header is always 20 bytes i.header[0, 20] = bdata[0, 20] # data can vary from 17 bytes upwards i.data = bdata[20, i.data_length - 2] # -2, don't copy checksum raise 'bad data length' unless i.data.length != i.data_length # calculate checksum and compare to input i.update_checksum raise 'invalid checksum' if i.chksum != bdata[-2..-1] i end
Public Instance Methods
bytes()
click to toggle source
# File lib/lxp/packet/base.rb, line 34 def bytes update_checksum header + data + chksum end
data_length()
click to toggle source
# File lib/lxp/packet/base.rb, line 100 def data_length @header[18] | @header[19] << 8 end
data_length=(data_length)
click to toggle source
# File lib/lxp/packet/base.rb, line 104 def data_length=(data_length) @header[18] = data_length & 0xff @header[19] = (data_length >> 8) & 0xff end
datalog_serial()
click to toggle source
# File lib/lxp/packet/base.rb, line 91 def datalog_serial @header[8, 10].pack('C*') end
datalog_serial=(datalog_serial)
click to toggle source
Passed as a string
# File lib/lxp/packet/base.rb, line 96 def datalog_serial=(datalog_serial) @header[8, 10] = datalog_serial.bytes end
device_function()
click to toggle source
# File lib/lxp/packet/base.rb, line 109 def device_function @data[1] end
device_function=(device_function)
click to toggle source
# File lib/lxp/packet/base.rb, line 113 def device_function=(device_function) @data[1] = device_function end
inverter_serial()
click to toggle source
# File lib/lxp/packet/base.rb, line 117 def inverter_serial @data[2, 10].pack('C*') end
inverter_serial=(inverter_serial)
click to toggle source
Passed as a string
# File lib/lxp/packet/base.rb, line 122 def inverter_serial=(inverter_serial) @data[2, 10] = inverter_serial.bytes end
packet_length()
click to toggle source
# File lib/lxp/packet/base.rb, line 74 def packet_length @header[4] | @header[5] << 8 end
packet_length=(packet_length)
click to toggle source
# File lib/lxp/packet/base.rb, line 78 def packet_length=(packet_length) @header[4] = packet_length & 0xff @header[5] = (packet_length >> 8) & 0xff end
protocol()
click to toggle source
# File lib/lxp/packet/base.rb, line 65 def protocol @header[2] | @header[3] << 8 end
protocol=(protocol)
click to toggle source
# File lib/lxp/packet/base.rb, line 69 def protocol=(protocol) @header[2] = protocol & 0xff @header[3] = (protocol >> 8) & 0xff end
register()
click to toggle source
# File lib/lxp/packet/base.rb, line 126 def register @data[12] | @data[13] << 8 end
register=(register)
click to toggle source
# File lib/lxp/packet/base.rb, line 130 def register=(register) @data[12] = register & 0xff @data[13] = (register >> 8) & 0xff end
tcp_function()
click to toggle source
# File lib/lxp/packet/base.rb, line 83 def tcp_function @header[7] end
tcp_function=(tcp_function)
click to toggle source
# File lib/lxp/packet/base.rb, line 87 def tcp_function=(tcp_function) @header[7] = tcp_function & 0xff end
to_bin()
click to toggle source
# File lib/lxp/packet/base.rb, line 39 def to_bin bytes.pack('C*') end
update_checksum()
click to toggle source
# File lib/lxp/packet/base.rb, line 165 def update_checksum chksum = crc16_modbus(data) @chksum[0] = chksum & 0xff @chksum[1] = (chksum >> 8) & 0xff end
value=(value)
click to toggle source
this only makes sense for protocol 1 at the moment. for 2 we'd need to append to an array, and not sure that is even used (sending an array of values to inverter) (maybe with W_MULTI?)
# File lib/lxp/packet/base.rb, line 158 def value=(value) raise 'cannot set value with protocol 2 yet' if protocol == 2 @data[14] = value & 0xff @data[15] = (value >> 8) & 0xff end
value_length()
click to toggle source
# File lib/lxp/packet/base.rb, line 135 def value_length if value_length_byte? @data[14] else 2 end end
values()
click to toggle source
protocol 1 has value at 14 and 15 protocol 2 has length at 14, then that many bytes of values
# File lib/lxp/packet/base.rb, line 146 def values if value_length_byte? @data[15, value_length] else @data[14, 2] # | @data[15] << 8 end end
Private Instance Methods
crc16_modbus(arr)
click to toggle source
# File lib/lxp/packet/base.rb, line 179 def crc16_modbus(arr) arr.length.times.inject(0xffff) do |r, n| r ^= arr[n] 8.times do t = r >> 1 r = (r & 1).positive? ? 40_961 ^ t : t end r end end
value_length_byte?()
click to toggle source
# File lib/lxp/packet/base.rb, line 173 def value_length_byte? @value_length_byte ||= protocol == 2 && device_function != DeviceFunctions::WRITE_SINGLE end