rsmp 0.3.6 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '06464038166b8a2a0dbd21e7e53d28472117acfb704312755023792d2650943b'
4
- data.tar.gz: 149b50fb2e39d2287fd3fbd7fbc6f5520a9922d778315272250a361a6cf4d4be
3
+ metadata.gz: 05d67026eef7404afe7979c198bcfe97bd63e231400e174988ab14454f23ea09
4
+ data.tar.gz: e82717dc287f0eb2e91577cf5e02d752cdf1d1fef6bdac6f4cf3569494d8da3e
5
5
  SHA512:
6
- metadata.gz: 115228cc10a63d009bffd2a7f3f0408ad47e2dafd14883f8a25b38870ef99fe73292ddc61ac9e38a1d895d70f53c5a08928492c940d01641d87b19e466764dba
7
- data.tar.gz: 6df15fe4e9c6044cb5fab93da68202d4e0bdb32e109bc538fc4d55c232669cbbf745e7aeacee87fa75567658687683d84ee5255d98b9841f05090a918d6b6c49
6
+ metadata.gz: 0d971e86ebd1ef25ff52cc4babd23567b2b5e870cc70f7edfc18ce7925a850fd94dfa851e70c16a43d4df1ef174045999ad41c0fd5ad2ed7c074ae022282e441
7
+ data.tar.gz: 5f991d2aee4af7ac5a30b133ecfa8e1505b005fbc8e7092551f0d28bd4d26cee36fb645aa188e8a9664c0a7d5c991c78a2059445c82e1ec697ff14a8df3d2cdf
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rsmp (0.3.6)
4
+ rsmp (0.4.0)
5
5
  async (~> 1.29.1)
6
6
  async-io (~> 1.32.1)
7
7
  colorize (~> 0.8.1)
@@ -52,11 +52,14 @@ module RSMP
52
52
  raise RSMP::TimeoutError.new str
53
53
  end
54
54
 
55
+ # Get the collected message.
56
+ def message
57
+ @messages.first
58
+ end
59
+
55
60
  # Get the collected messages.
56
- # If one message was requested, return it as a plain object instead of array
57
- def result
58
- return @messages.first if @options[:num] == 1
59
- @messages.first @options[:num]
61
+ def messages
62
+ @messages
60
63
  end
61
64
 
62
65
  # Clear all query results
