mc_protocol_e 0.1.2 → 0.2.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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +4 -2
- data/exe/mc_protocol_e.rb +61 -0
- data/lib/mc_protocol_e.rb +2 -0
- data/lib/mc_protocol_e/frame_1e/device.rb +114 -0
- data/lib/mc_protocol_e/frame_1e/device_range.rb +8 -10
- data/lib/mc_protocol_e/frame_3e/batch_read_in_multiple.rb +52 -0
- data/lib/mc_protocol_e/frame_3e/device.rb +180 -0
- data/lib/mc_protocol_e/frame_3e/device_range.rb +32 -9
- data/lib/mc_protocol_e/frame_3e/error_info.rb +1 -1
- data/lib/mc_protocol_e/frame_3e/request.rb +13 -4
- data/lib/mc_protocol_e/frame_3e/response.rb +1 -5
- data/lib/mc_protocol_e/version.rb +1 -1
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 12a5fce4d3a72883ec0948e9cc202e986375a864b1f2ca25c29b76a2237578f1
|
4
|
+
data.tar.gz: 5cdbefee2d30107edbcac9aaf7b7bd585cfbff4a4a9fce4dcafc6d3a08c573c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24fbeb78bfd0ba1171ddf0072a42bf442ef4aecf545dff40025b740d587a2b0a2e24facf8992ff651349c81d4ed4e05ac5e81fc8f190d99500d8c5937dabbcf9
|
7
|
+
data.tar.gz: 6b062be54b0dfa861e31560c5c324cb59006edfee99f58d42b873f1f939298f698757231eea02b50f12dec5d0e4ccdfe440ccb7ea9d6366163b14ac2956ad32b
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -84,7 +84,7 @@ req =
|
|
84
84
|
McProtocolE::Client.start(address: opts["h"], port: opts["p"].to_i) {|client|
|
85
85
|
pp req.to_b
|
86
86
|
res = client.request(req)
|
87
|
-
pp res.map {|raw| raw.
|
87
|
+
pp res.map {|raw| raw.unpack1("s") }
|
88
88
|
}
|
89
89
|
|
90
90
|
```
|
@@ -99,7 +99,9 @@ McProtocolE::Client.start(address: opts["h"], port: opts["p"].to_i) {|client|
|
|
99
99
|
* Support only below commands.
|
100
100
|
* Batch read in word units (0401)
|
101
101
|
* Batch write in word units (1401)
|
102
|
-
|
102
|
+
* Batch read in multiple units (0406)
|
103
|
+
* I have not tested on actual machines
|
104
|
+
|
103
105
|
## License
|
104
106
|
|
105
107
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'mc_protocol_e'
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
# Usage: ./mc_protocol_e.rb -h 192.168.1.250 -p 4000 -f 3e --rw r --device_num 3000 --device_points 16
|
8
|
+
opts = ARGV.getopts("h:p:f:", "rw:", "device_num:", "device_points:", "values:")
|
9
|
+
raise ArgumentError, "required option is not specified" unless %w[h p f device_num device_points].all? {|key| opts[key] }
|
10
|
+
|
11
|
+
req =
|
12
|
+
case opts["f"]
|
13
|
+
when "1e"
|
14
|
+
case opts["rw"]
|
15
|
+
when "r"
|
16
|
+
McProtocolE::Frame1e::Request.batch_read_in_word(
|
17
|
+
access_route: McProtocolE::Frame1e::AccessRoute.own_station,
|
18
|
+
wait_sec: 3,
|
19
|
+
device_range: McProtocolE::Frame1e::DeviceRange.data_register(device_num: opts["device_num"].to_i, device_points: opts["device_points"].to_i)
|
20
|
+
)
|
21
|
+
when "w"
|
22
|
+
raise ArgumentError, "values is required" unless opts["values"]
|
23
|
+
|
24
|
+
McProtocolE::Frame1e::Request.batch_write_in_word(
|
25
|
+
access_route: McProtocolE::Frame1e::AccessRoute.own_station,
|
26
|
+
wait_sec: 3,
|
27
|
+
device_range: McProtocolE::Frame1e::DeviceRange.data_register(device_num: opts["device_num"].to_i, device_points: opts["device_points"].to_i),
|
28
|
+
values: opts["values"].split(",").map(&:to_i),
|
29
|
+
)
|
30
|
+
else
|
31
|
+
raise ArgumentError
|
32
|
+
end
|
33
|
+
when "3e"
|
34
|
+
case opts["rw"]
|
35
|
+
when "r"
|
36
|
+
McProtocolE::Frame3e::Request.batch_read_in_word(
|
37
|
+
access_route: McProtocolE::Frame3e::AccessRoute.own_station,
|
38
|
+
wait_sec: 3,
|
39
|
+
device_range: McProtocolE::Frame3e::DeviceRange.data_register(device_num: opts["device_num"].to_i, device_points: opts["device_points"].to_i)
|
40
|
+
)
|
41
|
+
when "w"
|
42
|
+
raise ArgumentError, "values is required" unless opts["values"]
|
43
|
+
|
44
|
+
McProtocolE::Frame3e::Request.batch_write_in_word(
|
45
|
+
access_route: McProtocolE::Frame3e::AccessRoute.own_station,
|
46
|
+
wait_sec: 3,
|
47
|
+
device_range: McProtocolE::Frame3e::DeviceRange.data_register(device_num: opts["device_num"].to_i, device_points: opts["device_points"].to_i),
|
48
|
+
values: opts["values"].split(",").map(&:to_i),
|
49
|
+
)
|
50
|
+
else
|
51
|
+
raise ArgumentError
|
52
|
+
end
|
53
|
+
else
|
54
|
+
raise ArgumentError
|
55
|
+
end
|
56
|
+
|
57
|
+
McProtocolE::Client.start(address: opts["h"], port: opts["p"].to_i) {|client|
|
58
|
+
pp req.to_b
|
59
|
+
res = client.request(req)
|
60
|
+
pp res.map {|raw| raw.unpack1("s") }
|
61
|
+
}
|
data/lib/mc_protocol_e.rb
CHANGED
@@ -7,8 +7,10 @@ require 'mc_protocol_e/frame_1e/device_range'
|
|
7
7
|
require 'mc_protocol_e/frame_1e/request'
|
8
8
|
require 'mc_protocol_e/frame_1e/response'
|
9
9
|
require 'mc_protocol_e/frame_3e/access_route'
|
10
|
+
require 'mc_protocol_e/frame_3e/batch_read_in_multiple'
|
10
11
|
require 'mc_protocol_e/frame_3e/batch_read_in_word'
|
11
12
|
require 'mc_protocol_e/frame_3e/batch_write_in_word'
|
13
|
+
require 'mc_protocol_e/frame_3e/device'
|
12
14
|
require 'mc_protocol_e/frame_3e/device_range'
|
13
15
|
require 'mc_protocol_e/frame_3e/error_info'
|
14
16
|
require 'mc_protocol_e/frame_3e/request'
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module McProtocolE
|
4
|
+
module Frame1e
|
5
|
+
# This class shows a device.
|
6
|
+
class Device
|
7
|
+
|
8
|
+
module Code
|
9
|
+
INPUT = "\x20\x58".b
|
10
|
+
OUTPUT = "\x20\x59".b
|
11
|
+
INTERNAL_RELAY = "\x20\x4D".b
|
12
|
+
ANNUNCIATOR = "\x20\x46".b
|
13
|
+
LINK_RELAY = "\x20\x42".b
|
14
|
+
TIMER_CURRENT_VALUE = "\x4E\x54".b
|
15
|
+
TIMER_CONTACT = "\x53\x54".b
|
16
|
+
TIMER_COIL = "\x43\x54".b
|
17
|
+
COUNTER_CURRENT_VALUE = "\x4E\x43".b
|
18
|
+
COUNTER_CONTACT = "\x53\x43".b
|
19
|
+
COUNTER_COIL = "\x43\x43".b
|
20
|
+
DATA_REGISTER = "\x20\x44".b
|
21
|
+
LINK_REGISTER = "\x20\x57".b
|
22
|
+
FILE_REGISTER = "\x20\x52".b
|
23
|
+
end
|
24
|
+
|
25
|
+
module Type
|
26
|
+
WORD = :word
|
27
|
+
BIT = :bit
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :code
|
31
|
+
|
32
|
+
# Constructor.
|
33
|
+
# @param [String] code device code
|
34
|
+
# @param [Symbol] type device type
|
35
|
+
def initialize(code:, type:)
|
36
|
+
@code = code
|
37
|
+
@type = type
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.input
|
41
|
+
new(code: Code::INPUT, type: Type::BIT)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.output
|
45
|
+
new(code: Code::OUTPUT, type: Type::BIT)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.internal_relay
|
49
|
+
new(code: Code::INTERNAL_RELAY, type: Type::BIT)
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.annunciator
|
53
|
+
new(code: Code::ANNUNCIATOR, type: Type::BIT)
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.link_relay
|
57
|
+
new(code: Code::LINK_RELAY, type: Type::BIT)
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.timer_current_value
|
61
|
+
new(code: Code::TIMER_CURRENT_VALUE, type: Type::WORD)
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.timer_contact
|
65
|
+
new(code: Code::TIMER_CONTACT, type: Type::BIT)
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.timer_coil
|
69
|
+
new(code: Code::TIMER_COIL, type: Type::BIT)
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.counter_current_value
|
73
|
+
new(code: Code::COUNTER_CURRENT_VALUE, type: Type::WORD)
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.counter_contact
|
77
|
+
new(code: Code::COUNTER_CONTACT, type: Type::BIT)
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.counter_coil
|
81
|
+
new(code: Code::COUNTER_COIL, type: Type::BIT)
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.data_register
|
85
|
+
new(code: Code::DATA_REGISTER, type: Type::WORD)
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.link_register
|
89
|
+
new(code: Code::LINK_REGISTER, type: Type::WORD)
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.file_register
|
93
|
+
new(code: Code::FILE_REGISTER, type: Type::WORD)
|
94
|
+
end
|
95
|
+
|
96
|
+
def bit?
|
97
|
+
type == Type::BIT
|
98
|
+
end
|
99
|
+
|
100
|
+
def word?
|
101
|
+
type == Type::WORD
|
102
|
+
end
|
103
|
+
|
104
|
+
def to_b
|
105
|
+
code
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
attr_reader :type
|
111
|
+
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'device'
|
4
|
+
|
3
5
|
module McProtocolE
|
4
6
|
module Frame1e
|
5
7
|
# This class shows a device range.
|
@@ -7,16 +9,12 @@ module McProtocolE
|
|
7
9
|
|
8
10
|
FIXED_VALUE = "\x00".b
|
9
11
|
|
10
|
-
module DeviceCode
|
11
|
-
DATA_REGISTER = "\x20\x44".b
|
12
|
-
end
|
13
|
-
|
14
12
|
# Constructor.
|
15
|
-
# @param [String]
|
13
|
+
# @param [String] device device
|
16
14
|
# @param [Integer] device_num first device number in range
|
17
15
|
# @param [Integer] device_points number in range
|
18
|
-
def initialize(
|
19
|
-
@
|
16
|
+
def initialize(device:, device_num:, device_points:)
|
17
|
+
@device = device
|
20
18
|
@device_num = device_num
|
21
19
|
@device_points = device_points
|
22
20
|
end
|
@@ -25,7 +23,7 @@ module McProtocolE
|
|
25
23
|
# @param [Integer] device_num first device number in range
|
26
24
|
# @param [Integer] device_points number in range
|
27
25
|
def self.data_register(device_num:, device_points:)
|
28
|
-
new(
|
26
|
+
new(device: Device.data_register, device_num: device_num, device_points: device_points)
|
29
27
|
end
|
30
28
|
|
31
29
|
# Returns range size.
|
@@ -37,12 +35,12 @@ module McProtocolE
|
|
37
35
|
# Returns binary string.
|
38
36
|
# @return [String] binary string
|
39
37
|
def to_b
|
40
|
-
[[device_num].pack("V"),
|
38
|
+
[[device_num].pack("V"), device.code, [device_points].pack("v")[0], FIXED_VALUE].join
|
41
39
|
end
|
42
40
|
|
43
41
|
private
|
44
42
|
|
45
|
-
attr_reader :
|
43
|
+
attr_reader :device, :device_num, :device_points
|
46
44
|
|
47
45
|
end
|
48
46
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_command'
|
4
|
+
|
5
|
+
module McProtocolE
|
6
|
+
module Frame3e
|
7
|
+
# This class shows a command to batch read in word.
|
8
|
+
class BatchReadInMultiple < BaseCommand
|
9
|
+
|
10
|
+
COMMAND = "\x06\x04\x00\x00".b
|
11
|
+
|
12
|
+
# Constructor.
|
13
|
+
# @param [DeviceRange] device_range device range
|
14
|
+
def initialize(device_ranges:)
|
15
|
+
super(COMMAND)
|
16
|
+
@device_ranges = device_ranges
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns array of word.
|
20
|
+
# @param [Response] res response
|
21
|
+
# @return[Array] array of word
|
22
|
+
def parse(res)
|
23
|
+
super(res)
|
24
|
+
|
25
|
+
res.data&.each_char&.each_slice(2)&.map(&:join)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns binary string.
|
29
|
+
# @return [String] binary string
|
30
|
+
def to_b
|
31
|
+
@to_b ||=
|
32
|
+
command +
|
33
|
+
[word_block_num].pack("v")[0] +
|
34
|
+
[bit_block_num].pack("v")[0] +
|
35
|
+
device_ranges.map(&:to_b).join
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
attr_reader :device_ranges
|
41
|
+
|
42
|
+
def word_block_num
|
43
|
+
device_ranges.select(&:word?).size
|
44
|
+
end
|
45
|
+
|
46
|
+
def bit_block_num
|
47
|
+
device_ranges.select(&:bit?).size
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module McProtocolE
|
4
|
+
module Frame3e
|
5
|
+
# This class shows a device.
|
6
|
+
class Device
|
7
|
+
|
8
|
+
module Code
|
9
|
+
SPECIAL_RELAY = "\x91".b
|
10
|
+
SPECIAL_REGISTER = "\xA9".b
|
11
|
+
INPUT = "\x9C".b
|
12
|
+
OUTPUT = "\x9D".b
|
13
|
+
INTERNAL_RELAY = "\x90".b
|
14
|
+
LATCH_RELAY = "\x92".b
|
15
|
+
ANNUNCIATOR = "\x93".b
|
16
|
+
EDGE_RELAY = "\x94".b
|
17
|
+
LINK_RELAY = "\xA0".b
|
18
|
+
DATA_REGISTER = "\xA8".b
|
19
|
+
LINK_REGISTER = "\xB4".b
|
20
|
+
TIMER_CONTACT = "\xC1".b
|
21
|
+
TIMER_COIL = "\xC0".b
|
22
|
+
TIMER_CURRENT_VALUE = "\xC2".b
|
23
|
+
RETENTIVE_TIMER_CONTACT = "\xC7".b
|
24
|
+
RETENTIVE_TIMER_COIL = "\xC6".b
|
25
|
+
RETENTIVE_TIMER_CURRENT_VALUE = "\xC8".b
|
26
|
+
COUNTER_CONTACT = "\xC4".b
|
27
|
+
COUNTER_COIL = "\xC3".b
|
28
|
+
COUNTER_CURRENT_VALUE = "\xC5".b
|
29
|
+
LINK_SPECIAL_RELAY = "\xA1".b
|
30
|
+
LINK_SPECIAL_REGISTER = "\xB5".b
|
31
|
+
DIRECT_ACCESS_INPUT = "\xA2".b
|
32
|
+
DIRECT_ACCESS_OUTPUT = "\xA3".b
|
33
|
+
INDEX_REGISTER = "\xCC".b
|
34
|
+
FILE_REGISTER_BSM = "\xAF".b
|
35
|
+
FILE_REGISTER_SNAM = "\xb0".b
|
36
|
+
MODULE_ACCESS_DEVICE = "\xAB".b
|
37
|
+
end
|
38
|
+
|
39
|
+
module Type
|
40
|
+
WORD = :word
|
41
|
+
BIT = :bit
|
42
|
+
end
|
43
|
+
|
44
|
+
attr_reader :code
|
45
|
+
|
46
|
+
# Constructor.
|
47
|
+
# @param [String] code device code
|
48
|
+
# @param [Symbol] type device type
|
49
|
+
def initialize(code:, type:)
|
50
|
+
@code = code
|
51
|
+
@type = type
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.special_relay
|
55
|
+
new(code: Code::SPECIAL_RELAY, type: Type::BIT)
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.special_register
|
59
|
+
new(code: Code::SPECIAL_REGISTER, type: Type::WORD)
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.input
|
63
|
+
new(code: Code::INPUT, type: Type::BIT)
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.output
|
67
|
+
new(code: Code::OUTPUT, type: Type::BIT)
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.internal_relay
|
71
|
+
new(code: Code::INTERNAL_RELAY, type: Type::BIT)
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.latch_relay
|
75
|
+
new(code: Code::LATCH_RELAY, type: Type::BIT)
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.annunciator
|
79
|
+
new(code: Code::ANNUNCIATOR, type: Type::BIT)
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.edge_relay
|
83
|
+
new(code: Code::EDGE_RELAY, type: Type::BIT)
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.link_relay
|
87
|
+
new(code: Code::LINK_RELAY, type: Type::BIT)
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.data_register
|
91
|
+
new(code: Code::DATA_REGISTER, type: Type::WORD)
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.link_register
|
95
|
+
new(code: Code::LINK_REGISTER, type: Type::WORD)
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.timer_contact
|
99
|
+
new(code: Code::TIMER_CONTACT, type: Type::BIT)
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.timer_coil
|
103
|
+
new(code: Code::TIMER_COIL, type: Type::BIT)
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.timer_current_value
|
107
|
+
new(code: Code::TIMER_CURRENT_VALUE, type: Type::WORD)
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.retentive_timer_contact
|
111
|
+
new(code: Code::RETENTIVE_TIMER_CONTACT, type: Type::BIT)
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.retentive_timer_coil
|
115
|
+
new(code: Code::RETENTIVE_TIMER_COIL, type: Type::BIT)
|
116
|
+
end
|
117
|
+
|
118
|
+
def self.retentive_timer_current_value
|
119
|
+
new(code: Code::RETENTIVE_TIMER_CURRENT_VALUE, type: Type::WORD)
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.counter_contact
|
123
|
+
new(code: Code::COUNTER_CONTACT, type: Type::BIT)
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.counter_coil
|
127
|
+
new(code: Code::COUNTER_COIL, type: Type::BIT)
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.counter_current_value
|
131
|
+
new(code: Code::COUNTER_CURRENT_VALUE, type: Type::WORD)
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.link_special_relay
|
135
|
+
new(code: Code::LINK_SPECIAL_RELAY, type: Type::BIT)
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.link_special_register
|
139
|
+
new(code: Code::LINK_SPECIAL_REGISTER, type: Type::WORD)
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.direct_access_input
|
143
|
+
new(code: Code::DIRECT_ACCESS_INPUT, type: Type::BIT)
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.direct_access_output
|
147
|
+
new(code: Code::DIRECT_ACCESS_OUTPUT, type: Type::BIT)
|
148
|
+
end
|
149
|
+
|
150
|
+
def self.index_register
|
151
|
+
new(code: Code::INDEX_REGISTER, type: Type::WORD)
|
152
|
+
end
|
153
|
+
|
154
|
+
def self.file_register_bsm
|
155
|
+
new(code: Code::FILE_REGISTER_BSM, type: Type::WORD)
|
156
|
+
end
|
157
|
+
|
158
|
+
def self.file_register_snam
|
159
|
+
new(code: Code::FILE_REGISTER_SNAM, type: Type::BIT)
|
160
|
+
end
|
161
|
+
|
162
|
+
def bit?
|
163
|
+
type == Type::BIT
|
164
|
+
end
|
165
|
+
|
166
|
+
def word?
|
167
|
+
type == Type::WORD
|
168
|
+
end
|
169
|
+
|
170
|
+
def to_b
|
171
|
+
code
|
172
|
+
end
|
173
|
+
|
174
|
+
private
|
175
|
+
|
176
|
+
attr_reader :type
|
177
|
+
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -1,29 +1,52 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'forwardable'
|
4
|
+
require_relative 'device'
|
5
|
+
|
3
6
|
module McProtocolE
|
4
7
|
module Frame3e
|
5
8
|
# This class shows a device range.
|
6
9
|
class DeviceRange
|
10
|
+
extend Forwardable
|
7
11
|
|
8
|
-
|
9
|
-
DATA_REGISTER = "\xA8".b
|
10
|
-
end
|
12
|
+
def_delegators :@device, :bit?, :word?
|
11
13
|
|
12
14
|
# Constructor.
|
13
|
-
# @param [
|
15
|
+
# @param [Device] device device
|
14
16
|
# @param [Integer] device_num first device number in range
|
15
17
|
# @param [Integer] device_points number in range
|
16
|
-
def initialize(
|
17
|
-
@
|
18
|
+
def initialize(device:, device_num:, device_points:)
|
19
|
+
@device = device
|
18
20
|
@device_num = device_num
|
19
21
|
@device_points = device_points
|
20
22
|
end
|
21
23
|
|
24
|
+
# Returns device range of internal relay.
|
25
|
+
# @param [Integer] device_num first device number in range
|
26
|
+
# @param [Integer] device_points number in range
|
27
|
+
def self.internal_relay(device_num:, device_points:)
|
28
|
+
new(device: Device.internal_relay, device_num: device_num, device_points: device_points)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns device range of link relay.
|
32
|
+
# @param [Integer] device_num first device number in range
|
33
|
+
# @param [Integer] device_points number in range
|
34
|
+
def self.link_relay(device_num:, device_points:)
|
35
|
+
new(device: Device.link_relay, device_num: device_num, device_points: device_points)
|
36
|
+
end
|
37
|
+
|
22
38
|
# Returns device range of data register.
|
23
39
|
# @param [Integer] device_num first device number in range
|
24
40
|
# @param [Integer] device_points number in range
|
25
41
|
def self.data_register(device_num:, device_points:)
|
26
|
-
new(
|
42
|
+
new(device: Device.data_register, device_num: device_num, device_points: device_points)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns device range of link register.
|
46
|
+
# @param [Integer] device_num first device number in range
|
47
|
+
# @param [Integer] device_points number in range
|
48
|
+
def self.link_register(device_num:, device_points:)
|
49
|
+
new(device: Device.link_register, device_num: device_num, device_points: device_points)
|
27
50
|
end
|
28
51
|
|
29
52
|
# Returns range size.
|
@@ -35,12 +58,12 @@ module McProtocolE
|
|
35
58
|
# Returns binary string.
|
36
59
|
# @return [String] binary string
|
37
60
|
def to_b
|
38
|
-
[[device_num].pack("V")[0..2],
|
61
|
+
[[device_num].pack("V")[0..2], device.code, [device_points].pack("v")].join
|
39
62
|
end
|
40
63
|
|
41
64
|
private
|
42
65
|
|
43
|
-
attr_reader :
|
66
|
+
attr_reader :device, :device_num, :device_points
|
44
67
|
|
45
68
|
end
|
46
69
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'batch_read_in_multiple'
|
3
4
|
require_relative 'batch_read_in_word'
|
4
5
|
require_relative 'batch_write_in_word'
|
5
6
|
require_relative 'response'
|
@@ -23,18 +24,26 @@ module McProtocolE
|
|
23
24
|
@command = command
|
24
25
|
end
|
25
26
|
|
26
|
-
# Returns a request to batch read.
|
27
|
+
# Returns a request to batch read in multiple.
|
27
28
|
# @param [AccessRoute] access_route access route
|
28
29
|
# @param [Numeric] wait_sec waiting second
|
29
|
-
# @param [DeviceRange]
|
30
|
+
# @param [Array<DeviceRange>] device_ranges device ranges
|
31
|
+
def self.batch_read_in_multiple(access_route:, wait_sec:, device_ranges:)
|
32
|
+
new(access_route: access_route, wait_sec: wait_sec, command: BatchReadInMultiple.new(device_ranges: device_ranges))
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns a request to batch read in word.
|
36
|
+
# @param [AccessRoute] access_route access route
|
37
|
+
# @param [Numeric] wait_sec waiting second
|
38
|
+
# @param [DeviceRange] device_range device range
|
30
39
|
def self.batch_read_in_word(access_route:, wait_sec:, device_range:)
|
31
40
|
new(access_route: access_route, wait_sec: wait_sec, command: BatchReadInWord.new(device_range: device_range))
|
32
41
|
end
|
33
42
|
|
34
|
-
# Returns a request to batch write.
|
43
|
+
# Returns a request to batch write in word.
|
35
44
|
# @param [AccessRoute] access_route access route
|
36
45
|
# @param [Numeric] wait_sec waiting second
|
37
|
-
# @param [DeviceRange] device_range
|
46
|
+
# @param [DeviceRange] device_range device range
|
38
47
|
# @param [Array] values values to write
|
39
48
|
def self.batch_write_in_word(access_route:, wait_sec:, device_range:, values:)
|
40
49
|
new(access_route: access_route, wait_sec: wait_sec, command: BatchWriteInWord.new(device_range: device_range, values: values))
|
@@ -14,7 +14,7 @@ module McProtocolE
|
|
14
14
|
MAX_RECV_LEN = 1024 * 1024
|
15
15
|
SUCCEED_CODE = 0
|
16
16
|
|
17
|
-
attr_reader :data
|
17
|
+
attr_reader :code, :data
|
18
18
|
|
19
19
|
# Constructor.
|
20
20
|
# @param [String] raw_res binary string of response
|
@@ -48,10 +48,6 @@ module McProtocolE
|
|
48
48
|
!succeed?
|
49
49
|
end
|
50
50
|
|
51
|
-
private
|
52
|
-
|
53
|
-
attr_reader :code
|
54
|
-
|
55
51
|
end
|
56
52
|
end
|
57
53
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mc_protocol_e
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- commis1059
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -55,7 +55,8 @@ dependencies:
|
|
55
55
|
description:
|
56
56
|
email:
|
57
57
|
- commis.1059@gmail.com
|
58
|
-
executables:
|
58
|
+
executables:
|
59
|
+
- mc_protocol_e.rb
|
59
60
|
extensions: []
|
60
61
|
extra_rdoc_files: []
|
61
62
|
files:
|
@@ -71,18 +72,22 @@ files:
|
|
71
72
|
- Rakefile
|
72
73
|
- bin/console
|
73
74
|
- bin/setup
|
75
|
+
- exe/mc_protocol_e.rb
|
74
76
|
- lib/mc_protocol_e.rb
|
75
77
|
- lib/mc_protocol_e/client.rb
|
76
78
|
- lib/mc_protocol_e/frame_1e/access_route.rb
|
77
79
|
- lib/mc_protocol_e/frame_1e/batch_read_in_word.rb
|
78
80
|
- lib/mc_protocol_e/frame_1e/batch_write_in_word.rb
|
81
|
+
- lib/mc_protocol_e/frame_1e/device.rb
|
79
82
|
- lib/mc_protocol_e/frame_1e/device_range.rb
|
80
83
|
- lib/mc_protocol_e/frame_1e/request.rb
|
81
84
|
- lib/mc_protocol_e/frame_1e/response.rb
|
82
85
|
- lib/mc_protocol_e/frame_3e/access_route.rb
|
83
86
|
- lib/mc_protocol_e/frame_3e/base_command.rb
|
87
|
+
- lib/mc_protocol_e/frame_3e/batch_read_in_multiple.rb
|
84
88
|
- lib/mc_protocol_e/frame_3e/batch_read_in_word.rb
|
85
89
|
- lib/mc_protocol_e/frame_3e/batch_write_in_word.rb
|
90
|
+
- lib/mc_protocol_e/frame_3e/device.rb
|
86
91
|
- lib/mc_protocol_e/frame_3e/device_range.rb
|
87
92
|
- lib/mc_protocol_e/frame_3e/error_info.rb
|
88
93
|
- lib/mc_protocol_e/frame_3e/request.rb
|