Class: LadderDrive::Protocol::Omron::FinsTcpProtocol

Inherits:
Protocol
  • Object
show all
Defined in:
lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb

Constant Summary collapse

IOFINS_DESTINATION_NODE_FROM_IP =
0
IOFINS_SOURCE_AUTO_NODE =
0
ETHERNET_ETN21 =

Available ethernet module.

0
ETHERNET_CP1E =
1
ETHERNET_CP1L =
2
ETHERNET_CP1H =
3
TIMEOUT =
5.0

Instance Attribute Summary collapse

Attributes inherited from Protocol

#host, #port

Instance Method Summary collapse

Methods inherited from Protocol

#[], #[]=, #destination_ipv4, #get_bit_from_device, #get_from_devices, #get_word_from_device, #log_level, #log_level=, #self_ipv4, #set_bit_to_device, #set_to_devices, #set_word_to_device

Constructor Details

#initialize(options = {}) ⇒ FinsTcpProtocol



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 53

def initialize options={}
  super
  @socket = nil
  @host = options[:host] || "192.168.250.1"
  @port = options[:port] || 9600
  @gateway_count = 3
  @destination_network = 0
  @destination_node = 0
  @destination_unit = 0
  @source_network = 0
  @source_node = IOFINS_SOURCE_AUTO_NODE
  @source_unit = 0
  @ethernet_module = ETHERNET_ETN21

  @tcp_error_code = 0

  prepare_device_map
end

Instance Attribute Details

#destination_networkObject

Returns the value of attribute destination_network.



31
32
33
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 31

def destination_network
  @destination_network
end

#destination_nodeObject

Returns the value of attribute destination_node.



32
33
34
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 32

def destination_node
  @destination_node
end

#destination_unitObject

Returns the value of attribute destination_unit.



33
34
35
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 33

def destination_unit
  @destination_unit
end

#ethernet_moduleObject

Returns the value of attribute ethernet_module.



38
39
40
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 38

def ethernet_module
  @ethernet_module
end

#gateway_countObject

Returns the value of attribute gateway_count.



30
31
32
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 30

def gateway_count
  @gateway_count
end

#source_networkObject

Returns the value of attribute source_network.



34
35
36
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 34

def source_network
  @source_network
end

#source_nodeObject

Returns the value of attribute source_node.



35
36
37
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 35

def source_node
  @source_node
end

#source_unitObject

Returns the value of attribute source_unit.



36
37
38
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 36

def source_unit
  @source_unit
end

#tcp_error_codeObject

Returns the value of attribute tcp_error_code.



40
41
42
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 40

def tcp_error_code
  @tcp_error_code
end

Instance Method Details

#available_bits_range(device = nil) ⇒ Object

max length:

CS1W-ETN21, CJ1W-ETN21   : 2012
CP1W-CIF41 option board  : 540 (1004 if cpu is CP1L/H)


236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 236

def available_bits_range device=nil
  case ethernet_module
  when ETHERNET_ETN21
    1..(2012 - 8)
  when ETHERNET_CP1E
    1..(540 - 8)
  when ETHERNET_CP1L, ETHERNET_CP1H
    1..(1004 - 8)
  else
    0..0
  end
end

#available_words_range(device = nil) ⇒ Object



249
250
251
252
253
254
255
256
257
258
259
260
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 249

def available_words_range device=nil
  case ethernet_module
  when ETHERNET_ETN21
    1..((2012 - 8) / 2)
  when ETHERNET_CP1E
    1..((540 - 8) / 2)
  when ETHERNET_CP1L, ETHERNET_CP1H
    1..((1004 - 8) / 2)
  else
    0..0
  end
end

#closeObject



90
91
92
93
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 90

def close
  @socket.close if @socket
  @socket = nil
end

#create_fins_frame(packet) ⇒ Object



105
106
107
108
109
110
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 105

def create_fins_frame packet
  packet = packet.flatten
  header = [ "FINS".bytes.to_a,  0, 0, 0, 0,  0, 0, 0, 2,  0, 0, 0, 0].flatten
  header[4, 4] = int_to_a(packet.length + 8, 4)
  header + packet
end

#create_query_nodeObject



99
100
101
102
103
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 99

def create_query_node
  header = [ "FINS".bytes.to_a,  0, 0, 0, 0xc,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0].flatten
  header[19] = source_node == IOFINS_SOURCE_AUTO_NODE ? 0 : source_node
  header
end

#device_by_name(name) ⇒ Object



262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 262