File without changes
@@ -0,0 +1,100 @@
1
+ module RSMP
2
+ # Base class for waiting for specific status or command responses, specified by
3
+ # a list of queries. Queries are defined as an array of hashes, e.g
4
+ # [
5
+ # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"securityCode", "v"=>"1111"},
6
+ # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"year", "v"=>"2020"},
7
+ # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"month", "v"=>/\d+/}
8
+ # ]
9
+ #
10
+ # Note that queries can contain regex patterns for values, like /\d+/ in the example above.
11
+ #
12
+ # When an input messages is received it typically contains several items, eg:
13
+ # [
14
+ # {"cCI"=>"M0104", "n"=>"month", "v"=>"9", "age"=>"recent"},
15
+ # {"cCI"=>"M0104", "n"=>"day", "v"=>"29", "age"=>"recent"},
16
+ # {"cCI"=>"M0104", "n"=>"hour", "v"=>"17", "age"=>"recent"}
17
+ # ]
18
+ #
19
+ # Each input item is matched against each of the queries.
20
+ # If a match is found, it's stored in the @results hash, with the query as the key,
21
+ # and a mesage and status as the key. In the example above, this query:
22
+ #
23
+ # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"month", "v"=>/\d+/}
24
+ #
25
+ # matches this input:
26
+ #
27
+ # {"cCI"=>"M0104", "n"=>"month", "v"=>"9", "age"=>"recent"}
28
+ #
29
+ # And the result is stored as:
30
+ # {
31
+ # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"month", "v"=>/\d+/} =>
32
+ # { <StatusResponse message>, {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"month", "v"=>"9"} }
33
+ # }
34
+
35
+ class Matcher < Collector
36
+ attr_reader :queries
37
+
38
+ # Initialize with a list a wanted statuses
39
+ def initialize proxy, want, options={}
40
+ super proxy, options.merge( ingoing: true, outgoing: false)
41
+ @queries = want.map { |wanted_item| build_query wanted_item }
42
+ end
43
+
44
+ # Build a query object.
45
+ # Sub-classes should override to use their own query classes.
46
+ def build_query want
47
+ Query.new want
48
+ end
49
+
50
+ # Get a results
51
+ def query_result want
52
+ query = @queries.find { |q| q.want == want}
53
+ raise unless query
54
+ query.item
55
+ end
56
+
57
+ # get the first message. Useful when you only collected one mesage
58
+ def message
59
+ @queries.first.message
60
+ end
61
+
62
+ # Get messages from results
63
+ def messages
64
+ @queries.map { |query| query.message }.uniq
65
+ end
66
+
67
+ # Get items from results
68
+ def items
69
+ @queries.map { |query| query.item }.uniq
70
+ end
71
+
72
+ # Are there queries left to match?
73
+ def done?
74
+ @queries.all? { |query| query.done? }
75
+ end
76
+
77
+ # Get a simplified hash of queries, with values set to either true or false,
78
+ # indicating which queries have been matched.
79
+ def status
80
+ @queries.map { |query| [query.query,query.done?] }.to_h
81
+ end
82
+
83
+ # Get a simply array of bools, showing which queries ahve been matched.
84
+ def summary
85
+ @queries.map { |query| query.done? }
86
+ end
87
+
88
+ # Check if a messages matches our criteria.
89
+ # We iterate through each of the status items or return values in the message
90
+ # Breaks as soon as where done matching all queries
91
+ def check_match message
92
+ return unless match?(message)
93
+ @queries.each do |query| # look through queries
94
+ get_items(message).each do |item| # look through status items in message
95
+ break if query.check_match(item,message) != nil #check_item_match message, query, item
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,64 @@
1
+ module RSMP
2
+ # Class for waiting for specific command responses
3
+ class CommandResponseMatcher < Matcher
4
+ def initialize proxy, want, options={}
5
+ super proxy, want, options.merge(
6
+ type: ['CommandResponse','MessageNotAck'],
7
+ title:'command response'
8
+ )
9
+ end
10
+
11
+ def build_query want
12
+ CommandQuery.new want
13
+ end
14
+
15
+ # Get items, in our case the return values
16
+ def get_items message
17
+ message.attributes['rvs']
18
+ end
19
+ end
20
+
21
+ # Base class for waiting for status updates or responses
22
+ class StatusUpdateOrResponseMatcher < Matcher
23
+ def initialize proxy, want, options={}
24
+ super proxy, want, options.merge
25
+ end
26
+
27
+ def build_query want
28
+ StatusQuery.new want
29
+ end
30
+
31
+ # Get items, in our case status values
32
+ def get_items message
33
+ message.attributes['sS']
34
+ end
35
+ end
36
+
37
+ # Class for waiting for specific status responses
38
+ class StatusResponseMatcher < StatusUpdateOrResponseMatcher
39
+ def initialize proxy, want, options={}
40
+ super proxy, want, options.merge(
41
+ type: ['StatusResponse','MessageNotAck'],
42
+ title: 'status response'
43
+ )
44
+ end
45
+ end
46
+
47
+ # Class for waiting for specific status responses
48
+ class StatusUpdateMatcher < StatusUpdateOrResponseMatcher
49
+ def initialize proxy, want, options={}
50
+ super proxy, want, options.merge(
51
+ type: ['StatusUpdate','MessageNotAck'],
52
+ title:'status update'
53
+ )
54
+ end
55
+ end
56
+
57
+ # Class for waiting for an aggregated status response
58
+ class AggregatedStatusMatcher < Collector
59
+ def initialize proxy, options={}
60
+ required = { type: ['AggregatedStatus','MessageNotAck'], title: 'aggregated status' }
61
+ super proxy, options.merge(required)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,33 @@
1
+ module RSMP
2
+ # Match a specific command responses
3
+ class CommandQuery < Query
4
+ # Match a return value item against a query
5
+ def match? item
6
+ return nil if @want['cCI'] && @want['cCI'] != item['cCI']
7
+ return nil if @want['n'] && @want['n'] != item['n']
8
+ if @want['v'].is_a? Regexp
9
+ return false if @want['v'] && item['v'] !~ @want['v']
10
+ else
11
+ return false if @want['v'] && item['v'] != @want['v']
12
+ end
13
+ true
14
+ end
15
+ end
16
+
17
+ # Match a specific status response or update
18
+ class StatusQuery < Query
19
+ # Match a status value against a query
20
+ def match? item
21
+ return nil if @want['sCI'] && @want['sCI'] != item['sCI']
22
+ return nil if @want['cO'] && @want['cO'] != item['cO']
23
+ return nil if @want['n'] && @want['n'] != item['n']
24
+ return false if @want['q'] && @want['q'] != item['q']
25
+ if @want['s'].is_a? Regexp
26
+ return false if @want['s'] && item['s'] !~ @want['s']
27
+ else
28
+ return false if @want['s'] && item['s'] != @want['s']
29
+ end
30
+ true
31
+ end
32
+ end
33
+ end
File without changes
@@ -0,0 +1,44 @@
1
+ module RSMP
2
+
3
+ # Class that matches a single status or command item
4
+ class Query
5
+ attr_reader :want, :item, :message
6
+
7
+ def initialize want
8
+ @want = want
9
+ @item = nil
10
+ @message = nil
11
+ @done = false
12
+ end
13
+
14
+ def done?
15
+ @done
16
+ end
17
+
18
+ def check_match item, message
19
+ matched = match? item
20
+ if matched == true
21
+ keep message, item
22
+ true
23
+ elsif matched == false
24
+ forget
25
+ true
26
+ end
27
+ end
28
+
29
+ def match? item
30
+ end
31
+
32
+ # Mark a query as matched and store item and message
33
+ def keep message, item
34
+ @message = message
35
+ @item = item
36
+ @done = true
37
+ end
38
+
39
+ # Mark a query as not matched
40
+ def forget
41
+ @done = false
42
+ end
43
+ end
44
+ end
@@ -13,7 +13,7 @@ module RSMP
13
13
  :rest,
