farmitry_hvac/app/services/modbus/operations.rb

94 lines
2.5 KiB
Ruby

# app/lib/modbus/operations.rb
module Modbus
module Operations
# write method
def write_toggle_coil(slave)
with_timeout do
target_value = slave.read_coils(@start_address, 1).first == 0 ? 1 : 0
slave.coils[@start_address] = (target_value == 1)
loop do
break if slave.read_coils(@start_address, 1).first == target_value
sleep 0.1
end
end
end
def write_coil(slave)
with_timeout do
slave.coils[@start_address] = @value
loop do
break if slave.read_coils(@start_address, 1).first == @value
sleep 0.1
end
end
end
def write_int(slave, bits)
with_timeout do
regs = slave.holding_registers
if bits == 16
value = @value.present? ? @value.to_i : 123
regs[@start_address] = value
end
end
end
def write_float(slave)
with_timeout do
regs = slave.holding_registers
value = @value.present? ? @value.to_f : 123.45
regs[@start_address], regs[@start_address + 1] = [ value ].pack("f").unpack("v*")
end
end
# read method
def read_bit(slave, type)
with_timeout do
value = case type
when :read_coils
slave.read_coils(@start_address, @end_address - @start_address + 1)
when :discrete_inputs
slave.discrete_inputs[@start_address..@end_address]
else
# type code here
end
Rails.logger.info "[#{Time.current}] Read Bit (#{type}): #{value}"
value
end
end
def read_int(slave, bits, type)
with_timeout do
result = slave.send(type)
values = (@start_address..@end_address).map { |i| result[i] }
Rails.logger.info "[#{Time.current}] Read Float#{bits} (#{type}): #{values}"
values
end
end
def read_float(slave, type)
with_timeout do
result = slave.send(type)
values = []
(@start_address..@end_address).step(2) do |i|
raw = [ result[i], result[i + 1] ]
packed = raw.pack("v*")
float = packed.unpack("f")[0].round(2)
values << float
end
Rails.logger.info "[#{Time.current}] Read Float32 (#{type}): #{values.inspect}"
values
end
end
def with_timeout
seconds = ENV.fetch("OPERATION_TIME_OUT", 1).to_i
Timeout.timeout(seconds) do
yield
end
rescue Timeout::Error
Rails.logger.error "[#{Time.current}] TimeOut (#{seconds}s)"
end
end
end