prologix_gpib 0.4.4 → 0.5.3
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/.tool-versions +1 -1
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +11 -10
- data/NetFinder_info.md +30 -0
- data/README.md +58 -19
- data/lan_test.rb +17 -0
- data/lib/prologix_gpib/cli.rb +52 -26
- data/lib/prologix_gpib/{usb/commands.rb → commands.rb} +18 -32
- data/lib/prologix_gpib/discovery.rb +128 -0
- data/lib/prologix_gpib/lan.rb +69 -2
- data/lib/prologix_gpib/usb.rb +21 -12
- data/lib/prologix_gpib/version.rb +1 -1
- data/lib/prologix_gpib.rb +12 -25
- data/prologix_gpib.gemspec +5 -4
- data/test_broadcast.rb +50 -0
- data/test_script.rb +43 -4
- data/test_server.rb +35 -0
- metadata +34 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ac431f2d4186660651615941aa70b69de9d49de98d8101861e66daf9cc90cd9
|
4
|
+
data.tar.gz: c77f6db86bf82377345283cfc41e62b4cfe9f4d37f5ba5375021a4711f696369
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be989bbe8e07016b4f42b0b865474338fce70eaed5e828dae502d91db0d637903274bb9c734ac81e2249b87ad4a2c06025fcfab0c1a82f835763cbed993ae2fb
|
7
|
+
data.tar.gz: 66ed6d4a45a9ee22feb6470b73771f4e02c1ee38e0de666ff9c8b6e8cb01b242c9be1b20501761100332ba2a50a2a7e4e7144792c671831a4f87446506af50c0
|
data/.tool-versions
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby 3.1.
|
1
|
+
ruby 3.1.2
|
data/CHANGELOG.md
ADDED
data/Gemfile.lock
CHANGED
@@ -1,27 +1,29 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
prologix_gpib (0.
|
5
|
-
activesupport
|
6
|
-
|
4
|
+
prologix_gpib (0.5.0)
|
5
|
+
activesupport (~> 7.0.1)
|
6
|
+
bindata (~> 2.4.10)
|
7
|
+
rubyserial (~> 0.6.0)
|
7
8
|
terminal-table (~> 3.0.2)
|
8
|
-
thor
|
9
|
+
thor (~> 1.2.1)
|
9
10
|
|
10
11
|
GEM
|
11
12
|
remote: https://rubygems.org/
|
12
13
|
specs:
|
13
|
-
activesupport (7.0.
|
14
|
+
activesupport (7.0.3)
|
14
15
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
15
16
|
i18n (>= 1.6, < 2)
|
16
17
|
minitest (>= 5.1)
|
17
18
|
tzinfo (~> 2.0)
|
19
|
+
bindata (2.4.10)
|
18
20
|
coderay (1.1.3)
|
19
|
-
concurrent-ruby (1.1.
|
21
|
+
concurrent-ruby (1.1.10)
|
20
22
|
ffi (1.15.5)
|
21
|
-
i18n (1.
|
23
|
+
i18n (1.10.0)
|
22
24
|
concurrent-ruby (~> 1.0)
|
23
25
|
method_source (1.0.0)
|
24
|
-
minitest (5.
|
26
|
+
minitest (5.16.1)
|
25
27
|
pry (0.14.1)
|
26
28
|
coderay (~> 1.1)
|
27
29
|
method_source (~> 1.0)
|
@@ -43,7 +45,6 @@ DEPENDENCIES
|
|
43
45
|
prologix_gpib!
|
44
46
|
pry
|
45
47
|
rake (~> 10.0)
|
46
|
-
rubyserial (~> 0.6)
|
47
48
|
|
48
49
|
BUNDLED WITH
|
49
|
-
2.
|
50
|
+
2.3.16
|
data/NetFinder_info.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Net Finder
|
2
|
+
|
3
|
+
NetFinder, uses UDP broadcast to locate and configure GPIB-ETH controllers on a network.
|
4
|
+
You can find an implementation of the protocol in the nfcli utility
|
5
|
+
http://prologix.biz/downloads/nfcli.tar.gz
|
6
|
+
|
7
|
+
### Discovery
|
8
|
+
|
9
|
+
- Create NF_IDENTIFY packet.
|
10
|
+
- Set sequence to a random value
|
11
|
+
- Set eth_addr to all ones
|
12
|
+
- Broadcast NF_IDENTIFY datagram to port 3040/UDP.
|
13
|
+
- Listen for NF_IDENTIFY_REPLY datagrams.
|
14
|
+
- Verify sequence matches NF_IDENTIFY packet
|
15
|
+
|
16
|
+
### Configuration
|
17
|
+
|
18
|
+
- Create NF_ASSIGNMENT packet
|
19
|
+
- Set sequence to a random value
|
20
|
+
- Set eth_addr to MAC address of desired device Set ip_type to NF_IP_DYNAMIC or NF_IP_STATIC If ip_type is NF_IP_DYNAMIC specify ip, mask and gateway addresses.
|
21
|
+
- Broadcast NF\* ASSIGNMENT datagram to port 3040/UDP.
|
22
|
+
- Listen for NF_ASSIGNMENT_REPLY datagrams.
|
23
|
+
- Verify sequence matches that of NF_ASSIGNMENT packet Check result field for NF_SUCCESS
|
24
|
+
|
25
|
+
Notes:
|
26
|
+
|
27
|
+
1. You may get multiple replies. Discard duplicate replies.
|
28
|
+
2. All multi-byte values are in network order (big-endian)
|
29
|
+
3. On multi-homed hosts, make sure broadcasts go out over all interfaces.
|
30
|
+
4. NetFinder protocol only works within the same subnet as routers will not forward UDP broadcast packets.
|
data/README.md
CHANGED
@@ -24,18 +24,20 @@ Or install it yourself as:
|
|
24
24
|
|
25
25
|
### CLI
|
26
26
|
|
27
|
-
The gem comes with a simple cli for
|
27
|
+
The gem comes with a simple cli for finding controllers:
|
28
28
|
|
29
29
|
```bash
|
30
30
|
$ plx list
|
31
|
-
|
32
|
-
|
|
33
|
-
|
34
|
-
| index | Controller
|
35
|
-
|
36
|
-
| 0 | Prologix GPIB-USB Controller
|
37
|
-
| 1 | Prologix GPIB-USB Controller
|
38
|
-
|
31
|
+
+-----------------------------------------------------------------------------------------+
|
32
|
+
| Prologix Controllers |
|
33
|
+
+-------+------------------------------------+--------------+-----------------------------+
|
34
|
+
| index | Controller | Version | Location |
|
35
|
+
+-------+------------------------------------+--------------+-----------------------------+
|
36
|
+
| 0 | Prologix GPIB-USB Controller | 6.101 | /dev/tty.usbserial-PX9HPBMB |
|
37
|
+
| 1 | Prologix GPIB-USB Controller | 6.107 | /dev/tty.usbserial-PXEGWA9A |
|
38
|
+
| 2 | Prologix GPIB-LAN Controller | 01.03.00.00 | 192.168.10.161 |
|
39
|
+
| 3 | Prologix GPIB-ETHERNET Controller | 01.06.06.00 | 192.168.10.127 |
|
40
|
+
+-------+------------------------------------+--------------+-----------------------------+
|
39
41
|
|
40
42
|
$ plx info 0
|
41
43
|
|
@@ -50,24 +52,52 @@ $ plx info 0
|
|
50
52
|
EOS: Append CR+LF
|
51
53
|
EOT: Enabled
|
52
54
|
|
55
|
+
plx info 3
|
56
|
+
|
57
|
+
Prologix gpib-ethernet controller
|
58
|
+
Path: 192.168.10.127
|
59
|
+
Firmware: 01.06.06.00
|
60
|
+
Mode: Controller
|
61
|
+
Device Address: 5
|
62
|
+
Auto Read: Enabled
|
63
|
+
Read Timeout: 500
|
64
|
+
Eoi Assertion: Enabled
|
65
|
+
Eos: Append CR+LF
|
66
|
+
Eot: Disabled
|
53
67
|
```
|
54
68
|
|
55
|
-
###
|
69
|
+
### Finding Controllers
|
56
70
|
|
57
|
-
|
71
|
+
```irb
|
72
|
+
irb(main):001:0> f = PrologixGpib::Finder.new
|
73
|
+
=> #<PrologixGpib::Finder:0x00000001089844b0>
|
74
|
+
irb(main):002:0> controllers = f.avaliable_controllers
|
75
|
+
=> {
|
76
|
+
:usb=>["/dev/tty.usbserial-PX9HPBMB", "/dev/tty.usbserial-PXEGWA9A"],
|
77
|
+
:lan=>["192.168.10.161", "192.168.10.165"]
|
78
|
+
}
|
58
79
|
|
59
|
-
```
|
60
|
-
|
61
|
-
|
80
|
+
```
|
81
|
+
|
82
|
+
### Working with Controllers
|
62
83
|
|
63
|
-
|
64
|
-
=> ["/dev/tty.usbserial-PX9HPBMB", "/dev/tty.usbserial-PXEGWA9A"]
|
84
|
+
I'm not enamoured by this interface, I'd like a more ruby like way of finding and connecting controllers thats less clunky. It works for now, but may change as we refine things.
|
65
85
|
|
66
|
-
|
86
|
+
```ruby
|
87
|
+
irb(main):003:0> device = PrologixGpib::UsbController.new(controllers[:usb][0])
|
67
88
|
=> #<PrologixGpib::UsbController:0x00000001574c4098 @serial_port=#<Serial:0x00000001574bfef8 @config=#<RubySerial::Posix::Termios:0x00000001574bf728>, @fd=9, @open=true>>
|
68
89
|
|
69
90
|
irb(main):004:0> device.config
|
70
|
-
=> {
|
91
|
+
=> {
|
92
|
+
:device_name=>"Prologix GPIB-USB Controller",
|
93
|
+
:firmware=>"6.101", :mode=>"Device",
|
94
|
+
:device_address=>"9",
|
95
|
+
:auto_read=>"NA",
|
96
|
+
:read_timeout=>"NA",
|
97
|
+
:eoi_assertion=>"Enabled",
|
98
|
+
:eos=>"Append CR+LF",
|
99
|
+
:eot=>"Enabled"
|
100
|
+
}
|
71
101
|
|
72
102
|
irb(main):005:0> device.address
|
73
103
|
=> "9"
|
@@ -79,7 +109,16 @@ irb(main):007:0> device.mode
|
|
79
109
|
=> "0"
|
80
110
|
|
81
111
|
irb(main):008:0> device.config
|
82
|
-
=> {
|
112
|
+
=> {
|
113
|
+
:device_name=>"Prologix GPIB-USB Controller",
|
114
|
+
:firmware=>"6.101", :mode=>"Controller",
|
115
|
+
:device_address=>"9",
|
116
|
+
:auto_read=>"Disabled",
|
117
|
+
:read_timeout=>"200",
|
118
|
+
:eoi_assertion=>"Enabled",
|
119
|
+
:eos=>"Append CR+LF",
|
120
|
+
:eot=>"Enabled"
|
121
|
+
}
|
83
122
|
```
|
84
123
|
|
85
124
|
### Firmware update
|
data/lan_test.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'prologix_gpib'
|
2
|
+
require 'socket'
|
3
|
+
|
4
|
+
class Scanner
|
5
|
+
def search(range, timeout = 0.1)
|
6
|
+
array = []
|
7
|
+
range.each do |x|
|
8
|
+
s = Socket.tcp("192.168.10.#{x}", 1234, connect_timeout: timeout)
|
9
|
+
s.write("++ver\r\n")
|
10
|
+
array << s.gets
|
11
|
+
rescue => error
|
12
|
+
puts error.inspect
|
13
|
+
next
|
14
|
+
end
|
15
|
+
array
|
16
|
+
end
|
17
|
+
end
|
data/lib/prologix_gpib/cli.rb
CHANGED
@@ -2,52 +2,78 @@ require 'thor'
|
|
2
2
|
require 'pp'
|
3
3
|
require 'prologix_gpib'
|
4
4
|
require 'terminal-table'
|
5
|
+
require 'resolv'
|
5
6
|
|
6
7
|
module PrologixGpib
|
7
8
|
class CLI < Thor
|
9
|
+
def initialize(*args)
|
10
|
+
super
|
11
|
+
@controllers = PrologixGpib::Finder.new.avaliable_controllers
|
12
|
+
end
|
13
|
+
|
8
14
|
desc 'list', 'List all connected controllers'
|
9
15
|
|
10
16
|
def list
|
11
|
-
|
12
|
-
table =
|
13
|
-
Terminal::Table.new do |t|
|
14
|
-
t.title = 'Prologix Controllers'
|
15
|
-
t.headings = %w[index Controller Version Path]
|
16
|
-
PrologixGpib.usb_paths.each.with_index do |path, index|
|
17
|
-
device = PrologixGpib::UsbController.new(path)
|
18
|
-
str = device.version.split('version')
|
19
|
-
t.add_row [index.to_s, str[0], str[1], path]
|
20
|
-
end
|
21
|
-
end
|
22
|
-
puts table
|
23
|
-
else
|
24
|
-
puts 'No Prologix Controllers available.'
|
25
|
-
end
|
17
|
+
puts controller_table(@controllers)
|
26
18
|
end
|
27
19
|
|
28
|
-
desc 'info', 'Display Controller information'
|
29
|
-
option :path,
|
30
|
-
def info
|
20
|
+
desc 'info [INDEX]', 'Display Controller information'
|
21
|
+
option :path, aliases: :p
|
22
|
+
def info(index)
|
31
23
|
return unless controllers_connected?
|
32
24
|
|
33
|
-
|
25
|
+
controller_paths = @controllers.map { |k, v| v }.flatten
|
34
26
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
27
|
+
path = controller_paths[index.to_i]
|
28
|
+
hash = ip_address?(path) ? PrologixGpib::LanController.new(path).config : PrologixGpib::UsbController.new(path).config
|
29
|
+
|
30
|
+
puts "\n #{titleise hash.delete(:device_name)}"
|
31
|
+
puts "\tPath: #{path}"
|
32
|
+
hash.each { |k, v| puts "\t#{titleise(k)}: #{v}" }
|
41
33
|
end
|
42
34
|
|
43
35
|
private
|
44
36
|
|
37
|
+
def controller_table(controllers)
|
38
|
+
return 'No Prologix Controllers available.' unless controllers.length > 0
|
39
|
+
|
40
|
+
table =
|
41
|
+
Terminal::Table.new do |t|
|
42
|
+
t.title = 'Prologix Controllers'
|
43
|
+
t.headings = %w[index Controller Version Location]
|
44
|
+
end
|
45
|
+
|
46
|
+
index = 0
|
47
|
+
if controllers.key? :usb
|
48
|
+
controllers[:usb].each do |path|
|
49
|
+
device = PrologixGpib::UsbController.new(path)
|
50
|
+
str = device.version.split('version')
|
51
|
+
table.add_row [index.to_s, str[0], str[1], path]
|
52
|
+
index += 1
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
if controllers.key? :lan
|
57
|
+
controllers[:lan].each do |ip|
|
58
|
+
device = PrologixGpib::LanController.new(ip)
|
59
|
+
str = device.version.split('version')
|
60
|
+
table.add_row [index.to_s, str[0], str[1], ip]
|
61
|
+
index += 1
|
62
|
+
end
|
63
|
+
end
|
64
|
+
table
|
65
|
+
end
|
66
|
+
|
45
67
|
def controllers_connected?
|
46
|
-
|
68
|
+
@controllers[:usb].any? || @controllers[:lan].any?
|
47
69
|
end
|
48
70
|
|
49
71
|
def titleise(string)
|
50
72
|
string.to_s.split('_').map(&:capitalize).join(' ')
|
51
73
|
end
|
74
|
+
|
75
|
+
def ip_address?(string)
|
76
|
+
string =~ Resolv::IPv4::Regex ? true : false
|
77
|
+
end
|
52
78
|
end
|
53
79
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module PrologixGpib::
|
1
|
+
module PrologixGpib::Commands
|
2
2
|
def config
|
3
3
|
error_message = 'Error'
|
4
4
|
device_version = version.split('version').map(&:strip)
|
@@ -40,7 +40,7 @@ module PrologixGpib::Usb::Commands
|
|
40
40
|
conf
|
41
41
|
end
|
42
42
|
|
43
|
-
# This command configures the Prologix GPIB-USB controller to be a :controller or :device.
|
43
|
+
# # This command configures the Prologix GPIB-USB controller to be a :controller or :device.
|
44
44
|
def mode=(op_mode)
|
45
45
|
mode =
|
46
46
|
case op_mode
|
@@ -60,8 +60,8 @@ module PrologixGpib::Usb::Commands
|
|
60
60
|
end
|
61
61
|
alias operation_mode mode
|
62
62
|
|
63
|
-
# Timeout value, in milliseconds, used in the read command and spoll command.
|
64
|
-
# Any value between 1 and 3000 milliseconds.
|
63
|
+
# # Timeout value, in milliseconds, used in the read command and spoll command.
|
64
|
+
# # Any value between 1 and 3000 milliseconds.
|
65
65
|
def timeout=(milliseconds)
|
66
66
|
return unless connected? || milliseconds.class != Integer
|
67
67
|
|
@@ -72,8 +72,8 @@ module PrologixGpib::Usb::Commands
|
|
72
72
|
device_query('++read_tmo_ms')
|
73
73
|
end
|
74
74
|
|
75
|
-
# PrologixGPIB-USB controller can be configured to automatically address instruments to 'talk' after sending a command in order to read the response.
|
76
|
-
# *** Avaliable in Controller mode. When enabled can cause the prologix controller to lockup. ***
|
75
|
+
# # PrologixGPIB-USB controller can be configured to automatically address instruments to 'talk' after sending a command in order to read the response.
|
76
|
+
# # *** Avaliable in Controller mode. When enabled can cause the prologix controller to lockup. ***
|
77
77
|
def auto=(auto_mode)
|
78
78
|
mode =
|
79
79
|
case auto_mode
|
@@ -93,8 +93,8 @@ module PrologixGpib::Usb::Commands
|
|
93
93
|
end
|
94
94
|
alias auto_read_after_write auto
|
95
95
|
|
96
|
-
# In :controller mode, address refers to the GPIB address of the instrument being controlled.
|
97
|
-
# In :device mode, it is the address of the GPIB peripheral that Prologix GPIB-USB controller is emulating.
|
96
|
+
# # In :controller mode, address refers to the GPIB address of the instrument being controlled.
|
97
|
+
# # In :device mode, it is the address of the GPIB peripheral that Prologix GPIB-USB controller is emulating.
|
98
98
|
def address=(addr)
|
99
99
|
write("++addr #{addr}")
|
100
100
|
end
|
@@ -104,8 +104,8 @@ module PrologixGpib::Usb::Commands
|
|
104
104
|
device_query('++addr')
|
105
105
|
end
|
106
106
|
|
107
|
-
# This command enables or disables the assertion of the EOI signal with the last character of any command sent over GPIB port.
|
108
|
-
# Some instruments require EOI signal to be asserted in order to properly detect the end of a command.
|
107
|
+
# # This command enables or disables the assertion of the EOI signal with the last character of any command sent over GPIB port.
|
108
|
+
# # Some instruments require EOI signal to be asserted in order to properly detect the end of a command.
|
109
109
|
def eoi=(eoi_mode)
|
110
110
|
mode =
|
111
111
|
case eoi_mode
|
@@ -123,13 +123,13 @@ module PrologixGpib::Usb::Commands
|
|
123
123
|
device_query('++eoi')
|
124
124
|
end
|
125
125
|
|
126
|
-
# This command specifies GPIB termination characters. When data from host is received over USB, all non-escaped LF, CR and ESC characters are removed and GPIB terminators, as specified by this command, are appended before sending the data to instruments.
|
127
|
-
# This command does not affect data from instruments received over GPIB port.
|
128
|
-
# EXAMPLES:
|
129
|
-
# 0 Append CR+LF
|
130
|
-
# 1 Append CR to instrument commands
|
131
|
-
# 2 Append LF to instrument commands
|
132
|
-
# 3 Do not append anything to instrument commands
|
126
|
+
# # This command specifies GPIB termination characters. When data from host is received over USB, all non-escaped LF, CR and ESC characters are removed and GPIB terminators, as specified by this command, are appended before sending the data to instruments.
|
127
|
+
# # This command does not affect data from instruments received over GPIB port.
|
128
|
+
# # EXAMPLES:
|
129
|
+
# # 0 Append CR+LF
|
130
|
+
# # 1 Append CR to instrument commands
|
131
|
+
# # 2 Append LF to instrument commands
|
132
|
+
# # 3 Do not append anything to instrument commands
|
133
133
|
def eos=(eos_mode)
|
134
134
|
error_message = "Invalid arg: '#{eos_mode}'"
|
135
135
|
raise ArgumentError, error_message unless [0, 1, 2, 3].include? eos_mode
|
@@ -141,7 +141,7 @@ module PrologixGpib::Usb::Commands
|
|
141
141
|
device_query('++eos')
|
142
142
|
end
|
143
143
|
|
144
|
-
# This command enables or disables the appending of a user specified character (see eot_char) to USB output whenever EOI is detected while reading a character from the GPIBport.
|
144
|
+
# # This command enables or disables the appending of a user specified character (see eot_char) to USB output whenever EOI is detected while reading a character from the GPIBport.
|
145
145
|
def eot=(eot_mode)
|
146
146
|
mode =
|
147
147
|
case eot_mode
|
@@ -186,18 +186,4 @@ module PrologixGpib::Usb::Commands
|
|
186
186
|
def reset
|
187
187
|
write('++rst')
|
188
188
|
end
|
189
|
-
|
190
|
-
def flush
|
191
|
-
return unless connected?
|
192
|
-
|
193
|
-
loop until serial_port.getbyte.nil?
|
194
|
-
end
|
195
|
-
|
196
|
-
private
|
197
|
-
|
198
|
-
def device_query(command)
|
199
|
-
flush
|
200
|
-
write(command)
|
201
|
-
readline
|
202
|
-
end
|
203
189
|
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
module PrologixGpib::Discovery
|
2
|
+
require 'socket'
|
3
|
+
require 'ipaddr'
|
4
|
+
require 'bindata'
|
5
|
+
require 'timeout'
|
6
|
+
|
7
|
+
class Error < StandardError
|
8
|
+
end
|
9
|
+
|
10
|
+
def avaliable_controllers
|
11
|
+
{ usb: usb_device_paths, lan: lan_device_ips }
|
12
|
+
end
|
13
|
+
|
14
|
+
class IPAddr < BinData::Primitive
|
15
|
+
array :octets, type: :uint8, initial_length: 4
|
16
|
+
|
17
|
+
def set(val)
|
18
|
+
self.octets = val.split(/\./).map(&:to_i)
|
19
|
+
end
|
20
|
+
|
21
|
+
def get
|
22
|
+
self.octets.map(&:to_s).join('.')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class MacAddr < BinData::Primitive
|
27
|
+
array :octets, type: :uint8, initial_length: 6
|
28
|
+
|
29
|
+
def set(val)
|
30
|
+
self.octets = val.split(/:/).map(&:hex)
|
31
|
+
end
|
32
|
+
|
33
|
+
def get
|
34
|
+
self.octets.map { |octet| '%02x' % octet }.join(':')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class NFHeader < BinData::Record
|
39
|
+
endian :big
|
40
|
+
uint8 :magic
|
41
|
+
uint8 :identify
|
42
|
+
uint16 :seq
|
43
|
+
mac_addr :eth_addr
|
44
|
+
bit16 :reserved, initial_value: 0x0000
|
45
|
+
end
|
46
|
+
|
47
|
+
class NFIdentifyReply < BinData::Record
|
48
|
+
endian :big
|
49
|
+
nf_header :header
|
50
|
+
uint16 :uptime_days
|
51
|
+
uint8 :uptime_hrs
|
52
|
+
uint8 :uptime_mins
|
53
|
+
uint8 :uptime_secs
|
54
|
+
uint8 :mode
|
55
|
+
uint8 :alert
|
56
|
+
uint8 :ip_type
|
57
|
+
ip_addr :addr
|
58
|
+
ip_addr :netmask
|
59
|
+
string :ip_gw, read_length: 4
|
60
|
+
string :app_ver, read_length: 4
|
61
|
+
string :boot_ver, read_length: 4
|
62
|
+
string :hw_ver, read_length: 4
|
63
|
+
end
|
64
|
+
|
65
|
+
NF_MAGIC = 0x5a
|
66
|
+
HEADER_FMT = 'CCna8'
|
67
|
+
NF_IDENTIFY = 0
|
68
|
+
NF_IDENTIFY_REPLY = 1
|
69
|
+
BROADCAST_PORT = 3040
|
70
|
+
BROADCAST_ADDRESS = '255.255.255.255'
|
71
|
+
TIMEOUT = 0.5
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def lan_device_ips
|
76
|
+
seq = rand(0..65_535)
|
77
|
+
|
78
|
+
# puts "Seq = #{seq}"
|
79
|
+
sock = UDPSocket.new
|
80
|
+
sock.setsockopt(:SOL_SOCKET, :SO_BROADCAST, true)
|
81
|
+
|
82
|
+
# data = [NF_MAGIC, NF_IDENTIFY, seq, "\xFF\xFF\xFF\xFF\xFF\xFF"].pack(HEADER_FMT)
|
83
|
+
|
84
|
+
data = NFHeader.new
|
85
|
+
data.magic = NF_MAGIC
|
86
|
+
data.identify = NF_IDENTIFY
|
87
|
+
data.seq = seq
|
88
|
+
data.eth_addr = 'FF:FF:FF:FF:FF:FF'
|
89
|
+
|
90
|
+
sock.send(data.to_binary_s, 0, BROADCAST_ADDRESS, BROADCAST_PORT)
|
91
|
+
array = []
|
92
|
+
replies = []
|
93
|
+
begin
|
94
|
+
Timeout.timeout(TIMEOUT) do
|
95
|
+
while true
|
96
|
+
data, addr = sock.recvfrom(1000)
|
97
|
+
replies << data
|
98
|
+
end
|
99
|
+
end
|
100
|
+
rescue Timeout::Error
|
101
|
+
replies.each do |data|
|
102
|
+
begin
|
103
|
+
reply = NFIdentifyReply.read(data)
|
104
|
+
rescue EOFError
|
105
|
+
# About 1% of responses are not always as expected from the controller
|
106
|
+
next
|
107
|
+
end
|
108
|
+
next if array.include?(reply.addr)
|
109
|
+
array << reply.addr if reply.header.seq == seq && reply.header.identify == NF_IDENTIFY_REPLY
|
110
|
+
end
|
111
|
+
sock.close
|
112
|
+
array
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def usb_device_paths
|
117
|
+
path_str, dir =
|
118
|
+
if RubySerial::ON_LINUX
|
119
|
+
%w[ttyUSB /dev/]
|
120
|
+
elsif RubySerial::ON_WINDOWS
|
121
|
+
['TODO: Implement find device for Windows', 'You lazy bugger']
|
122
|
+
else
|
123
|
+
%w[tty.usbserial /dev/]
|
124
|
+
end
|
125
|
+
|
126
|
+
Dir.glob("#{dir}#{path_str}*")
|
127
|
+
end
|
128
|
+
end
|
data/lib/prologix_gpib/lan.rb
CHANGED
@@ -1,3 +1,70 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
|
1
3
|
module PrologixGpib::Lan
|
2
|
-
class Error < StandardError
|
3
|
-
end
|
4
|
+
class Error < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
DEVICE_PORT = 1234
|
8
|
+
EOL = "\r\n".freeze
|
9
|
+
|
10
|
+
def initialize(ip, mode: :controller, address: 9)
|
11
|
+
open_socket(ip)
|
12
|
+
|
13
|
+
# open_serial_port(paths)
|
14
|
+
# flush
|
15
|
+
# self.mode = mode
|
16
|
+
# self.address = address
|
17
|
+
# self.auto = :disable
|
18
|
+
# self.eos = 0
|
19
|
+
|
20
|
+
yield self if block_given?
|
21
|
+
end
|
22
|
+
|
23
|
+
def write(command)
|
24
|
+
return unless connected?
|
25
|
+
|
26
|
+
@socket.send "#{command}#{EOL}", 0
|
27
|
+
sleep 0.1
|
28
|
+
end
|
29
|
+
|
30
|
+
def read
|
31
|
+
return unless connected?
|
32
|
+
|
33
|
+
@socket.gets.chomp
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def open_socket(ip)
|
39
|
+
@socket = TCPSocket.new ip, DEVICE_PORT
|
40
|
+
write('++ver')
|
41
|
+
return if getline.include? 'Prologix'
|
42
|
+
|
43
|
+
raise Error, 'No Prologix LAN controllers found.'
|
44
|
+
end
|
45
|
+
|
46
|
+
def connected?
|
47
|
+
raise Error, 'ConnectionError: No open Prologix device connections.' if @socket.nil?
|
48
|
+
|
49
|
+
true
|
50
|
+
end
|
51
|
+
|
52
|
+
def readline
|
53
|
+
return unless connected?
|
54
|
+
|
55
|
+
t = Timeout.timeout(1, Timeout::Error, "No response from device at #{@socket.peeraddr[3]}") { getline }
|
56
|
+
end
|
57
|
+
|
58
|
+
# This method will block until the EOL terminator is received
|
59
|
+
# The lower level gets method is pure ruby, so can be safely used with Timeout.
|
60
|
+
def getline
|
61
|
+
return unless connected?
|
62
|
+
|
63
|
+
@socket.gets(EOL).chomp
|
64
|
+
end
|
65
|
+
|
66
|
+
def device_query(command)
|
67
|
+
write(command)
|
68
|
+
readline
|
69
|
+
end
|
70
|
+
end
|
data/lib/prologix_gpib/usb.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module PrologixGpib::Usb
|
2
2
|
require 'timeout'
|
3
|
-
require 'prologix_gpib/usb/commands'
|
4
3
|
|
5
4
|
class Error < StandardError
|
6
5
|
end
|
@@ -10,8 +9,7 @@ module PrologixGpib::Usb
|
|
10
9
|
attr_reader :serial_port
|
11
10
|
|
12
11
|
def initialize(path, mode: :controller, address: 9)
|
13
|
-
|
14
|
-
open_serial_port(paths)
|
12
|
+
open_serial_port(path)
|
15
13
|
flush
|
16
14
|
self.mode = mode
|
17
15
|
self.address = address
|
@@ -29,10 +27,10 @@ module PrologixGpib::Usb
|
|
29
27
|
@serial_port.nil?
|
30
28
|
end
|
31
29
|
|
32
|
-
def write(
|
30
|
+
def write(string)
|
33
31
|
return unless connected?
|
34
32
|
|
35
|
-
@serial_port.write("#{
|
33
|
+
@serial_port.write("#{string}#{EOL}")
|
36
34
|
end
|
37
35
|
|
38
36
|
def read(bytes)
|
@@ -44,7 +42,7 @@ module PrologixGpib::Usb
|
|
44
42
|
def readline
|
45
43
|
return unless connected?
|
46
44
|
|
47
|
-
t = Timeout.timeout(1, Timeout::Error, 'No response from
|
45
|
+
t = Timeout.timeout(1, Timeout::Error, 'No response from device') { getline }
|
48
46
|
end
|
49
47
|
|
50
48
|
def sr(register = nil)
|
@@ -58,12 +56,11 @@ module PrologixGpib::Usb
|
|
58
56
|
|
59
57
|
private
|
60
58
|
|
61
|
-
def open_serial_port(
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
59
|
+
def open_serial_port(path)
|
60
|
+
@serial_port = Serial.new(path)
|
61
|
+
write('++ver')
|
62
|
+
return if getline.include? 'Prologix'
|
63
|
+
|
67
64
|
raise Error, 'No Prologix USB controllers found.'
|
68
65
|
end
|
69
66
|
|
@@ -73,6 +70,12 @@ module PrologixGpib::Usb
|
|
73
70
|
true
|
74
71
|
end
|
75
72
|
|
73
|
+
def flush
|
74
|
+
return unless connected?
|
75
|
+
|
76
|
+
loop until serial_port.getbyte.nil?
|
77
|
+
end
|
78
|
+
|
76
79
|
# This method will block until the EOL terminator is received
|
77
80
|
# The lower level gets method is pure ruby, so can be safely used with Timeout.
|
78
81
|
def getline
|
@@ -80,4 +83,10 @@ module PrologixGpib::Usb
|
|
80
83
|
|
81
84
|
@serial_port.gets(EOL).chomp
|
82
85
|
end
|
86
|
+
|
87
|
+
def device_query(command)
|
88
|
+
flush
|
89
|
+
write(command)
|
90
|
+
readline
|
91
|
+
end
|
83
92
|
end
|
data/lib/prologix_gpib.rb
CHANGED
@@ -4,46 +4,33 @@ require 'rubyserial'
|
|
4
4
|
require 'prologix_gpib/version'
|
5
5
|
require 'prologix_gpib/lan'
|
6
6
|
require 'prologix_gpib/usb'
|
7
|
+
require 'prologix_gpib/commands'
|
8
|
+
require 'prologix_gpib/discovery'
|
7
9
|
require 'prologix_gpib/cli'
|
8
10
|
|
9
11
|
module PrologixGpib
|
10
12
|
class UsbController
|
13
|
+
def test
|
14
|
+
puts 'testing'
|
15
|
+
end
|
16
|
+
|
11
17
|
include PrologixGpib::Usb
|
12
|
-
include PrologixGpib::
|
18
|
+
include PrologixGpib::Commands
|
13
19
|
end
|
14
20
|
|
15
21
|
class LanController
|
16
22
|
include PrologixGpib::Lan
|
23
|
+
include PrologixGpib::Commands
|
24
|
+
end
|
25
|
+
|
26
|
+
class Finder
|
27
|
+
include PrologixGpib::Discovery
|
17
28
|
end
|
18
29
|
|
19
|
-
# Ideally this class needs to handle finding all avaliable Prologix GPIB controllers (USB and Ethernet),
|
20
|
-
# But for now it simply passes the Prologix USB device paths onto the controller class
|
21
30
|
# No windows serial support just yet.
|
22
31
|
class << self
|
23
32
|
def new
|
24
33
|
self
|
25
34
|
end
|
26
|
-
|
27
|
-
# Find first avaliable Prologix controller and return a valid controller object
|
28
|
-
def open; end
|
29
|
-
|
30
|
-
def usb_paths
|
31
|
-
usb_controller_paths
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def usb_controller_paths
|
37
|
-
path_str, dir =
|
38
|
-
if RubySerial::ON_LINUX
|
39
|
-
%w[ttyUSB /dev/]
|
40
|
-
elsif RubySerial::ON_WINDOWS
|
41
|
-
['TODO: Implement find device for Windows', 'You lazy bugger']
|
42
|
-
else
|
43
|
-
%w[tty.usbserial /dev/]
|
44
|
-
end
|
45
|
-
|
46
|
-
Dir.glob("#{dir}#{path_str}*")
|
47
|
-
end
|
48
35
|
end
|
49
36
|
end
|
data/prologix_gpib.gemspec
CHANGED
@@ -12,14 +12,14 @@ Gem::Specification.new do |spec|
|
|
12
12
|
|
13
13
|
spec.summary = 'Prologix GPIB controller ruby wrapper.'
|
14
14
|
spec.description = 'Ruby wrapper for the Prologix GPIB controllers, USB & Ethernet.'
|
15
|
-
spec.homepage = 'https://
|
15
|
+
spec.homepage = 'https://gitlab.com/robcarruthers/prologix_gpib.git'
|
16
16
|
spec.license = 'MIT'
|
17
17
|
|
18
18
|
# spec.metadata['allowed_push_host'] = "http://mygemserver.com'"
|
19
19
|
|
20
20
|
spec.metadata['homepage_uri'] = spec.homepage
|
21
|
-
spec.metadata['source_code_uri'] = 'https://
|
22
|
-
spec.metadata['changelog_uri'] = 'https://
|
21
|
+
spec.metadata['source_code_uri'] = 'https://gitlab.com/robcarruthers/prologix_gpib.git'
|
22
|
+
spec.metadata['changelog_uri'] = 'https://gitlab.com/robcarruthers/prologix_gpib.git'
|
23
23
|
|
24
24
|
# Specify which files should be added to the gem when it is released.
|
25
25
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
@@ -29,9 +29,10 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.require_paths = ['lib']
|
30
30
|
|
31
31
|
spec.add_dependency 'activesupport', '~> 7.0.1'
|
32
|
+
spec.add_dependency 'bindata', '~> 2.4.10'
|
32
33
|
spec.add_dependency 'rubyserial', '~> 0.6.0'
|
33
|
-
spec.add_dependency 'thor', '~> 1.2.1'
|
34
34
|
spec.add_dependency 'terminal-table', '~> 3.0.2'
|
35
|
+
spec.add_dependency 'thor', '~> 1.2.1'
|
35
36
|
|
36
37
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
37
38
|
spec.add_development_dependency 'rake', '~> 10.0'
|
data/test_broadcast.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
def broadcast
|
4
|
+
addr = '255.255.255.255'
|
5
|
+
sock = UDPSocket.new
|
6
|
+
sock.setsockopt(:SOL_SOCKET, :SO_BROADCAST, true)
|
7
|
+
|
8
|
+
port = 3040
|
9
|
+
|
10
|
+
data = [90, 0, 11_111, "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00"].pack('CCna8')
|
11
|
+
sock.send(data, 0, addr, port)
|
12
|
+
|
13
|
+
while true
|
14
|
+
r_data, r_addr = sock.recvfrom(2000) # if this number is too low it will drop the larger packets and never give them to you
|
15
|
+
p "From addr: #{r_addr}, msg: #{r_data}"
|
16
|
+
# p r_data.unpack('CCna8')
|
17
|
+
# puts ''
|
18
|
+
end
|
19
|
+
|
20
|
+
sock.close
|
21
|
+
end
|
22
|
+
|
23
|
+
# ❯ python
|
24
|
+
|
25
|
+
# WARNING: Python 2.7 is not recommended.
|
26
|
+
# This version is included in macOS for compatibility with legacy software.
|
27
|
+
# Future versions of macOS will not include Python 2.7.
|
28
|
+
# Instead, it is recommended that you transition to using 'python3' from within Terminal.
|
29
|
+
|
30
|
+
# Python 2.7.18 (default, Nov 13 2021, 06:17:34)
|
31
|
+
# [GCC Apple LLVM 13.0.0 (clang-1300.0.29.10) [+internal-os, ptrauth-isa=deployme on darwin
|
32
|
+
# Type "help", "copyright", "credits" or "license" for more information.
|
33
|
+
# >>> "Z\x00ST\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00".unpack("!2cH6s2x")
|
34
|
+
# Traceback (most recent call last):
|
35
|
+
# File "<stdin>", line 1, in <module>
|
36
|
+
# AttributeError: 'str' object has no attribute 'unpack'
|
37
|
+
# >>> struct.unpack("!2cH6s2x", "Z\x00ST\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00")
|
38
|
+
# Traceback (most recent call last):
|
39
|
+
# File "<stdin>", line 1, in <module>
|
40
|
+
# NameError: name 'struct' is not defined
|
41
|
+
# >>> import struct
|
42
|
+
# >>> struct.unpack("!2cH6s2x", "Z\x00ST\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00")
|
43
|
+
# ('Z', '\x00', 21332, '\xff\xff\xff\xff\xff\xff')
|
44
|
+
# >>> struct.unpack("!2cH6s2x", "Z\x00s|\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00")
|
45
|
+
# ('Z', '\x00', 29564, '\xff\xff\xff\xff\xff\xff')
|
46
|
+
# >>> struct.unpack("!2cH6s2x", 'Z\x00+g\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00')
|
47
|
+
# ('Z', '\x00', 11111, '\xff\xff\xff\xff\xff\xff')
|
48
|
+
# >>>
|
49
|
+
# 5a012b670021690100d700000000020324010000c0a80aa1ffffff00c0a80a01010300000101000001010000a5bba57bf645122ba7773d197aa7963448eb8c932a85527a24b3966096caa2ef
|
50
|
+
# "\x5a\x01\x2b\x67\x00\x21\x69\x01\x00\xd7\x00\x00\x00\x00\x02\x03\x24\x01\x00\x00\xc0\xa8\x0a\xa1\xff\xff\xff\x00\xc0\xa8\x0a\x01\x01\x03\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\xa5\xbb\xa5\x7b\xf6\x45\x12\x2b\xa7\x77\x3d\x19\x7a\xa7\x96\x34\x48\xeb\x8c\x93\x2a\x85\x52\x7a\x24\xb3\x96\x60\x96\xca\xa2\xef"
|
data/test_script.rb
CHANGED
@@ -1,6 +1,45 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
require '
|
3
|
-
paths = PrologixGpib.usb_paths
|
2
|
+
require 'bindata'
|
4
3
|
|
5
|
-
|
6
|
-
|
4
|
+
class NFHeader < BinData::Record
|
5
|
+
endian :big
|
6
|
+
uint8 :magic
|
7
|
+
uint8 :identify
|
8
|
+
uint16 :seq
|
9
|
+
string :addr, read_length: 6
|
10
|
+
string :res, read_length: 2
|
11
|
+
end
|
12
|
+
|
13
|
+
class IPAddr < BinData::Primitive
|
14
|
+
array :octets, type: :uint8, initial_length: 4
|
15
|
+
|
16
|
+
def set(val)
|
17
|
+
self.octets = val.split(/\./).map(&:to_i)
|
18
|
+
end
|
19
|
+
|
20
|
+
def get
|
21
|
+
self.octets.map(&:to_s).join('.')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class NFIdentifyReply < BinData::Record
|
26
|
+
endian :big
|
27
|
+
nf_header :header
|
28
|
+
uint16 :uptime_days
|
29
|
+
uint8 :uptime_hrs
|
30
|
+
uint8 :uptime_mins
|
31
|
+
uint8 :uptime_secs
|
32
|
+
uint8 :mode
|
33
|
+
uint8 :alert
|
34
|
+
uint8 :ip_type
|
35
|
+
ip_addr :addr
|
36
|
+
ip_addr :netmask
|
37
|
+
string :ip_gw, read_length: 4
|
38
|
+
string :app_ver, read_length: 4
|
39
|
+
string :boot_ver, read_length: 4
|
40
|
+
string :hw_ver, read_length: 4
|
41
|
+
end
|
42
|
+
|
43
|
+
@identify = "Z\x00+g\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00"
|
44
|
+
@indentify_reply =
|
45
|
+
'Z\x01+g\x00!i\x01\x00\xd7\x00\x00\x00\x00\x02\x03$\x01\x00\x00\xc0\xa8\n\xa1\xff\xff\xff\x00\xc0\xa8\n\x01\x01\x03\x00\x00\x01\x01\x00\x00\x01\x01\x00\x00\xa5\xbb\xa5{\xf6E\x12+\xa7w=\x19z\xa7\x964H\xeb\x8c\x93*\x85Rz$\xb3\x96`\x96\xca\xa2\xef'
|
data/test_server.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'ipaddr'
|
3
|
+
|
4
|
+
class UDPTest
|
5
|
+
def listen
|
6
|
+
s = UDPSocket.new
|
7
|
+
|
8
|
+
# membership = IPAddr.new(multicast_addr).hton + IPAddr.new(bind_addr).hton
|
9
|
+
# s.setsockopt(:IPPROTO_UDP, :IP_ADD_MEMBERSHIP, membership)
|
10
|
+
|
11
|
+
s.bind('', 3040)
|
12
|
+
while true
|
13
|
+
data, addr = s.recvfrom(1024)
|
14
|
+
puts "addr = #{addr}\r\ndata ="
|
15
|
+
p data
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def start_server
|
20
|
+
multi_addr = '225.1.1.1'
|
21
|
+
bind_addr = '0.0.0.0'
|
22
|
+
|
23
|
+
sock = UDPSocket.new
|
24
|
+
membership = IPAddr.new(multi_addr).hton + IPAddr.new(bind_addr).hton
|
25
|
+
sock.setsockopt(:IPPROTO_IP, :IP_ADD_MEMBERSHIP, membership)
|
26
|
+
sock.bind(bind_addr, 3040)
|
27
|
+
while true
|
28
|
+
data, addr = sock.recvfrom(2000) # if this number is too low it will drop the larger packets and never give them to you
|
29
|
+
p "From addr: #{addr}, msg: #{data}"
|
30
|
+
p data.unpack('CCna8')
|
31
|
+
puts ''
|
32
|
+
end
|
33
|
+
sock.close
|
34
|
+
end
|
35
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prologix_gpib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Carruthers
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-06-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -25,33 +25,33 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 7.0.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: bindata
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 2.4.10
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 2.4.10
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rubyserial
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 0.6.0
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 0.6.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: terminal-table
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 3.0.2
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: thor
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.2.1
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.2.1
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: bundler
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -105,8 +119,10 @@ files:
|
|
105
119
|
- ".DS_Store"
|
106
120
|
- ".gitignore"
|
107
121
|
- ".tool-versions"
|
122
|
+
- CHANGELOG.md
|
108
123
|
- Gemfile
|
109
124
|
- Gemfile.lock
|
125
|
+
- NetFinder_info.md
|
110
126
|
- PrologixGpibEthernetManual.pdf
|
111
127
|
- PrologixGpibUsbManual-6.0.pdf
|
112
128
|
- README.md
|
@@ -114,23 +130,27 @@ files:
|
|
114
130
|
- bin/console
|
115
131
|
- bin/setup
|
116
132
|
- exe/plx
|
133
|
+
- lan_test.rb
|
117
134
|
- lib/prologix_gpib.rb
|
118
135
|
- lib/prologix_gpib/cli.rb
|
136
|
+
- lib/prologix_gpib/commands.rb
|
137
|
+
- lib/prologix_gpib/discovery.rb
|
119
138
|
- lib/prologix_gpib/lan.rb
|
120
139
|
- lib/prologix_gpib/usb.rb
|
121
|
-
- lib/prologix_gpib/usb/commands.rb
|
122
140
|
- lib/prologix_gpib/version.rb
|
123
141
|
- package.json
|
124
142
|
- prologix_gpib.gemspec
|
143
|
+
- test_broadcast.rb
|
125
144
|
- test_script.rb
|
145
|
+
- test_server.rb
|
126
146
|
- yarn.lock
|
127
|
-
homepage: https://
|
147
|
+
homepage: https://gitlab.com/robcarruthers/prologix_gpib.git
|
128
148
|
licenses:
|
129
149
|
- MIT
|
130
150
|
metadata:
|
131
|
-
homepage_uri: https://
|
132
|
-
source_code_uri: https://
|
133
|
-
changelog_uri: https://
|
151
|
+
homepage_uri: https://gitlab.com/robcarruthers/prologix_gpib.git
|
152
|
+
source_code_uri: https://gitlab.com/robcarruthers/prologix_gpib.git
|
153
|
+
changelog_uri: https://gitlab.com/robcarruthers/prologix_gpib.git
|
134
154
|
post_install_message:
|
135
155
|
rdoc_options: []
|
136
156
|
require_paths:
|
@@ -146,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
166
|
- !ruby/object:Gem::Version
|
147
167
|
version: '0'
|
148
168
|
requirements: []
|
149
|
-
rubygems_version: 3.3.
|
169
|
+
rubygems_version: 3.3.7
|
150
170
|
signing_key:
|
151
171
|
specification_version: 4
|
152
172
|
summary: Prologix GPIB controller ruby wrapper.
|