14
14
  :not_connected ]
15
15
 
16
- def initialize node:, id:, grouped:
16
+ def initialize node:, id:, grouped: false
17
17
  @c_id = id
18
18
  @node = node
19
19
  @grouped = grouped
@@ -39,7 +39,7 @@ module RSMP
39
39
  end
40
40
 
41
41
  def infer_component_type component_id
42
- { klass: Component, grouped: false }
42
+ Component
43
43
  end
44
44
 
45
45
  def find_component component_id, build: true
@@ -47,10 +47,10 @@ module RSMP
47
47
  return component if component
48
48
  if build
49
49
  inferred = infer_component_type component_id
50
- component = inferred[:klass].new node: self, id: component_id
50
+ component = inferred.new node: self, id: component_id
51
51
  @components[ component_id] = component
52
52
  class_name = component.class.name.split('::').last
53
- log "Inferred component #{component_id} of type #{class_name} for site #{@site_id}", level: :info
53
+ log "Inferred #{class_name} component #{component_id}", level: :info
54
54
  component
55
55
  else
56
56
  raise UnknownComponent.new("Component #{component_id} not found") unless component
@@ -121,18 +121,6 @@ module RSMP
121
121
  end
122
122
  end
123
123
 
124
- def infer_component_type component_id
125
- if component_id =~ /TC/
126
- { klass: TrafficController, grouped: true }
127
- elsif component_id =~ /DL/
128
- { klass: DetectorLogic, goruped: false }
129
- elsif component_id =~ /SG/
130
- { klass: SignalGroup, grouped: false }
131
- else
132
- super
133
- end
134
- end
135
-
136
124
  def process_aggregated_status message
137
125
  se = message.attribute("se")
138
126
  validate_aggregated_status(message,se) == false
@@ -347,20 +335,12 @@ module RSMP
347
335
  @supervisor.notify_error e, options if @supervisor
348
336
  end
349
337
 
350
- def wait_for_alarm parent_task, options={}
351
- matching_alarm = nil
352
- message = collect(parent_task,options.merge(type: "Alarm", with_message: true, num: 1)) do |message|
353
- # TODO check components
354
- matching_alarm = nil
355
- alarm = message
338
+ def collect_alarms parent_task, options={}
339
+ collect(parent_task,options.merge(type: "Alarm")) do |alarm|
356
340
  next if options[:aCId] && options[:aCId] != alarm.attribute("aCId")
357
341
  next if options[:aSp] && options[:aSp] != alarm.attribute("aSp")
