Class: PlcAccess::Protocol::Mitsubishi::FxProtocol
- Inherits:
-
Protocol
- Object
- Protocol
- PlcAccess::Protocol::Mitsubishi::FxProtocol
show all
- Defined in:
- lib/plc_access/protocol/mitsubishi/fx_protocol.rb
Constant Summary
collapse
- STX =
"\u0002"
- ETX =
"\u0003"
- EOT =
"\u0004"
- ENQ =
"\u0005"
- ACK =
"\u0006"
- LF =
"\u000a"
- CR =
"\u000d"
- NAK =
"\u0015"
- DELIMITER =
"\r\n"
Constants inherited
from Protocol
Protocol::TIMEOUT
Instance Attribute Summary collapse
Attributes inherited from Protocol
#host, #log_level, #port
Instance Method Summary
collapse
Methods inherited from Protocol
#[], #[]=, #destination_ipv4, #get_bit_from_device, #get_from_devices, #get_word_from_device, #self_ipv4, #set_bit_to_device, #set_to_devices, #set_word_to_device
Constructor Details
#initialize(options = {}) ⇒ FxProtocol
Returns a new instance of FxProtocol.
43
44
45
46
47
48
49
50
51
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 43
def initialize(options = {})
super
@port = options[:port] || `ls /dev/tty.usb*`.split("\n").map(&:chomp).first
@pc_no = 0xff
@baudrate = 19_200
@station_no = 0
@wait_time = 0
@comm = nil
end
|
Instance Attribute Details
#baudrate ⇒ Object
Returns the value of attribute baudrate.
30
31
32
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 30
def baudrate
@baudrate
end
|
#pc_no ⇒ Object
Returns the value of attribute pc_no.
30
31
32
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 30
def pc_no
@pc_no
end
|
#station_no ⇒ Object
Returns the value of attribute station_no.
30
31
32
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 30
def station_no
@station_no
end
|
#wait_time ⇒ Object
Returns the value of attribute wait_time.
30
31
32
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 30
def wait_time
@wait_time
end
|
Instance Method Details
#available_bits_range(_device = nil) ⇒ Object
198
199
200
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 198
def available_bits_range(_device = nil)
1..256
end
|
#available_words_range(_device = nil) ⇒ Object
202
203
204
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 202
def available_words_range(_device = nil)
1..64
end
|
#body_for_get_bit_from_deivce(device) ⇒ Object
206
207
208
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 206
def body_for_get_bit_from_deivce(device)
body_for_get_bits_from_device 1, device
end
|
#body_for_get_bits_from_device(count, device) ⇒ Object
210
211
212
213
214
215
216
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 210
def body_for_get_bits_from_device(count, device)
body = header_with_command 'BR'
body += "#{device.name}#{count.to_s(16).rjust(2, '0')}"
body += check_sum(body)
body += DELIMITER
body.upcase
end
|
#body_for_get_words_from_device(count, device) ⇒ Object
218
219
220
221
222
223
224
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 218
def body_for_get_words_from_device(count, device)
body = header_with_command 'WR'
body += "#{device.name}#{count.to_s(16).rjust(2, '0')}"
body += check_sum(body)
body += DELIMITER
body.upcase
end
|
#body_for_set_bits_to_device(bits, device) ⇒ Object
Also known as:
body_for_set_bit_to_device
226
227
228
229
230
231
232
233
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 226
def body_for_set_bits_to_device(bits, device)
body = header_with_command 'BW'
body += "#{device.name}#{bits.count.to_s(16).rjust(2, '0')}"
body += bits.map { |b| b ? '1' : '0' }.join('')
body += check_sum(body)
body += DELIMITER
body.upcase
end
|
#body_for_set_words_to_device(words, device) ⇒ Object
236
237
238
239
240
241
242
243
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 236
def body_for_set_words_to_device(words, device)
body = header_with_command 'WW'
body += "#{device.name}#{words.count.to_s(16).rjust(2, '0')}"
body += words.map { |w| w.to_s(16).rjust(4, '0') }.join('')
body += check_sum(body)
body += DELIMITER
body.upcase
end
|
#close ⇒ Object
74
75
76
77
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 74
def close
@comm&.close
@comm = nil
end
|
#device_by_name(name) ⇒ Object
173
174
175
176
177
178
179
180
181
182
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 173
def device_by_name(name)
case name
when String
d = FxDevice.new name
d.valid? ? d : nil
else
name
end
end
|
#dump_packet(packet) ⇒ Object
245
246
247
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 245
def dump_packet(packet)
packet.inspect
end
|
#get_bits_from_device(count, device) ⇒ Object
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 79
def get_bits_from_device(count, device)
unless available_bits_range.include? count
raise ArgumentError,
"A count #{count} must be between #{available_bits_range.first} and #{available_bits_range.last} for #{__method__}"
end
device = device_by_name device
packet = body_for_get_bits_from_device(count, device) + DELIMITER
@logger.debug("> #{dump_packet packet}")
open
@comm.write(packet)
@comm.flush
res = receive
bits = []
if res && (check_sum(res[0..-5]) == res[-4, 2])
bits =
res[5..-6].each_char.map do |c|
c == '1'
end
end
@logger.debug("> #{dump_packet ack_packet}")
@comm.write(ack_packet)
@logger.debug("get #{device.name} => #{bits}")
bits
end
|
#get_words_from_device(count, device) ⇒ Object
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 126
def get_words_from_device(count, device)
unless available_words_range.include? count
raise ArgumentError,
"A count #{count} must be between #{available_words_range.first} and #{available_words_range.last} for #{__method__}"
end
device = device_by_name device
packet = body_for_get_words_from_device(count, device) + DELIMITER
@logger.debug("> #{dump_packet packet}")
open
@comm.write(packet)
@comm.flush
res = receive
words = []
if res && (check_sum(res[0..-5]) == res[-4, 2])
words =
res[5..-6].scan(/.{4}/).map do |v|
v.to_i(16)
end
end
@logger.debug("> #{dump_packet ack_packet}")
@comm.write(ack_packet)
@logger.debug("get #{device.name} => #{words}")
words
end
|
#open ⇒ Object
53
54
55
56
57
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 53
def open
open!
rescue StandardError
nil
end
|
#open! ⇒ Object
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 59
def open!
return false unless @port
begin
@comm ||= SerialPort.new(@port, @baudrate, 7, 1, 2).tap do |s|
s.read_timeout = (TIMEOUT * 1000.0).to_i
end
raise StandardError.new("invalid port #{@port}") unless @comm
rescue StandardError => e
p e
nil
end
end
|
#receive ⇒ Object
184
185
186
187
188
189
190
191
192
193
194
195
196
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 184
def receive
res = ''
begin
Timeout.timeout(TIMEOUT) do
res = @comm.gets
end
res
rescue Timeout::Error
puts "*** ERROR: TIME OUT : #{res} ***"
end
@logger.debug("< #{dump_packet res}")
res
end
|
#set_bits_to_device(bits, device) ⇒ Object
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 107
def set_bits_to_device(bits, device)
unless available_bits_range.include? bits.size
raise ArgumentError,
"A count #{count} must be between #{available_bits_range.first} and #{available_bits_range.last} for #{__method__}"
end
device = device_by_name device
packet = body_for_set_bits_to_device(bits, device)
@logger.debug("> #{dump_packet packet}")
open
@comm.write(packet)
@comm.flush
res = receive
@logger.debug("set #{bits} to:#{device.name}")
raise "ERROR: return #{res} for set_bits_to_device(#{bits}, #{device.name})" unless res == ack_packet
end
|
#set_words_to_device(words, device) ⇒ Object
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
# File 'lib/plc_access/protocol/mitsubishi/fx_protocol.rb', line 154
def set_words_to_device(words, device)
unless available_bits_range.include? words.size
raise ArgumentError,
"A count of words #{words.size} must be between #{available_words_range.first} and #{available_words_range.last} for #{__method__}"
end
device = device_by_name device
packet = body_for_set_words_to_device(words, device)
@logger.debug("> #{dump_packet packet}")
open
@comm.write(packet)
@comm.flush
res = receive
@logger.debug("set #{words} to: #{device.name}")
raise "ERROR: return #{res} for set_bits_to_device(#{words}, #{device.name})" unless res == ack_packet
end
|