def device_by_name name
  case name
  when String
    d = OmronDevice.new name
    d.valid? ? d : nil
  when EscDevice
    local_device_of name
  else
    # it may be already OmronDevice
    name
  end
end

#get_bits_from_device(count, device) ⇒ Object

Raises:

  • (ArgumentError)


112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 112

def get_bits_from_device(count, device)
  open
  raise ArgumentError.new("A count #{count} must be between #{available_bits_range.first} and #{available_bits_range.last} for #{__method__}") unless available_bits_range.include? count

  device = device_by_name device
  raise ArgumentError.new("#{device.name} is not bit device!") unless device.bit_device?

  command = [1, 1]
  command << device_to_a(device)
  command << int_to_a(count, 2)

  send_packet create_fins_frame(fins_header + command)
  res = receive

  count.times.inject([]) do |a, i|
    a << (res[16 + 10 + 4 + i] == 0 ? false : true)
    a
  end
end

#get_words_from_device(count, device) ⇒ Object

Raises:

  • (ArgumentError)


132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 132

def get_words_from_device(count, device)
  open
  raise ArgumentError.new("A count #{count} must be between #{available_words_range.first} and #{available_words_range.last} for #{__method__}") unless available_words_range.include? count

  device = device_by_name device
  device = device.channel_device

  command = [1, 1]
  command << device_to_a(device)
  command << int_to_a(count, 2)

  send_packet create_fins_frame(fins_header + command)
  res = receive
  count.times.inject([]) do |a, i|
    a << to_int(res[16 + 10 + 4 + i * 2, 2])
    a
  end
end

#openObject



72
73
74
75
76
77
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 72

def open
  open!
rescue =>e
p e
  nil
end

#open!Object



79
80
81
82
83
84
85
86
87
88
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 79

def open!
  if @socket.nil?
    @socket = TCPSocket.open(@host, @port)
    if @socket
      source_node = IOFINS_SOURCE_AUTO_NODE
      query_node
    end
  end
  @socket
end

#query_nodeObject



189
190
191
192
193
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 189

def query_node
  send_packet create_query_node
  res = receive
  self.source_node = res[19]
end

#receiveObject



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 202

def receive
  res = []
  len = 0
  begin
    Timeout.timeout(TIMEOUT) do
      loop do
        c = @socket.getc
        next if c.nil? || c == ""

        res << c.bytes.first
        next if res.length < 8

        len = to_int(res[4, 4])
        next if res.length < 8 + len

        tcp_command = to_int(res[8, 4])
        case tcp_command
        when 3 # ERROR
          raise "Invalidate tcp header: #{res}"
        end
        break
      end
    end
    raise "Response error code: #{res[15]}" unless res[15] == 0
    res
  end
  @logger.debug("< #{dump_packet res}")
  res
end

#send_packet(packet) ⇒ Object



196
197
198
199
200
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 196

def send_packet packet
  @socket.write(packet.flatten.pack("c*"))
  @socket.flush
  @logger.debug("> #{dump_packet packet}")
end

#set_bits_to_device(bits, device) ⇒ Object

Raises:

  • (ArgumentError)


151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 151

def set_bits_to_device(bits, device)
  open
  count = bits.size
  raise ArgumentError.new("A count #{count} must be between #{available_bits_range.first} and #{available_bits_range.last} for #{__method__}") unless available_bits_range.include? count

  device = device_by_name device
  raise ArgumentError.new("#{device.name} is not bit device!") unless device.bit_device?

  command = [1, 2]
  command << device_to_a(device)
  command << int_to_a(count, 2)
  bits.each do |b|
    command << (b ? 1 : 0)
  end

  send_packet create_fins_frame(fins_header + command)
  res = receive
end

#set_words_to_device(words, device) ⇒ Object

Raises:

  • (ArgumentError)


170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 170

def set_words_to_device(words, device)
  open
  count = words.size
  raise ArgumentError.new("A count #{count} must be between #{available_words_range.first} and #{available_words_range.last} for #{__method__}") unless available_words_range.include? count

  device = device_by_name device
  device = device.channel_device

  command = [1, 2]
  command << device_to_a(device)
  command << int_to_a(count, 2)
  words.each do |w|
    command << int_to_a(w, 2)
  end

  send_packet create_fins_frame(fins_header + command)
  res = receive
end

#tcp_error?Boolean



95
96
97
# File 'lib/ladder_drive/protocol/omron/fins_tcp_protocol.rb', line 95

def tcp_error?
  tcp_error_code != 0
end