358
342
  next if options[:aS] && options[:aS] != alarm.attribute("aS")
359
- matching_alarm = alarm
360
- break
361
- end
362
- if item
363
- { message: message, status: matching_alarm }
343
+ true
364
344
  end
365
345
  end
366
346
 
data/lib/rsmp/tlc.rb CHANGED
@@ -293,7 +293,8 @@ module RSMP
293
293
  def handle_s0002 status_code, status_name=nil
294
294
  case status_name
295
295
  when 'detectorlogicstatus'
296
- RSMP::Tlc.make_status @detector_logics.map { |dl| dl.forced ? '1' : '0' }.join
296
+ RSMP::Tlc.make_status @detector_logics.each { |dl| p dl.value }
297
+ RSMP::Tlc.make_status @detector_logics.map { |dl| dl.value ? '1' : '0' }.join
297
298
  end
298
299
  end
299
300
 
@@ -625,13 +626,15 @@ module RSMP
625
626
  class SignalGroup < Component
626
627
  attr_reader :plan, :state
627
628
 
628
- def initialize node:, id:, plan:
629
+ # plan is a string, with each character representing a signal phase at a particular second in the cycle
630
+ def initialize node:, id:, plan: nil
629
631
  super node: node, id: id, grouped: false
630
632
  @plan = plan
631
633
  move 0
632
634
  end
633
635
 
634
636
  def get_state pos
637
+ return 'a' unless @plan # if no plan, use phase a, which means disabled/dark
635
638
  if pos > @plan.length
636
639
  '.'
637
640
  else
@@ -701,7 +704,7 @@ module RSMP
701
704
  end
702
705
 
703
706
  class DetectorLogic < Component
704
- attr_reader :status, :forced, :value
707
+ attr_reader :forced, :value
705
708
 
706
709
  def initialize node:, id:
707
710
  super node: node, id: id, grouped: false
@@ -781,13 +784,20 @@ module RSMP
781
784
 
782
785
  def handle_m0008 arg
783
786
  @node.verify_security_code 2, arg['securityCode']
784
- force_detector_logic arg['status']=='True', arg['value']='True'
787
+ status = arg['status']=='True'
788
+ mode = arg['mode']=='True'
789
+ force_detector_logic status, mode
785
790
  arg
786
791
  end
787
792
 
788
- def force_detector_logic status, value
789
- @forced = status
793
+ def force_detector_logic forced, value
794
+ @forced = forced
790
795
  @value = value
796
+ if @forced
797
+ log "Forcing to #{value}", level: :info
798
+ else
799
+ log "Releasing", level: :info
800
+ end
791
801
  end
792
802
 
793
803
  end
data/lib/rsmp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RSMP
2
- VERSION = "0.3.6"
2
+ VERSION = "0.4.0"
3
3
  end
data/lib/rsmp.rb CHANGED
@@ -17,10 +17,13 @@ require 'rsmp/wait'
17
17
  require 'rsmp/node'
18
18
  require 'rsmp/supervisor'
19
19
  require 'rsmp/components'
20
- require 'rsmp/notifier'
21
- require 'rsmp/listener'
22
- require 'rsmp/collector'
23
- require 'rsmp/matcher'
20
+ require 'rsmp/collect/notifier'
21
+ require 'rsmp/collect/listener'
22
+ require 'rsmp/collect/collector'
23
+ require 'rsmp/collect/query'
24
+ require 'rsmp/collect/matcher'
25
+ require 'rsmp/collect/message_queries'
26
+ require 'rsmp/collect/message_matchers'
24
27
  require 'rsmp/component'
25
28
  require 'rsmp/site'
26
29
  require 'rsmp/proxy'
data/test.rb ADDED
@@ -0,0 +1,27 @@
1
+ class A
2
+ def go &block
3
+ @block = block # block will be converted automatically to a Proc
4
+ indirect
5
+ end
6
+
7
+ def call
8
+ @block.call
9
+ end
10
+
11
+ def indirect
12
+ call
13
+ end
14
+
15
+ end
16
+
17
+ a = A.new
18
+
19
+ a.go do
20
+ break # this is ok. break causes the block to exit, and the encasing method to return - go() will exit
21
+ end
22
+
23
+ # this raises an error. the block we passed to go() will be called again, and it tries to break
24
+ # but we're not inside a method we can exit from
25
+
26
+
27
+ a.indirect
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rsmp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emil Tin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-22 00:00:00.000000000 Z
11
+ date: 2021-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -205,7 +205,13 @@ files:
205
205
  - lib/rsmp.rb
