bcs-interrogator 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,46 @@
1
+ module NRB
2
+ class BCSInterrogator
3
+ class API
4
+
5
+ autoload :Endpoint, 'bcs_interrogator/api/endpoint'
6
+ autoload :Response, 'bcs_interrogator/api/response'
7
+ autoload :Sysname, 'bcs_interrogator/api/sysname'
8
+ autoload :Ultemp, 'bcs_interrogator/api/ultemp'
9
+
10
+ API_VERSION = 'BCS 3.7.0' # Use NRB::BCSInterrogator::API.api_version instead
11
+
12
+ def self.api_version; API_VERSION; end
13
+
14
+
15
+ attr_reader :http_service, :base_url
16
+
17
+ def api_call(args,connection_opts={})
18
+ args[:response_class] ||= NRB::BCSInterrogator::API::Response
19
+ response = @http_service.new(args,connection_opts).make_request
20
+ if response.server_version &&
21
+ response.server_version != self.class.api_version
22
+ warn "Firmware version (#{response.server_version}) does not match API version (#{self.class.api_version})."
23
+ end
24
+ response
25
+ end
26
+
27
+
28
+ def initialize(args={})
29
+ @base_url = args.delete(:base_url)
30
+ raise ArgumentError.new("Please supply a :base_url") unless @base_url
31
+ @http_service = args.delete(:http_service) || NRB::HTTPService
32
+ end
33
+
34
+
35
+ def sysname; @sysname ||= Sysname.new api: self; end
36
+ def ultemp; @ultemp ||= Ultemp.new api: self; end
37
+
38
+ private
39
+
40
+ def endpoint_base
41
+ @base_url
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,61 @@
1
+ module NRB
2
+ class BCSInterrogator
3
+ class API
4
+ class Endpoint
5
+
6
+ include Enumerable
7
+
8
+ attr_reader :response
9
+
10
+ def self.descriptions
11
+ const_defined?(:DESCRIPTIONS) ? const_get(:DESCRIPTIONS) : nil
12
+ end
13
+
14
+
15
+ def self.endpoint
16
+ const_defined?(:ENDPOINT) ? const_get(:ENDPOINT) : nil
17
+ end
18
+
19
+
20
+ def api_call(args={})
21
+ args[:verb] ||= :get
22
+ args[:url] ||= endpoint
23
+ @response = @api.api_call args
24
+ @data = @response.body
25
+ @response
26
+ end
27
+
28
+
29
+ def each(&block)
30
+ data.each(block)
31
+ end
32
+
33
+
34
+ def endpoint
35
+ @api.base_url + self.class.endpoint
36
+ end
37
+
38
+
39
+ def initialize(args={})
40
+ @api = args.delete(:api)
41
+ raise ArgumentError.new("Please supply an API object") unless @api
42
+ end
43
+
44
+
45
+ def data
46
+ return @data if @data
47
+ api_call
48
+ @data
49
+ end
50
+
51
+
52
+ def to_a; data; end
53
+
54
+ def to_h
55
+ self.class.descriptions.each_with_index { |descr,i| data[descr] = @response.body[i] }
56
+ end
57
+
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,38 @@
1
+ module NRB
2
+ class BCSInterrogator
3
+ class API
4
+ class Response
5
+
6
+ attr_reader :status, :body, :headers
7
+
8
+ def errored?
9
+ ! success?
10
+ end
11
+
12
+
13
+ def initialize(args)
14
+ @status = args[:status]
15
+ @body = process_body args[:body]
16
+ @headers = args[:headers]
17
+ end
18
+
19
+
20
+ def server_version
21
+ @headers.nil? ? "" : @headers["server"].sub(/\s+\(http:\/\/www\.embeddedcc\.com\)$/, '')
22
+ end
23
+
24
+
25
+ def success?
26
+ @status >= 200 && @status < 300
27
+ end
28
+
29
+ private
30
+
31
+ def process_body(body_string)
32
+ @body = body_string.split(',').map { |str| str.strip }
33
+ end
34
+
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,227 @@
1
+ module NRB
2
+ class BCSInterrogator
3
+ class API
4
+ class Sysname < Endpoint
5
+ # http://wiki.embeddedcc.com/index.php/Sysname.dat
6
+ # Entries in the sysname structure cannot be more than 16 characters
7
+ # Commas are not allowed
8
+
9
+ DESCRIPTIONS = [
10
+ 'Firmware Version',
11
+ 'Process 0 name',
12
+ 'Process 1 name',
13
+ 'Process 2 name',
14
+ 'Process 3 name',
15
+ 'Process 0 State 0 name',
16
+ 'Process 0 State 1 name',
17
+ 'Process 0 State 2 name',
18
+ 'Process 0 State 3 name',
19
+ 'Process 0 State 4 name',
20
+ 'Process 0 State 5 name',
21
+ 'Process 0 State 6 name',
22
+ 'Process 0 State 7 name',
23
+ 'Process 1 State 0 name',
24
+ 'Process 1 State 1 name',
25
+ 'Process 1 State 2 name',
26
+ 'Process 1 State 3 name',
27
+ 'Process 1 State 4 name',
28
+ 'Process 1 State 5 name',
29
+ 'Process 1 State 6 name',
30
+ 'Process 1 State 7 name',
31
+ 'Process 2 State 0 name',
32
+ 'Process 2 State 1 name',
33
+ 'Process 2 State 2 name',
34
+ 'Process 2 State 3 name',
35
+ 'Process 2 State 4 name',
36
+ 'Process 2 State 5 name',
37
+ 'Process 2 State 6 name',
38
+ 'Process 2 State 7 name',
39
+ 'Process 3 State 0 name',
40
+ 'Process 3 State 1 name',
41
+ 'Process 3 State 2 name',
42
+ 'Process 3 State 3 name',
43
+ 'Process 3 State 4 name',
44
+ 'Process 3 State 5 name',
45
+ 'Process 3 State 6 name',
46
+ 'Process 3 State 7 name',
47
+ 'Output 0 name',
48
+ 'Output 1 name',
49
+ 'Output 2 name',
50
+ 'Output 3 name',
51
+ 'Output 4 name',
52
+ 'Output 5 name',
53
+ 'Din 0 name',
54
+ 'Din 1 name',
55
+ 'Din 2 name',
56
+ 'Din 3 name',
57
+ 'Process 0 Win 0 name',
58
+ 'Process 0 Win 1 name',
59
+ 'Process 0 Win 2 name',
60
+ 'Process 0 Win 3 name',
61
+ 'Process 1 Win 0 name',
62
+ 'Process 1 Win 1 name',
63
+ 'Process 1 Win 2 name',
64
+ 'Process 1 Win 3 name',
65
+ 'Process 2 Win 0 name',
66
+ 'Process 2 Win 1 name',
67
+ 'Process 2 Win 2 name',
68
+ 'Process 2 Win 3 name',
69
+ 'Process 3 Win 0 name',
70
+ 'Process 3 Win 1 name',
71
+ 'Process 3 Win 2 name',
72
+ 'Process 3 Win 3 name',
73
+ 'Temp Probe 0 name',
74
+ 'Temp Probe 1 name',
75
+ 'Temp Probe 2 name',
76
+ 'Temp Probe 3 name',
77
+ 'Process 0 Timer 0 name',
78
+ 'Process 0 Timer 1 name',
79
+ 'Process 0 Timer 2 name',
80
+ 'Process 0 Timer 3 name',
81
+ 'Process 1 Timer 0 name',
82
+ 'Process 1 Timer 1 name',
83
+ 'Process 1 Timer 2 name',
84
+ 'Process 1 Timer 3 name',
85
+ 'Process 2 Timer 0 name',
86
+ 'Process 2 Timer 1 name',
87
+ 'Process 2 Timer 2 name',
88
+ 'Process 2 Timer 3 name',
89
+ 'Process 3 Timer 0 name',
90
+ 'Process 3 Timer 1 name',
91
+ 'Process 3 Timer 2 name',
92
+ 'Process 3 Timer 3 name',
93
+ 'Reserved',
94
+ 'Reserved',
95
+ 'Temp Probe 4 name',
96
+ 'Temp Probe 5 name',
97
+ 'Temp Probe 6 name',
98
+ 'Temp Probe 7 name',
99
+ 'Din 4 name',
100
+ 'Din 5 name',
101
+ 'Din 6 name',
102
+ 'Din 7 name',
103
+ 'Output 6 name',
104
+ 'Output 7 name',
105
+ 'Output 8 name',
106
+ 'Output 9 name',
107
+ 'Output 10 name',
108
+ 'Output 11 name',
109
+ 'Output 12 name',
110
+ 'Output 13 name',
111
+ 'Output 14 name',
112
+ 'Output 15 name',
113
+ 'Output 16 name',
114
+ 'Output 17 name',
115
+ 'Process 4 name',
116
+ 'Process 5 name',
117
+ 'Process 6 name',
118
+ 'Process 7 name',
119
+ 'Process 4 State 0 name',
120
+ 'Process 4 State 1 name',
121
+ 'Process 4 State 2 name',
122
+ 'Process 4 State 3 name',
123
+ 'Process 4 State 4 name',
124
+ 'Process 4 State 5 name',
125
+ 'Process 4 State 6 name',
126
+ 'Process 4 State 7 name',
127
+ 'Process 5 State 0 name',
128
+ 'Process 5 State 1 name',
129
+ 'Process 5 State 2 name',
130
+ 'Process 5 State 3 name',
131
+ 'Process 5 State 4 name',
132
+ 'Process 5 State 5 name',
133
+ 'Process 5 State 6 name',
134
+ 'Process 5 State 7 name',
135
+ 'Process 6 State 0 name',
136
+ 'Process 6 State 1 name',
137
+ 'Process 6 State 2 name',
138
+ 'Process 6 State 3 name',
139
+ 'Process 6 State 4 name',
140
+ 'Process 6 State 5 name',
141
+ 'Process 6 State 6 name',
142
+ 'Process 6 State 7 name',
143
+ 'Process 7 State 0 name',
144
+ 'Process 7 State 1 name',
145
+ 'Process 7 State 2 name',
146
+ 'Process 7 State 3 name',
147
+ 'Process 7 State 4 name',
148
+ 'Process 7 State 5 name',
149
+ 'Process 7 State 6 name',
150
+ 'Process 7 State 7 name',
151
+ 'Process 4 Win 0 name',
152
+ 'Process 4 Win 1 name',
153
+ 'Process 4 Win 2 name',
154
+ 'Process 4 Win 3 name',
155
+ 'Process 5 Win 0 name',
156
+ 'Process 5 Win 1 name',
157
+ 'Process 5 Win 2 name',
158
+ 'Process 5 Win 3 name',
159
+ 'Process 6 Win 0 name',
160
+ 'Process 6 Win 1 name',
161
+ 'Process 6 Win 2 name',
162
+ 'Process 6 Win 3 name',
163
+ 'Process 7 Win 0 name',
164
+ 'Process 7 Win 1 name',
165
+ 'Process 7 Win 2 name',
166
+ 'Process 7 Win 3 name',
167
+ '4 Timer 0 name',
168
+ '4 Timer 1 name',
169
+ '4 Timer 2 name',
170
+ '4 Timer 3 name',
171
+ '5 Timer 0 name',
172
+ '5 Timer 1 name',
173
+ '5 Timer 2 name',
174
+ '5 Timer 3 name',
175
+ '6 Timer 0 name',
176
+ '6 Timer 1 name',
177
+ '6 Timer 2 name',
178
+ '6 Timer 3 name',
179
+ '7 Timer 0 name',
180
+ '7 Timer 1 name',
181
+ '7 Timer 2 name',
182
+ '7 Timer 3 name',
183
+ 'Reserved',
184
+ 'Reserved',
185
+ 'Reserved',
186
+ 'Reserved',
187
+ 'Reserved',
188
+ 'Reserved',
189
+ 'Reserved',
190
+ 'Reserved',
191
+ 'Reserved',
192
+ 'Reserved',
193
+ 'Reserved',
194
+ 'Reserved',
195
+ 'Reserved',
196
+ 'Reserved',
197
+ 'Reserved',
198
+ 'Reserved',
199
+ 'Reserved',
200
+ 'Reserved',
201
+ 'Reserved',
202
+ 'Reserved',
203
+ 'Reserved',
204
+ 'Reserved',
205
+ 'Reserved',
206
+ 'Reserved',
207
+ 'Reserved',
208
+ 'Reserved',
209
+ 'Reserved',
210
+ 'Reserved',
211
+ 'Reserved',
212
+ 'Reserved',
213
+ 'Reserved',
214
+ 'Reserved',
215
+ 'Reserved'
216
+ ]
217
+
218
+ ENDPOINT = '/sysname.dat'
219
+
220
+ def input_names; data[43..46] + data[89..92]; end
221
+ def output_names; data[37..42] + data[93..104]; end
222
+ def temp_probe_names; data[63..66] + data[85..88]; end
223
+
224
+ end
225
+ end
226
+ end
227
+ end
@@ -0,0 +1,110 @@
1
+ module NRB
2
+ class BCSInterrogator
3
+ class API
4
+ class Ultemp < Endpoint
5
+ # http://wiki.embeddedcc.com/index.php/Ultemp.dat
6
+ # All entries in the ultemp structure have to be in the range
7
+ # 0 <= ultemp < 2^32
8
+ # Commas are not allowed
9
+
10
+ DESCRIPTIONS = [
11
+ 'Running Process (proc_en) (7:0)',
12
+ 'Discrete Outputs (17:0)',
13
+ 'Discrete Inputs (8:0)',
14
+ 'Temp0 * 10',
15
+ 'Temp1 * 10',
16
+ 'Temp2 * 10',
17
+ 'Temp3 * 10',
18
+ 'Temp4 * 10',
19
+ 'Temp5 * 10',
20
+ 'Temp6 * 10',
21
+ 'Temp7 * 10',
22
+ 'Temp0 Setpoint * 10',
23
+ 'Temp1 Setpoint * 10',
24
+ 'Temp2 Setpoint * 10',
25
+ 'Temp3 Setpoint * 10',
26
+ 'Temp4 Setpoint * 10',
27
+ 'Temp5 Setpoint * 10',
28
+ 'Temp6 Setpoint * 10',
29
+ 'Temp7 Setpoint * 10',
30
+ 'Current State - P0(31:24) P1(23:16) P2(15:8) P3(7:0)',
31
+ 'Current State - P4(31:24) P5(23:16) P6(15:8) P7(7:0)',
32
+ 'Process Timer 0 [P0:P7][T0:T3]',
33
+ 'Process Timer 0 [P0:P7][T0:T3]',
34
+ 'Process Timer 0 [P0:P7][T0:T3]',
35
+ 'Process Timer 0 [P0:P7][T0:T3]',
36
+ 'Process Timer 0 [P0:P7][T0:T3]',
37
+ 'Process Timer 0 [P0:P7][T0:T3]',
38
+ 'Process Timer 0 [P0:P7][T0:T3]',
39
+ 'Process Timer 0 [P0:P7][T0:T3]',
40
+ 'Process Timer 0 [P0:P7][T0:T3]',
41
+ 'Process Timer 0 [P0:P7][T0:T3]',
42
+ 'Process Timer 0 [P0:P7][T0:T3]',
43
+ 'Process Timer 0 [P0:P7][T0:T3]',
44
+ 'Process Timer 0 [P0:P7][T0:T3]',
45
+ 'Process Timer 0 [P0:P7][T0:T3]',
46
+ 'Process Timer 0 [P0:P7][T0:T3]',
47
+ 'Process Timer 0 [P0:P7][T0:T3]',
48
+ 'Process Timer 0 [P0:P7][T0:T3]',
49
+ 'Process Timer 0 [P0:P7][T0:T3]',
50
+ 'Process Timer 0 [P0:P7][T0:T3]',
51
+ 'Process Timer 0 [P0:P7][T0:T3]',
52
+ 'Process Timer 0 [P0:P7][T0:T3]',
53
+ 'Process Timer 0 [P0:P7][T0:T3]',
54
+ 'Process Timer 0 [P0:P7][T0:T3]',
55
+ 'Process Timer 0 [P0:P7][T0:T3]',
56
+ 'Process Timer 0 [P0:P7][T0:T3]',
57
+ 'Process Timer 0 [P0:P7][T0:T3]',
58
+ 'Process Timer 0 [P0:P7][T0:T3]',
59
+ 'Process Timer 0 [P0:P7][T0:T3]',
60
+ 'Process Timer 0 [P0:P7][T0:T3]',
61
+ 'Process Timer 0 [P0:P7][T0:T3]',
62
+ 'Process Timer 0 [P0:P7][T0:T3]',
63
+ 'Process Timer 0 [P0:P7][T0:T3]',
64
+ 'Internal Registers (15:0)',
65
+ 'Miscellaneous
66
+ Bit 8: Alarm
67
+ Bits 7:0 : Process[7:0] Pause'
68
+ ]
69
+
70
+ ENDPOINT = '/ultemp.dat'
71
+
72
+ def inputs
73
+ bitmasked_data 0..7, 2
74
+ end
75
+
76
+
77
+ def outputs
78
+ bitmasked_data 0..17, 1
79
+ end
80
+
81
+
82
+ def temps
83
+ data_by_ten(3..10)
84
+ end
85
+
86
+
87
+ def setpoints
88
+ data_by_ten(11..18)
89
+ end
90
+
91
+ private
92
+
93
+ def collect_data(range, &block)
94
+ data[range].collect &block
95
+ end
96
+
97
+
98
+ def bitmasked_data(range, data_pos)
99
+ collect_data(range) { |i| data[data_pos].to_i & (2**i) > 0 }
100
+ end
101
+
102
+
103
+ def data_by_ten(range)
104
+ collect_data(range) { |t| t.to_f / 10.0 }
105
+ end
106
+
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,43 @@
1
+ module NRB
2
+ class BCSInterrogator
3
+ class Entity
4
+
5
+ def initialize(args={})
6
+ @bcs = args[:bcs]
7
+ raise ArgumentError("Please provide a BCS object") if @bcs.nil?
8
+ if args[:positions].is_a?(Fixnum)
9
+ @positions = { output_names: args[:positions],
10
+ outputs: args[:positions],
11
+ temp_probe_names: args[:positions],
12
+ temps: args[:positions],
13
+ setpoints: args[:positions]
14
+ }
15
+ else
16
+ @positions = args[:positions]
17
+ end
18
+ end
19
+
20
+
21
+ def input_name; data :input_names; end
22
+ def last_update; @bcs.last_update; end
23
+ def name; data :temp_probe_names; end
24
+ def output_name; data :output_names; end
25
+ def output; data :outputs; end
26
+ def setpoint; data :setpoints; end
27
+ def temp; data :temps; end
28
+ def update; @bcs.update; end
29
+
30
+ private
31
+
32
+ def data(lookup)
33
+ update if last_update.nil?
34
+ if @bcs.respond_to?(lookup)
35
+ @bcs.send(lookup)[@positions[lookup]]
36
+ else
37
+ raise ArgumentError.new "No data for #{lookup}"
38
+ end
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -1,6 +1,6 @@
1
1
  module NRB
