serial.rb 파일 호출 방식으로 변경
This commit is contained in:
parent
f9cdd77e7a
commit
fed1b75fd2
1
Gemfile
1
Gemfile
|
|
@ -69,4 +69,5 @@ group :test do
|
||||||
gem "selenium-webdriver"
|
gem "selenium-webdriver"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
gem "ccutrer-serialport"
|
||||||
gem "rmodbus"
|
gem "rmodbus"
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,8 @@ GEM
|
||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.6.3)
|
||||||
regexp_parser (>= 1.5, < 3.0)
|
regexp_parser (>= 1.5, < 3.0)
|
||||||
xpath (~> 3.2)
|
xpath (~> 3.2)
|
||||||
|
ccutrer-serialport (1.1.0)
|
||||||
|
ffi (~> 1.9, >= 1.9.3)
|
||||||
concurrent-ruby (1.3.5)
|
concurrent-ruby (1.3.5)
|
||||||
connection_pool (2.5.0)
|
connection_pool (2.5.0)
|
||||||
crass (1.0.6)
|
crass (1.0.6)
|
||||||
|
|
@ -126,6 +128,7 @@ GEM
|
||||||
erubi (1.13.1)
|
erubi (1.13.1)
|
||||||
et-orbi (1.2.11)
|
et-orbi (1.2.11)
|
||||||
tzinfo
|
tzinfo
|
||||||
|
ffi (1.17.2-aarch64-linux-gnu)
|
||||||
foreman (0.88.1)
|
foreman (0.88.1)
|
||||||
fugit (1.11.1)
|
fugit (1.11.1)
|
||||||
et-orbi (~> 1, >= 1.2.11)
|
et-orbi (~> 1, >= 1.2.11)
|
||||||
|
|
@ -387,6 +390,7 @@ DEPENDENCIES
|
||||||
bootsnap
|
bootsnap
|
||||||
brakeman
|
brakeman
|
||||||
capybara
|
capybara
|
||||||
|
ccutrer-serialport
|
||||||
cssbundling-rails
|
cssbundling-rails
|
||||||
debug
|
debug
|
||||||
erb_lint
|
erb_lint
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
# Modbus::Service.new(plc_id: 1, type: "bit_coil", start_address: 0, end_address: 15).execute
|
|
||||||
module Modbus
|
|
||||||
module Commands
|
|
||||||
def bit_coil(slave)
|
|
||||||
read_bit(slave, :read_coils)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
# Modbus::Service.new(plc_id: 1, type: "bit_input", start_address: 0, end_address: 15).execute
|
|
||||||
module Modbus
|
|
||||||
module Commands
|
|
||||||
def bit_input(slave)
|
|
||||||
read_bit(slave, :discrete_inputs)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
# Modbus::Service.new(plc_id: 1, type: "word_holding_float32", start_address: 0, end_address: 15).execute
|
|
||||||
module Modbus
|
|
||||||
module Commands
|
|
||||||
def word_holding_float32(slave)
|
|
||||||
read_float(slave, :holding_registers)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
# Modbus::Service.new(plc_id: 1, type: "word_holding_int16", start_address: 16, end_address: 31).execute
|
|
||||||
module Modbus
|
|
||||||
module Commands
|
|
||||||
def word_holding_int16(slave)
|
|
||||||
read_int(slave, 16, :holding_registers)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
# Modbus::Service.new(plc_id: 1, type: "word_input_float32", start_address: 0, end_address: 15).execute
|
|
||||||
module Modbus
|
|
||||||
module Commands
|
|
||||||
def word_input_float32(slave)
|
|
||||||
read_float(slave, :input_registers)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
# Modbus::Service.new(plc_id: 1, type: "word_input_int16", start_address: 0, end_address: 15).execute
|
|
||||||
module Modbus
|
|
||||||
module Commands
|
|
||||||
def word_input_int16(slave)
|
|
||||||
read_int(slave, 16, :input_registers)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
# Modbus::Service.new(plc_id: 1, type: "write_bit", start_address: 0, value: 1).execute
|
|
||||||
module Modbus
|
|
||||||
module Commands
|
|
||||||
def write_bit(slave)
|
|
||||||
write_coil(slave)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
# Modbus::Service.new(plc_id: 1, type: "write_bit_toggle", start_address: 0).execute
|
|
||||||
module Modbus
|
|
||||||
module Commands
|
|
||||||
def write_bit_toggle(slave)
|
|
||||||
write_toggle_coil(slave)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
# Modbus::Service.new(plc_id: 1, type: "float32", start_address: 0, value: 123.45).execute
|
|
||||||
module Modbus
|
|
||||||
module Commands
|
|
||||||
def write_float32(slave)
|
|
||||||
write_float(slave)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
# Modbus::Service.new(plc_id: 1, type: "int16", start_address: 0, value: 123).execute
|
|
||||||
module Modbus
|
|
||||||
module Commands
|
|
||||||
def write_int16(slave)
|
|
||||||
write_int(slave, 16)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
# 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
|
|
||||||
|
|
@ -15,17 +15,15 @@ module Modbus
|
||||||
if current_hour != last_logged_hour && now.min == 0
|
if current_hour != last_logged_hour && now.min == 0
|
||||||
schedule = Schedule.find_by(hour: current_hour)
|
schedule = Schedule.find_by(hour: current_hour)
|
||||||
|
|
||||||
Modbus::Service.new(
|
serial_path = Rails.root.join("serial.rb")
|
||||||
type: "write_int16",
|
system("ruby", serial_path.to_s, "#{schedule.temperature * 10}")
|
||||||
start_address: 2,
|
|
||||||
end_address: 2,
|
|
||||||
value: schedule.temperature * 10
|
|
||||||
).execute
|
|
||||||
puts "[Schedule] #{current_hour}:00 -> Target temp: #{schedule.temperature}°C"
|
puts "[Schedule] #{current_hour}:00 -> Target temp: #{schedule.temperature}°C"
|
||||||
last_logged_hour = current_hour
|
last_logged_hour = current_hour
|
||||||
end
|
end
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
error_message = "[#{Time.current}] 오류: #{e.message}"
|
error_message = "[#{Time.current}] 오류: #{e.message}"
|
||||||
|
|
||||||
puts error_message
|
puts error_message
|
||||||
ensure
|
ensure
|
||||||
sleep 0.1
|
sleep 0.1
|
||||||
|
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
require_relative "operations"
|
|
||||||
|
|
||||||
Dir[File.join(__dir__.to_s, "commands", "**", "*.rb")].each do |file|
|
|
||||||
load file
|
|
||||||
end
|
|
||||||
|
|
||||||
class Modbus::Service
|
|
||||||
include Modbus::Operations
|
|
||||||
include Modbus::Commands
|
|
||||||
|
|
||||||
def initialize(type:, start_address:, end_address: nil, value: nil)
|
|
||||||
@type = type
|
|
||||||
@start_address = start_address.to_i
|
|
||||||
@end_address = end_address&.to_i
|
|
||||||
@value = value
|
|
||||||
@slave_id = 1
|
|
||||||
@plc_host = "rubyon.co.kr"
|
|
||||||
@plc_port = 502
|
|
||||||
end
|
|
||||||
|
|
||||||
def execute
|
|
||||||
ModBus::TCPClient.new(@plc_host, @plc_port) do |client|
|
|
||||||
client.with_slave(@slave_id) do |slave|
|
|
||||||
method_name = @type.strip
|
|
||||||
# Commands 모듈에 정의된 메서드만 허용
|
|
||||||
if Modbus::Commands.instance_methods(false).include?(method_name.to_sym)
|
|
||||||
return send(method_name, slave)
|
|
||||||
else
|
|
||||||
available_commands = Modbus::Commands.instance_methods(false).sort.map(&:to_s)
|
|
||||||
command_list = available_commands.join("\r\n")
|
|
||||||
raise ArgumentError, "지원되지 않는 type: #{@type}\r\n사용 가능한 명령어 목록:\r\n#{command_list}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
rescue => e
|
|
||||||
Rails.logger.error "[#{Time.current}] Service 오류: #{e.message}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
require "rmodbus"
|
||||||
|
require "ccutrer-serialport"
|
||||||
|
|
||||||
|
value = ARGV[0]&.to_i
|
||||||
|
|
||||||
|
ModBus::RTUClient.new("/dev/ttyUSB0", 9600) do |cl|
|
||||||
|
cl.with_slave(7) do |slave|
|
||||||
|
regs = slave.holding_registers
|
||||||
|
regs[2] = value
|
||||||
|
sleep 0.1
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in New Issue