206
206
  - lib/rsmp/archive.rb
207
207
  - lib/rsmp/cli.rb
208
- - lib/rsmp/collector.rb
208
+ - lib/rsmp/collect/collector.rb
209
+ - lib/rsmp/collect/listener.rb
210
+ - lib/rsmp/collect/matcher.rb
211
+ - lib/rsmp/collect/message_matchers.rb
212
+ - lib/rsmp/collect/message_queries.rb
213
+ - lib/rsmp/collect/notifier.rb
214
+ - lib/rsmp/collect/query.rb
209
215
  - lib/rsmp/component.rb
210
216
  - lib/rsmp/components.rb
211
217
  - lib/rsmp/convert/export/json_schema.rb
@@ -213,13 +219,10 @@ files:
213
219
  - lib/rsmp/deep_merge.rb
214
220
  - lib/rsmp/error.rb
215
221
  - lib/rsmp/inspect.rb
216
- - lib/rsmp/listener.rb
217
222
  - lib/rsmp/logger.rb
218
223
  - lib/rsmp/logging.rb
219
- - lib/rsmp/matcher.rb
220
224
  - lib/rsmp/message.rb
221
225
  - lib/rsmp/node.rb
222
- - lib/rsmp/notifier.rb
223
226
  - lib/rsmp/proxy.rb
224
227
  - lib/rsmp/rsmp.rb
225
228
  - lib/rsmp/site.rb
@@ -231,6 +234,7 @@ files:
231
234
  - lib/rsmp/version.rb
232
235
  - lib/rsmp/wait.rb
233
236
  - rsmp.gemspec
237
+ - test.rb
234
238
  homepage: https://github.com/rsmp-nordic/rsmp
235
239
  licenses:
236
240
  - MIT