2
2
  class BCSInterrogator
3
- VERSION = '0.0.1'
3
+ VERSION = '0.0.2'
4
4
  def self.version; VERSION; end
5
5
  end
6
6
  end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe NRB::BCSInterrogator::API do
4
+
5
+ context 'class methods' do
6
+ it 'has a version' do
7
+ NRB::BCSInterrogator::API.should respond_to :api_version
8
+ end
9
+ end
10
+
11
+ context 'defaults' do
12
+
13
+ let(:api) { NRB::BCSInterrogator::API.new args }
14
+ let(:args) { { base_url: base_url } }
15
+ let(:base_url) { '' }
16
+ let(:http_service) { NRB::HTTPService }
17
+
18
+ it 'has a default http_service' do
19
+ api.http_service.should == http_service
20
+ end
21
+
22
+ it 'has an base_url reader' do
23
+ api.base_url.should eq base_url
24
+ end
25
+
26
+ end
27
+
28
+ it 'blows up without a base_url' do
29
+ expect { NRB::BCSInterrogator::API.new }.to raise_error(ArgumentError)
30
+ end
31
+
32
+
33
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe NRB::BCSInterrogator do
4
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bcs-interrogator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -117,8 +117,16 @@ files:
117
117
  - LICENSE
118
118
  - README.md
119
119
  - lib/bcs_interrogator.rb
120
+ - lib/bcs_interrogator/api.rb
121
+ - lib/bcs_interrogator/api/endpoint.rb
122
+ - lib/bcs_interrogator/api/response.rb
123
+ - lib/bcs_interrogator/api/sysname.rb
124
+ - lib/bcs_interrogator/api/ultemp.rb
125
+ - lib/bcs_interrogator/entity.rb
120
126
  - lib/bcs_interrogator/version.rb
121
127
  - spec/spec_helper.rb
128
+ - spec/cases/api_spec.rb
129
+ - spec/cases/bcs_interrogator_spec.rb
122
130
  homepage: https://github.com/NewRepublicBrewing/BCS-Interrogator
123
131
  licenses: []
124
132
  post_install_message:
@@ -145,4 +153,6 @@ specification_version: 3
145
153
  summary: A gem to intorrogate EEC Brewery Control Systems
146
154
  test_files:
147
155
  - spec/spec_helper.rb
156
+ - spec/cases/api_spec.rb
157
+ - spec/cases/bcs_interrogator_spec.rb
148
158
  has_rdoc: