ladder_drive 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 248f3ac5ff9b3eefd59641efd96088ad33f1aec8
4
- data.tar.gz: 31b342a5fb099082eece265f137739862fc6eff4
3
+ metadata.gz: 11f39560e094ef9fc61411b71fc952aebbca6051
4
+ data.tar.gz: 3bedd76a016c2f5bd8848bbf1ff8610a569c13be
5
5
  SHA512:
6
- metadata.gz: c28787587a2a95656a5ab1b7887b551dd5fec15f2cd21aaaeb5c7b1b2979a8ebee73dee7948f92f931a14378929b724bd4e67ba97ec6f2cd5f89597b18914913
7
- data.tar.gz: 12722c48c7c1d2d197233fa438ee28d59b38650eed9e8d1ce1f671b3b96c0836f3f9f47e46c2d2ad9cdc446e811b3cb526e6ae747de989522938080a715f0b41
6
+ metadata.gz: ff72c950069f9b7bd6606547b4769b1956738b4c1f450782d3e0dc8f7b98c40769e8517c8cec93fead79ae65ae2e130ef795bb409efd05e1435c8d58124a5268
7
+ data.tar.gz: c498bcbc93242716a1fb697d0ee5ec5f6b2d46943b3e870a046312c720248003217dd557aebe3fdbb500ec2b99e8186c3ab78bbb98b98c4d3e705ab37712097d
data/Gemfile.lock CHANGED
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ladder_drive (0.3.1)
5
- activesupport (>= 4.2.7)
6
- thor
4
+ ladder_drive (0.4.0)
5
+ activesupport (~> 4.2, >= 4.2.7)
6
+ thor (~> 0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -180,6 +180,27 @@ OUT M1
180
180
  <!-- [![](http://img.youtube.com/vi/qGbicGLB7Gs/0.jpg)](https://youtu.be/qGbicGLB7Gs) -->
181
181
 
182
182
 
183
+ # Accessing a device values
184
+
185
+ You can use LadderDrive as a accessing tool for the PLC device.
186
+
187
+ You can read/write device like this.
188
+
189
+ ```
190
+ require 'ladder_drive'
191
+
192
+ plc = LadderDrive::Protocol::Mitsubishi::McProtocol.new host:"192.168.0.10"
193
+
194
+ plc["M0"] = true
195
+ plc["M0"] # => true
196
+ plc["M0", 10] # => [true, false, ..., false]
197
+
198
+ plc["D0"] = 123
199
+ plc["D0"] # => 123
200
+ plc["D0", 10] = [0, 1, 2, ..., 9]
201
+ plc["D0".."D9"] => [0, 1, 2, ..., 9]
202
+ ```
203
+
183
204
  # Information related ladder_drive
184
205
 
185
206
  - [My japanese diary [ladder_drive]](http://diary.itosoft.com/?category=ladder_drive)
data/README_jp.md CHANGED
@@ -183,6 +183,26 @@ OUT M1
183
183
 
184
184
  <!-- [![](http://img.youtube.com/vi/qGbicGLB7Gs/0.jpg)](https://youtu.be/qGbicGLB7Gs) -->
185
185
 
186
+ ## PLCデバイスへのアクセスツールとしての利用
187
+
188
+ LadderDriveはPLCデバイスの読み書きツールとしての利用もできます。
189
+ 下の様にとても簡単に読み書きできます。
190
+
191
+ ```
192
+ require 'ladder_drive'
193
+
194
+ plc = LadderDrive::Protocol::Mitsubishi::McProtocol.new host:"192.168.0.10"
195
+
196
+ plc["M0"] = true
197
+ plc["M0"] # => true
198
+ plc["M0", 10] # => [true, false, ..., false]
199
+
200
+ plc["D0"] = 123
201
+ plc["D0"] # => 123
202
+ plc["D0", 10] = [0, 1, 2, ..., 9]
203
+ plc["D0".."D9"] => [0, 1, 2, ..., 9]
204
+ ```
205
+
186
206
  ## エスカレーターに関する情報
187
207
 
188
208
  - [一往確認日記 [ladder_drive]](http://diary.itosoft.com/?category=ladder_drive)
data/ladder_drive.gemspec CHANGED
@@ -14,8 +14,8 @@ Gem::Specification.new do |spec|
14
14
  spec.homepage = "https://github.com/ito-soft-design/ladder_drive"
15
15
  spec.license = "MIT"
16
16
 
17
- spec.add_dependency "thor"
18
- spec.add_runtime_dependency "activesupport", ">=4.2.7"
17
+ spec.add_runtime_dependency 'thor', '~> 0'
18
+ spec.add_runtime_dependency 'activesupport', '~> 4.2', '>= 4.2.7'
19
19
 
20
20
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
21
  spec.bindir = "exe"
@@ -104,7 +104,7 @@ module LadderDrive
104
104
  end
105
105
 
106
106
  def bit_device?
107
- SUFFIXES_FOR_BIT.include? @suffix
107
+ suffixes_for_bit.include? @suffix
108
108
  end
109
109
 
110
110
  def + value
@@ -59,7 +59,7 @@ module Keyence
59
59
  values = values.map{|v| v == 0 ? false : true}
60
60
  values.each do |v|
61
61
  device.bool = v
62
- device = device_by_name (device+1).name
62
+ device += 1
63
63
  end
64
64
  values
65
65
  end
@@ -80,7 +80,7 @@ module Keyence
80
80
  @socket.puts(packet)
81
81
  res = receive
82
82
  raise res unless /OK/i =~ res
83
- device = device_by_name (device+1).name
83
+ device += 1
84
84
  end
85
85
  end
86
86
  alias :set_bit_to_device :set_bits_to_device
@@ -144,6 +144,46 @@ module Keyence
144
144
  packet.dup.chomp
145
145
  end
146
146
 
147
+ def available_bits_range suffix=nil
148
+ case suffix
149
+ when "TM"
150
+ 1..512
151
+ when "TM"
152
+ 1..12
153
+ when "T", "TC", "TS", "C", "CC", "CS"
154
+ 1..120
155
+ when "CTH"
156
+ 1..2
157
+ when "CTC"
158
+ 1..4
159
+ when "AT"
160
+ 1..8
161
+ else
162
+ 1..1000
163
+ end
164
+ end
165
+
166
+ def available_words_range suffix=nil
167
+ case suffix
168
+ when "TM"
169
+ 1..256
170
+ when "TM"
171
+ 1..12
172
+ when "T", "TC", "TS", "C", "CC", "CS"
173
+ 1..120
174
+ 1..120
175
+ when "CTH"
176
+ 1..2
177
+ when "CTC"
178
+ 1..4
179
+ when "AT"
180
+ 1..8
181
+ else
182
+ 1..500
183
+ end
184
+ end
185
+
186
+
147
187
  private
148
188
 
149
189
  def device_class
@@ -55,13 +55,24 @@ module Mitsubishi
55
55
  end
56
56
 
57
57
  def get_bits_from_device count, device
58
+ 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
59
+
58
60
  device = device_by_name device
59
61
  packet = make_packet(body_for_get_bits_from_deivce(count, device))
60
62
  @logger.debug("> #{dump_packet packet}")
61
63
  open
62
- @socket.write(packet.pack("c*"))
64
+ @socket.write(packet.pack("C*"))
63
65
  @socket.flush
64
66
  res = receive
67
+
68
+ # error checking
69
+ end_code = res[9,2].pack("C*").unpack("v").first
70
+ unless end_code == 0
71
+ error = res[11,2].pack("C*").unpack("v").first
72
+ raise "return end code 0x#{end_code.to_s(16)} error code 0x#{error.to_s(16)} for get_bits_from_device(#{count}, #{device.name})"
73
+ end
74
+
75
+ # get results
65
76
  bits = []
66
77
  count.times do |i|
67
78
  v = res[11 + i / 2]
@@ -76,14 +87,23 @@ module Mitsubishi
76
87
  end
77
88
 
78
89
  def set_bits_to_device bits, device
90
+ 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? bits.size
91
+
79
92
  device = device_by_name device
80
93
  packet = make_packet(body_for_set_bits_to_device(bits, device))
81
94
  @logger.debug("> #{dump_packet packet}")
82
95
  open
83
- @socket.write(packet.pack("c*"))
96
+ @socket.write(packet.pack("C*"))
84
97
  @socket.flush
85
98
  res = receive
86
99
  @logger.debug("set #{bits} to:#{device.name}")
100
+
101
+ # error checking
102
+ end_code = res[9,2].pack("C*").unpack("v").first
103
+ unless end_code == 0
104
+ error = res[11,2].pack("C*").unpack("v").first
105
+ raise "return end code 0x#{end_code.to_s(16)} error code 0x#{error.to_s(16)} for set_bits_to_device(#{bits}, #{device.name})"
106
+ end
87
107
  end
88
108
 
89
109
 
@@ -93,30 +113,50 @@ module Mitsubishi
93
113
  end
94
114
 
95
115
  def get_words_from_device(count, device)
116
+ raise ArgumentError.new("A count #{count} must be between #{available_words_range.first} and #{available_words_range.last} for #{__method__}") unless available_bits_range.include? count
117
+
96
118
  device = device_by_name device
97
119
  packet = make_packet(body_for_get_words_from_deivce(count, device))
98
120
  @logger.debug("> #{dump_packet packet}")
99
121
  open
100
- @socket.write(packet.pack("c*"))
122
+ @socket.write(packet.pack("C*"))
101
123
  @socket.flush
102
124
  res = receive
125
+
126
+ # error checking
127
+ end_code = res[9,2].pack("C*").unpack("v").first
128
+ unless end_code == 0
129
+ error = res[11,2].pack("C*").unpack("v").first
130
+ raise "return end code 0x#{end_code.to_s(16)} error code 0x#{error.to_s(16)} for get_words_from_device(#{count}, #{device.name})"
131
+ end
132
+
133
+ # get result
103
134
  words = []
104
135
  res[11, 2 * count].each_slice(2) do |pair|
105
- words << pair.pack("c*").unpack("v").first
136
+ words << pair.pack("C*").unpack("v").first
106
137
  end
107
138
  @logger.debug("get from: #{device.name} => #{words}")
108
139
  words
109
140
  end
110
141
 
111
142
  def set_words_to_device words, device
143
+ raise ArgumentError.new("A count #{count} must be between #{available_words_range.first} and #{available_words_range.last} for #{__method__}") unless available_bits_range.include? words.size
144
+
112
145
  device = device_by_name device
113
146
  packet = make_packet(body_for_set_words_to_device(words, device))
114
147
  @logger.debug("> #{dump_packet packet}")
115
148
  open
116
- @socket.write(packet.pack("c*"))
149
+ @socket.write(packet.pack("C*"))
117
150
  @socket.flush
118
151
  res = receive
119
152
  @logger.debug("set #{words} to: #{device.name}")
153
+
154
+ # error checking
155
+ end_code = res[9,2].pack("C*").unpack("v").first
156
+ unless end_code == 0
157
+ error = res[11,2].pack("C*").unpack("v").first
158
+ raise "return end code 0x#{end_code.to_s(16)} error code 0x#{error.to_s(16)} for set_words_to_device(#{words}, #{device.name})"
159
+ end
120
160
  end
121
161
 
122
162
 
@@ -143,7 +183,7 @@ module Mitsubishi
143
183
  next if c.nil? || c == ""
144
184
 
145
185
  res << c.bytes.first
146
- len = res[7,2].pack("c*").unpack("v*").first if res.length >= 9
186
+ len = res[7,2].pack("C*").unpack("v*").first if res.length >= 9
147
187
  break if (len + 9 == res.length)
148
188
  end
149
189
  end
@@ -154,6 +194,14 @@ module Mitsubishi
154
194
  res
155
195
  end
156
196
 
197
+ def available_bits_range device=nil
198
+ 1..(960 * 16)
199
+ end
200
+
201
+ def available_words_range device=nil
202
+ 1..960
203
+ end
204
+
157
205
  private
158
206
 
159
207
  def make_packet body
@@ -214,11 +262,11 @@ module Mitsubishi
214
262
  end
215
263
 
216
264
  def data_for_short value
217
- [value].pack("v").unpack("c*")
265
+ [value].pack("v").unpack("C*")
218
266
  end
219
267
 
220
268
  def data_for_int value
221
- [value].pack("V").unpack("c*")
269
+ [value].pack("V").unpack("C*")
222
270
  end
223
271
 
224
272
  def dump_packet packet
@@ -46,14 +46,14 @@ module Mitsubishi
46
46
  @number = b
47
47
  else
48
48
  if a.length == 12
49
- @suffix = [a[0,2].to_i(16), a[2,2].to_i(16)].pack "c*"
49
+ @suffix = [a[0,2].to_i(16), a[2,2].to_i(16)].pack "C*"
50
50
  @suffix.strip!
51
51
  @number = a[4,8].to_i(16)
52
52
  elsif /(X|Y)(.+)/i =~ a
53
53
  @suffix = $1.upcase
54
54
  @number = $2.to_i(p_adic_number)
55
55
  else
56
- /(M|L|S|B|F|T|C|D|W|R)(.+)/i =~ a
56
+ /(M|L|S|B|F|T|C|D|W|R|ZR)(.+)/i =~ a
57
57
  @suffix = $1.upcase
58
58
  @number = $2.to_i(p_adic_number)
59
59
  end
@@ -63,7 +63,7 @@ module Mitsubishi
63
63
 
64
64
  def p_adic_number
65
65
  case @suffix
66
- when "X", "Y", "B", "W", "SB", "SW", "DX", "DY", "ZR"
66
+ when "X", "Y", "B", "W", "SB", "SW", "DX", "DY"
67
67
  16
68
68
  else
69
69
  10
@@ -24,11 +24,6 @@
24
24
  dir = File.expand_path(File.dirname(__FILE__))
25
25
  $:.unshift dir unless $:.include? dir
26
26
 
27
- module LadderDrive
28
- module Protocol
29
- end
30
- end
31
-
32
27
  module LadderDrive
33
28
  module Protocol
34
29
 
@@ -67,12 +62,12 @@ module Protocol
67
62
  def get_bit_from_device device; end
68
63
  def get_bits_from_device count, device; end
69
64
  def set_bits_to_device bits, device; end
70
- def set_bit_to_device bit, device; set_bits_to_device bit, device; end
65
+ def set_bit_to_device bit, device; set_bits_to_device [bit], device; end
71
66
 
72
67
  def get_word_from_device device; end
73
68
  def get_words_from_device(count, device); end
74
69
  def set_words_to_device words, device; end
75
- def set_word_to_device word, device; set_words_to_device word, device; end
70
+ def set_word_to_device word, device; set_words_to_device [word], device; end
76
71
 
77
72
  def device_by_name name; nil; end
78
73
 
@@ -96,6 +91,99 @@ module Protocol
96
91
  end
97
92
  end
98
93
 
94
+ def available_bits_range device=nil
95
+ -Float::INFINITY..Float::INFINITY
96
+ end
97
+
98
+ def available_words_range device=nil
99
+ -Float::INFINITY..Float::INFINITY
100
+ end
101
+
102
+ def [] *args
103
+ case args.size
104
+ when 1
105
+ # protocol["DM0"]
106
+ # protocol["DM0".."DM9"]
107
+ case args[0]
108
+ when String
109
+ self[args[0], 1].first
110
+ when Range
111
+ self[args[0].first, args[0].count]
112
+ else
113
+ raise ArgumentError.new("#{args[0]} must be String or Range.")
114
+ end
115
+ when 2
116
+ # protocol["DM0", 10]
117
+ d = device_by_name args[0]
118
+ c = args[1]
119
+ if d.bit_device?
120
+ a = []
121
+ b = available_bits_range(d).last
122
+ until c == 0
123
+ n_c = [b, c].min
124
+ a += get_bits_from_device(n_c, d)
125
+ d += n_c
126
+ c -= n_c
127
+ end
128
+ a
129
+ else
130
+ a = []
131
+ b = available_words_range(d).last
132
+ until c == 0
133
+ n_c = [b, c].min
134
+ a += get_words_from_device(n_c, d)
135
+ d += n_c
136
+ c -= n_c
137
+ end
138
+ a
139
+ end
140
+ else
141
+ raise ArgumentError.new("wrong number of arguments (given #{args.size}, expected 1 or 2)")
142
+ end
143
+ end
144
+
145
+ def []= *args
146
+ case args.size
147
+ when 2
148
+ # protocol["DM0"] = 0
149
+ # protocol["DM0".."DM9"] = [0, 1, .., 9]
150
+ v = args[1]
151
+ v = [v] unless v.is_a? Array
152
+ case args[0]
153
+ when String
154
+ self[args[0], 1] = v
155
+ when Range
156
+ self[args[0].first, args[0].count] = v
157
+ else
158
+ raise ArgumentError.new("#{args[1]} must be String or Array.")
159
+ end
160
+ when 3
161
+ # protocol["DM0", 10] = [0, 1, .., 9]
162
+ d = device_by_name args[0]
163
+ c = args[1]
164
+ values = args[2]
165
+ values = [values] unless values.is_a? Array
166
+ raise ArgumentError.new("Count #{c} is not match #{args[2].size}.") unless c == values.size
167
+ if d.bit_device?
168
+ a = []
169
+ values.each_slice(available_bits_range(d).last) do |sv|
170
+ set_bits_to_device(values, d)
171
+ d += sv.size
172
+ end
173
+ a
174
+ else
175
+ a = []
176
+ values.each_slice(available_words_range(d).last) do |sv|
177
+ set_words_to_device(values, d)
178
+ d += sv.size
179
+ end
180
+ a
181
+ end
182
+ else
183
+ raise ArgumentError.new("wrong number of arguments (given #{args.size}, expected 2 or 3)")
184
+ end
185
+ end
186
+
99
187
  end
100
188
 
101
189
  end
@@ -55,7 +55,7 @@ module LadderDrive
55
55
  def word_data
56
56
  data.each_slice(2).map do |pair|
57
57
  pair << 0 if pair.size == 1
58
- pair.pack("c*").unpack("n*")
58
+ pair.pack("C*").unpack("n*")
59
59
  end.flatten
60
60
  end
61
61
 
@@ -22,5 +22,5 @@
22
22
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
 
24
24
  module LadderDrive
25
- VERSION = "0.3.1"
25
+ VERSION = "0.4.0"
26
26
  end
@@ -152,7 +152,7 @@ module Emulator
152
152
  case d.suffix
153
153
  when "PRG"
154
154
  c.times do
155
- r << program_data[d.number * 2, 2].pack("c*").unpack("n").first
155
+ r << program_data[d.number * 2, 2].pack("C*").unpack("n").first
156
156
  d = device_by_name (d+1).name
157
157
  end
158
158
  else
@@ -169,7 +169,7 @@ module Emulator
169
169
  case d.suffix
170
170
  when "PRG"
171
171
  a[3, c].each do |v|
172
- program_data[d.number * 2, 2] = [v.to_i].pack("n").unpack("c*")
172
+ program_data[d.number * 2, 2] = [v.to_i].pack("n").unpack("C*")
173
173
  d = device_by_name (d+1).name
174
174
  end
175
175
  else
metadata CHANGED
@@ -1,33 +1,36 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ladder_drive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katsuyoshi Ito
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-03-05 00:00:00.000000000 Z
11
+ date: 2017-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activesupport
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.2'
31
34
  - - ">="
32
35
  - !ruby/object:Gem::Version
33
36
  version: 4.2.7
@@ -35,6 +38,9 @@ dependencies:
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '4.2'
38
44
  - - ">="
39
45
  - !ruby/object:Gem::Version
40
46
  version: 4.2.7