data/lib/rsmp/matcher.rb DELETED
@@ -1,195 +0,0 @@
1
- module RSMP
2
-
3
- # Base class for waiting for specific status or command responses, specified by
4
- # a list of queries. Queries are defined as an array of hashes, e.g
5
- # [
6
- # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"securityCode", "v"=>"1111"},
7
- # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"year", "v"=>"2020"},
8
- # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"month", "v"=>/\d+/}
9
- # ]
10
- #
11
- # Note that queries can contain regex patterns for values, like /\d+/ in the example above.
12
- #
13
- # When an input messages is received it typically contains several items, eg:
14
- # [
15
- # {"cCI"=>"M0104", "n"=>"month", "v"=>"9", "age"=>"recent"},
16
- # {"cCI"=>"M0104", "n"=>"day", "v"=>"29", "age"=>"recent"},
17
- # {"cCI"=>"M0104", "n"=>"hour", "v"=>"17", "age"=>"recent"}
18
- # ]
19
- #
20
- # Each input item is matched against each of the queries.
21
- # If a match is found, it's stored in the @results hash, with the query as the key,
22
- # and a mesage and status as the key. In the example above, this query:
23
- #
24
- # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"month", "v"=>/\d+/}
25
- #
26
- # matches this input:
27
- #
28
- # {"cCI"=>"M0104", "n"=>"month", "v"=>"9", "age"=>"recent"}
29
- #
30
- # And the result is stored as:
31
- # {
32
- # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"month", "v"=>/\d+/} =>
33
- # { <StatusResponse message>, {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"month", "v"=>"9"} }
34
- # }
35
- #
36
- #
37
- class Matcher < Collector
38
- attr_reader :queries
39
-
40
- # Initialize with a list a wanted statuses
41
- def initialize proxy, want, options={}
42
- super proxy, options.merge( ingoing: true, outgoing: false)
43
- @queries = {}
44
- want.each do |query|
45
- @queries[query] = nil
46
- end
47
- end
48
-
49
- # Get the results, as a hash of queries => results
50
- def result
51
- @queries
52
- end
53
-
54
- # Get messages from results
55
- def messages
56
- @queries.map { |query,result| result[:message] }.uniq
57
- end
58
-
59
- # Get items from results
60
- def items
61
- @queries.map { |query,result| result[:item] }.uniq
62
- end
63
-
64
- # Are there queries left to match?
65
- def done?
66
- @queries.values.all? { |result| result != nil }
67
- end
68
-
69
- # Get a simplified hash of queries, with values set to either true or false,
70
- # indicating which queries have been matched.
71
- def status
72
- @queries.transform_values{ |v| v != nil }
73
- end
74
-
75
- # Get a simply array of bools, showing which queries ahve been matched.
76
- def summary
77
- @queries.values.map { |v| v != nil }
78
- end
79
-
80
- # Mark a query as matched, by linking it to the matched item and message
81
- def keep query, message, item
82
- @queries[query] = { message:message, item:item }
83
- end
84
-
85
- # Mark a query as not matched
86
- def forget query
87
- @queries[query] = nil
88
- end
89
-
90
- # Check if a messages matches our criteria.
91
- # We iterate through each of the status items or return values in the message
92
- # Breaks as soon as where done matching all queries
93
- def check_match message
94
- return unless match?(message)
95
- @queries.keys.each do |query| # look through queries
96
- get_items(message).each do |item| # look through status items in message
97
- break if check_item_match message, query, item
98
- end
99
- end
100
- end
101
-
102
- # Check if an item matches, and mark query as matched/unmatched accordingly.
103
- def check_item_match message, query, item
104
- matched = match_item? query, item
105
- if matched == true
106
- keep query, message, item
107
- true
108
- elsif matched == false
109
- forget query
110
- true
111
- end
112
- end
113
- end
114
-
115
- # Class for waiting for specific command responses
116
- class CommandResponseMatcher < Matcher
117
- def initialize proxy, want, options={}
118
- super proxy, want, options.merge(
119
- type: ['CommandResponse','MessageNotAck'],
120
- title:'command response'
121
- )
122
- end
123
-
124
- # Get items, in our case the return values
125
- def get_items message
126
- message.attributes['rvs']
127
- end
128
-
129
- # Match a return value item against a query
130
- def match_item? query, item
131
- return nil if query['cCI'] && query['cCI'] != item['cCI']
132
- return nil if query['n'] && query['n'] != item['n']
133
- if query['v'].is_a? Regexp
134
- return false if query['v'] && item['v'] !~ query['v']
135
- else
136
- return false if query['v'] && item['v'] != query['v']
137
- end
138
- true
139
- end
140
- end
141
-
142
- # Base class for waiting for status updates or responses
143
- class StatusUpdateOrResponseMatcher < Matcher
144
- def initialize proxy, want, options={}
145
- super proxy, want, options.merge
146
- end
147
-
148
- # Get items, in our case status values
149
- def get_items message
150
- message.attributes['sS']
151
- end
152
-
153
- # Match a status value against a query
154
- def match_item? query, item
155
- return nil if query['sCI'] && query['sCI'] != item['sCI']
156
- return nil if query['cO'] && query['cO'] != item['cO']
157
- return nil if query['n'] && query['n'] != item['n']
158
- return false if query['q'] && query['q'] != item['q']
159
- if query['s'].is_a? Regexp
160
- return false if query['s'] && item['s'] !~ query['s']
161
- else
162
- return false if query['s'] && item['s'] != query['s']
163
- end
164
- true
165
- end
166
- end
167
-
168
- # Class for waiting for specific status responses
169
- class StatusResponseMatcher < StatusUpdateOrResponseMatcher
170
- def initialize proxy, want, options={}
171
- super proxy, want, options.merge(
172
- type: ['StatusResponse','MessageNotAck'],
173
- title: 'status response'
174
- )
175
- end
176
- end
177
-
178
- # Class for waiting for specific status responses
179
- class StatusUpdateMatcher < StatusUpdateOrResponseMatcher
180
- def initialize proxy, want, options={}
181
- super proxy, want, options.merge(
182
- type: ['StatusUpdate','MessageNotAck'],
183
- title:'status update'
184
- )
185
- end
186
- end
187
-
188
- # Class for waiting for an aggregated status response
189
- class AggregatedStatusMatcher < Collector
190
- def initialize proxy, options={}
191
- required = { type: ['AggregatedStatus','MessageNotAck'], title: 'aggregated status' }
192
- super proxy, options.merge(required)
193
- end
194
- end
195
- end