rsmp 0.51.4 → 0.53.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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/Gemfile.lock +1 -1
  4. data/documentation/collecting_message.md +112 -0
  5. data/documentation/configuration.md +53 -2
  6. data/lib/rsmp/collect/collector.rb +6 -0
  7. data/lib/rsmp/collect/queue.rb +4 -0
  8. data/lib/rsmp/collect/status_collector.rb +2 -2
  9. data/lib/rsmp/component/component_base.rb +10 -1
  10. data/lib/rsmp/component/component_proxy.rb +1 -1
  11. data/lib/rsmp/component/components.rb +24 -2
  12. data/lib/rsmp/node/site/site.rb +21 -7
  13. data/lib/rsmp/node/site/status.rb +39 -0
  14. data/lib/rsmp/node/supervisor/modules/connection.rb +20 -4
  15. data/lib/rsmp/node/supervisor/modules/sites.rb +2 -0
  16. data/lib/rsmp/options/schemas/required_settings.json +20 -12
  17. data/lib/rsmp/options/schemas/supervisor_site.json +1 -1
  18. data/lib/rsmp/options/site_options.rb +1 -0
  19. data/lib/rsmp/proxy/modules/acknowledgements.rb +2 -0
  20. data/lib/rsmp/proxy/modules/receive.rb +32 -2
  21. data/lib/rsmp/proxy/modules/send.rb +23 -3
  22. data/lib/rsmp/proxy/modules/version_validation.rb +76 -0
  23. data/lib/rsmp/proxy/modules/versions.rb +21 -22
  24. data/lib/rsmp/proxy/proxy.rb +29 -5
  25. data/lib/rsmp/proxy/site/modules/aggregated_status.rb +22 -2
  26. data/lib/rsmp/proxy/site/modules/commands.rb +1 -1
  27. data/lib/rsmp/proxy/site/site_proxy.rb +22 -13
  28. data/lib/rsmp/proxy/site/sxl_selection.rb +13 -22
  29. data/lib/rsmp/proxy/supervisor/modules/aggregated_status.rb +56 -1
  30. data/lib/rsmp/proxy/supervisor/modules/alarms.rb +11 -4
  31. data/lib/rsmp/proxy/supervisor/modules/commands.rb +4 -3
  32. data/lib/rsmp/proxy/supervisor/modules/message_buffer.rb +6 -1
  33. data/lib/rsmp/proxy/supervisor/modules/status.rb +46 -1
  34. data/lib/rsmp/proxy/supervisor/modules/status_updates.rb +17 -1
  35. data/lib/rsmp/proxy/supervisor/supervisor_proxy.rb +12 -16
  36. data/lib/rsmp/schema/validation.rb +2 -1
  37. data/lib/rsmp/version.rb +1 -1
  38. data/schemas/core/3.1.2/definitions.json +5 -0
  39. data/schemas/core/3.1.2/status_subscribe.json +1 -1
  40. data/schemas/core/3.1.3/definitions.json +5 -0
  41. data/schemas/core/3.1.3/status_subscribe.json +1 -1
  42. data/schemas/core/3.1.4/definitions.json +5 -0
  43. data/schemas/core/3.1.4/status_subscribe.json +1 -1
  44. data/schemas/core/3.1.5/definitions.json +5 -0
  45. data/schemas/core/3.1.5/status_subscribe.json +1 -1
  46. data/schemas/core/3.2.0/definitions.json +5 -0
  47. data/schemas/core/3.2.0/status_subscribe.json +1 -1
  48. data/schemas/core/3.2.1/definitions.json +5 -0
  49. data/schemas/core/3.2.1/status_subscribe.json +1 -1
  50. data/schemas/core/3.2.2/definitions.json +5 -0
  51. data/schemas/core/3.2.2/status_subscribe.json +1 -1
  52. data/schemas/core/3.3.0/aggregated_status.json +17 -11
  53. data/schemas/core/3.3.0/aggregated_status_request.json +4 -4
  54. data/schemas/core/3.3.0/component_list.json +1 -1
  55. data/schemas/core/3.3.0/definitions.json +23 -2
  56. data/schemas/core/3.3.0/status_subscribe.json +14 -4
  57. data/schemas/core/3.3.0/version.json +46 -26
  58. data/schemas/tlc/1.0.10/defs/definitions.json +5 -0
  59. data/schemas/tlc/1.0.13/defs/definitions.json +5 -0
  60. data/schemas/tlc/1.0.14/defs/definitions.json +5 -0
  61. data/schemas/tlc/1.0.15/defs/definitions.json +5 -0
  62. data/schemas/tlc/1.0.7/defs/definitions.json +5 -0
  63. data/schemas/tlc/1.0.8/defs/definitions.json +5 -0
  64. data/schemas/tlc/1.0.9/defs/definitions.json +5 -0
  65. data/schemas/tlc/1.1.0/defs/definitions.json +5 -0
  66. data/schemas/tlc/1.2.0/defs/definitions.json +5 -0
  67. data/schemas/tlc/1.2.1/defs/definitions.json +5 -0
  68. data/schemas/tlc/1.3.0/defs/definitions.json +7 -0
  69. metadata +3 -1
@@ -60,7 +60,8 @@ module RSMP
60
60
  def add_status_subscription(component_id, subs, update_list, arg, now)
61
61
  sci = arg['sCI']
62
62
  name = arg['n']
63
- subcription = { interval: arg['uRt'].to_i, last_sent_at: now }
63
+ subcription = { interval: arg['uRt'].to_f, last_sent_at: now }
64
+ subcription[:on_change] = arg['sOc'] if core_3_3_0_or_newer?
64
65
  subs[sci] ||= {}
65
66
  subs[sci][name] = subcription
66
67
  update_list[component_id][sci] ||= []
@@ -70,6 +71,8 @@ module RSMP
70
71
  def process_status_subcribe(message)
71
72
  log "Received #{message.type}", message: message, level: :log
72
73
 
74
+ return process_core_3_3_subscription(message) if core_3_3_0_or_newer?
75
+
73
76
  update_list = {}
74
77
  component_id = message.attributes['cId']
75
78
  @status_subscriptions[component_id] ||= {}
@@ -84,6 +87,48 @@ module RSMP
84
87
  send_status_updates update_list
85
88
  end
86
89
 
90
+ def process_core_3_3_subscription(message)
91
+ validate_core_3_3_subscription!(message)
92
+ id = message.attributes['cId']
93
+ args = message.attributes['sS']
94
+ component = @site.find_component(id, build: false)
95
+ values = component ? fetch_status_values(component, args) : build_undefined_statuses(args)
96
+ subs = (@status_subscriptions[id] ||= {})
97
+ update_core_3_3_subscriptions(id, args, values, subs)
98
+ @status_subscriptions.delete(id) if subs.empty?
99
+ acknowledge message
100
+ update = core_3_3_subscription_update(id, values)
101
+ send_generated_message update
102
+ store_last_sent_status update
103
+ end
104
+
105
+ def core_3_3_subscription_update(id, values)
106
+ values = values.map { |value| value.except('uRt', 'sOc') }
107
+ StatusUpdate.new('cId' => id, 'sTs' => clock.to_s, 'sS' => values)
108
+ end
109
+
110
+ def update_core_3_3_subscriptions(id, args, values, subs)
111
+ updates = { id => {} }
112
+ values.each_with_index do |value, index|
113
+ arg = args[index]
114
+ if %w[unknown undefined].include?(value['q'])
115
+ remove_status_subscription(subs, arg)
116
+ else
117
+ add_status_subscription(id, subs, updates, arg, Time.now)
118
+ end
119
+ end
120
+ end
121
+
122
+ def validate_core_3_3_subscription!(message)
123
+ invalid = message.attributes['sS'].any? do |arg|
124
+ interval = arg['uRt'].to_f
125
+ interval.negative? || (interval.zero? && !arg['sOc'])
126
+ end
127
+ return unless invalid
128
+
129
+ raise MessageRejected, 'Subscription interval must be nonnegative and enable interval or sendOnChange'
130
+ end
131
+
87
132
  def get_status_subscribe_interval(component_id, sci, name)
88
133
  @status_subscriptions.dig component_id, sci, name
89
134
  end
@@ -22,7 +22,8 @@ module RSMP
22
22
  end
23
23
 
24
24
  def check_on_change_update(subscription, component, code, name)
25
- return [nil, false] unless subscription[:interval].zero?
25
+ enabled = core_3_3_0_or_newer? ? subscription[:on_change] : subscription[:interval].zero?
26
+ return [nil, false] unless enabled
26
27
 
27
28
  current = current_status_value(component, code, name)
28
29
  last_sent = fetch_last_sent_status component.c_id, code, name
@@ -34,6 +35,10 @@ module RSMP
34
35
 
35
36
  value, quality = *(component.get_status code, name)
36
37
  rsmpify_value(value, quality)
38
+ rescue UnknownStatus
39
+ raise unless core_3_3_0_or_newer?
40
+
41
+ nil
37
42
  end
38
43
 
39
44
  def encode_status_value(code, name, value)
@@ -59,6 +64,8 @@ module RSMP
59
64
  end
60
65
 
61
66
  def status_update_timer(now)
67
+ return if core_3_3_0_or_newer? && connected? && !ready?
68
+
62
69
  send_status_updates status_updates_due(now)
63
70
  end
64
71
 
@@ -71,8 +78,15 @@ module RSMP
71
78
  end
72
79
 
73
80
  def collect_component_status_updates(update_list, component_id, by_code, now)
81
+ if core_3_3_0_or_newer? && !@site.components.key?(component_id)
82
+ @status_subscriptions.delete(component_id)
83
+ return
84
+ end
74
85
  component = @site.find_component component_id
75
86
  by_code.each_pair do |code, by_name|
87
+ probe = StatusUpdate.new('sS' => [{ 'sCI' => code }])
88
+ next if core_3_3_0_or_newer? && !sxl_message_allowed?(probe)
89
+
76
90
  by_name.each_pair do |name, subscription|
77
91
  current, should_send = check_status_subscription(subscription, component, code, name, now)
78
92
  next unless should_send
@@ -90,6 +104,8 @@ module RSMP
90
104
  end
91
105
 
92
106
  def precomputed_status_value(subscription, current)
107
+ return if core_3_3_0_or_newer? # Fetch value and quality together; do not replace quality with recent.
108
+
93
109
  PrecomputedStatusValue.new(current) if subscription[:interval].zero?
94
110
  end
95
111
 
@@ -127,11 +127,14 @@ module RSMP
127
127
  level: :info
128
128
  self.state = :ready
129
129
  start_watchdog
130
- if @site_settings['send_after_connect']
131
- send_all_aggregated_status
132
- send_active_alarms if receive_alarms?
130
+ @initial_alarm_events = [] if core_3_3_0_or_newer?
131
+ if core_3_3_0_or_newer? || @site_settings['send_after_connect']
132
+ send_all_aggregated_status unless core_3_3_0_or_newer?
133
+ send_active_alarms if use_alarms?
133
134
  end
134
135
  flush_message_buffer
136
+ @initial_alarm_events = nil
137
+ synchronize_site_state if core_3_3_0_or_newer?
135
138
  super
136
139
  end
137
140
 
@@ -175,7 +178,7 @@ module RSMP
175
178
  def acknowledged_first_ingoing(message)
176
179
  case message.type
177
180
  when 'Watchdog'
178
- if core_3_3?
181
+ if core_3_3_0_or_newer?
179
182
  send_component_list
180
183
  else
181
184
  handshake_complete
@@ -205,16 +208,17 @@ module RSMP
205
208
  return extraneous_version message if @version_determined
206
209
 
207
210
  check_core_version message
211
+ validate_version! message, step: 'Response'
208
212
  check_sxl_version message
209
213
  @site_id = Supervisor.build_id_from_ip_port @ip, @port
210
214
  version_accepted message
211
215
  end
212
216
 
213
217
  def check_sxl_version(message)
214
- if core_3_3?
215
- @rejected_sxls, @accepted_sxls = message.sxls.partition { |item| item['rejected'] }
216
- validate_sxl_response! @accepted_sxls
217
- @receive_alarms = message.attributes.fetch('receiveAlarms', true)
218
+ if core_3_3_0_or_newer?
219
+ validate_sxl_response! message.sxls
220
+ @accepted_sxls, @rejected_sxls = message.sxls.partition { |item| item['status'] == 'ok' }
221
+ @use_alarms = message.attributes.fetch('useAlarms', true)
218
222
  else
219
223
  primary = primary_configured_sxl
220
224
  raise HandshakeError, 'Legacy Version response received, but no SXL is configured' unless primary
@@ -225,14 +229,6 @@ module RSMP
225
229
  build_sxl_interfaces
226
230
  end
227
231
 
228
- def send_component_list
229
- send_generated_message ComponentList.new('components' => @site.component_list)
230
- end
231
-
232
- def component_list_acknowledged
233
- handshake_complete
234
- end
235
-
236
232
  def main
237
233
  @site.main
238
234
  end
@@ -24,7 +24,8 @@ module RSMP
24
24
 
25
25
  def self.validate_sxls(message, schemas, options)
26
26
  sxl_schemas = schemas.reject { |type, _version| type.to_sym == :core }
27
- return [] if sxl_schemas.empty? || core_message_type?(message)
27
+ return [] if core_message_type?(message)
28
+ return [] if sxl_schemas.empty? && schema_core_version(schemas) != '3.3.0'
28
29
 
29
30
  resolved = resolve_sxl(message, schemas: schemas, **options)
30
31
  return validate_resolved_sxl(message, resolved, schemas, options) if resolved
data/lib/rsmp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RSMP
2
- VERSION = '0.51.4'.freeze
2
+ VERSION = '0.53.0'.freeze
3
3
  end
@@ -17,6 +17,11 @@
17
17
  "$comment" : "Example: 123 or -123",
18
18
  "pattern": "^\\-?[0-9]+$"
19
19
  },
20
+ "number_as_string": {
21
+ "description" : "Integer or decimal number as string",
22
+ "type": "string",
23
+ "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$"
24
+ },
20
25
  "version": {
21
26
  "description" : "Version",
22
27
  "type": "string",
@@ -14,7 +14,7 @@
14
14
  "sCI" : { "$ref": "definitions.json#/status_code" },
15
15
  "n" : { "description" : "Unique reference of the value", "type" : "string" },
16
16
  "uRt" : {
17
- "$ref": "definitions.json#/integer",
17
+ "$ref": "definitions.json#/number_as_string",
18
18
  "description" : "Update interval in seconds, 0 means send when value changes"
19
19
  }
20
20
  },
@@ -17,6 +17,11 @@
17
17
  "$comment" : "Example: 123 or -123",
18
18
  "pattern": "^\\-?[0-9]+$"
19
19
  },
20
+ "number_as_string": {
21
+ "description" : "Integer or decimal number as string",
22
+ "type": "string",
23
+ "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$"
24
+ },
20
25
  "version": {
21
26
  "description" : "Version",
22
27
  "type": "string",
@@ -14,7 +14,7 @@
14
14
  "sCI" : { "$ref": "definitions.json#/status_code" },
15
15
  "n" : { "description" : "Unique reference of the value", "type" : "string" },
16
16
  "uRt" : {
17
- "$ref": "definitions.json#/integer",
17
+ "$ref": "definitions.json#/number_as_string",
18
18
  "description" : "Update interval in seconds, 0 means send when value changes"
19
19
  }
20
20
  },
@@ -17,6 +17,11 @@
17
17
  "$comment" : "Example: 123 or -123",
18
18
  "pattern": "^\\-?[0-9]+$"
19
19
  },
20
+ "number_as_string": {
21
+ "description" : "Integer or decimal number as string",
22
+ "type": "string",
23
+ "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$"
24
+ },
20
25
  "version": {
21
26
  "description" : "Version",
22
27
  "type": "string",
@@ -14,7 +14,7 @@
14
14
  "sCI" : { "$ref": "definitions.json#/status_code" },
15
15
  "n" : { "description" : "Unique reference of the value", "type" : "string" },
16
16
  "uRt" : {
17
- "$ref": "definitions.json#/integer",
17
+ "$ref": "definitions.json#/number_as_string",
18
18
  "description" : "Update interval in seconds, 0 means send when value changes"
19
19
  }
20
20
  },
@@ -17,6 +17,11 @@
17
17
  "$comment" : "Example: 123 or -123",
18
18
  "pattern": "^\\-?[0-9]+$"
19
19
  },
20
+ "number_as_string": {
21
+ "description" : "Integer or decimal number as string",
22
+ "type": "string",
23
+ "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$"
24
+ },
20
25
  "version": {
21
26
  "description" : "Version",
22
27
  "type": "string",
@@ -14,7 +14,7 @@
14
14
  "sCI" : { "$ref": "definitions.json#/status_code" },
15
15
  "n" : { "description" : "Unique reference of the value", "type" : "string" },
16
16
  "uRt" : {
17
- "$ref": "definitions.json#/integer",
17
+ "$ref": "definitions.json#/number_as_string",
18
18
  "description" : "Update interval in seconds, 0 means send when value changes"
19
19
  },
20
20
  "sOc" : {
@@ -17,6 +17,11 @@
17
17
  "$comment" : "Example: 123 or -123",
18
18
  "pattern": "^\\-?[0-9]+$"
19
19
  },
20
+ "number_as_string": {
21
+ "description" : "Integer or decimal number as string",
22
+ "type": "string",
23
+ "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$"
24
+ },
20
25
  "version": {
21
26
  "description" : "Version",
22
27
  "type": "string",
@@ -14,7 +14,7 @@
14
14
  "sCI" : { "$ref": "definitions.json#/status_code" },
15
15
  "n" : { "description" : "Unique reference of the value", "type" : "string" },
16
16
  "uRt" : {
17
- "$ref": "definitions.json#/integer",
17
+ "$ref": "definitions.json#/number_as_string",
18
18
  "description" : "Update interval in seconds, 0 means send when value changes"
19
19
  },
20
20
  "sOc" : {
@@ -17,6 +17,11 @@
17
17
  "$comment" : "Example: 123 or -123",
18
18
  "pattern": "^\\-?[0-9]+$"
19
19
  },
20
+ "number_as_string": {
21
+ "description" : "Integer or decimal number as string",
22
+ "type": "string",
23
+ "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$"
24
+ },
20
25
  "version": {
21
26
  "description" : "Version",
22
27
  "type": "string",
@@ -14,7 +14,7 @@
14
14
  "sCI" : { "$ref": "definitions.json#/status_code" },
15
15
  "n" : { "description" : "Unique reference of the value", "type" : "string" },
16
16
  "uRt" : {
17
- "$ref": "definitions.json#/integer",
17
+ "$ref": "definitions.json#/number_as_string",
18
18
  "description" : "Update interval in seconds, 0 means send when value changes"
19
19
  },
20
20
  "sOc" : {
@@ -17,6 +17,11 @@
17
17
  "$comment" : "Example: 123 or -123",
18
18
  "pattern": "^\\-?[0-9]+$"
19
19
  },
20
+ "number_as_string": {
21
+ "description" : "Integer or decimal number as string",
22
+ "type": "string",
23
+ "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$"
24
+ },
20
25
  "version": {
21
26
  "description" : "Version",
22
27
  "type": "string",
@@ -14,7 +14,7 @@
14
14
  "sCI" : { "$ref": "definitions.json#/status_code" },
15
15
  "n" : { "description" : "Unique reference of the value", "type" : "string" },
16
16
  "uRt" : {
17
- "$ref": "definitions.json#/integer",
17
+ "$ref": "definitions.json#/number_as_string",
18
18
  "description" : "Update interval in seconds, 0 means send when value changes"
19
19
  },
20
20
  "sOc" : {
@@ -1,25 +1,31 @@
1
1
  {
2
2
  "title" : "Aggregated Status",
3
- "description" : "Aggregated status message",
3
+ "description" : "Aggregated status of the site",
4
4
  "properties" : {
5
5
  "mId" : { "$ref": "definitions.json#/message_id" },
6
6
  "aSTS" : { "$ref": "definitions.json#/timestamp" },
7
- "fP" : {
8
- "description" : "Functional position",
9
- "type" : ["string", "null"]
10
- },
11
- "fS" : {
12
- "description" : "Functional position",
13
- "type" : ["string", "null"]
14
- },
7
+ "cId" : false,
8
+ "fP" : false,
9
+ "fS" : false,
15
10
  "se" : {
11
+ "description" : "State bits 1 through 8. Bits 2, 6 and 8 must be cleared in messages sent by sites.",
16
12
  "type" : "array",
17
13
  "minItems": 8,
18
14
  "maxItems": 8,
15
+ "prefixItems" : [
16
+ { "type" : "boolean" },
17
+ { "const" : false },
18
+ { "type" : "boolean" },
19
+ { "type" : "boolean" },
20
+ { "type" : "boolean" },
21
+ { "const" : false },
22
+ { "type" : "boolean" },
23
+ { "const" : false }
24
+ ],
19
25
  "items" : {
20
26
  "type" : "boolean"
21
27
  }
22
28
  }
23
29
  },
24
- "required" : [ "mId", "aSTS", "fP", "fS", "se" ]
25
- }
30
+ "required" : [ "mId", "aSTS", "se" ]
31
+ }
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "title" : "Aggregated Status Request",
3
- "description" : "Aggregated status request message",
3
+ "description" : "Request for the aggregated status of the site",
4
4
  "properties" : {
5
5
  "mId" : { "$ref": "definitions.json#/message_id" },
6
- "cId" : { "$ref": "definitions.json#/component_id" }
6
+ "cId" : false
7
7
  },
8
- "required" : [ "mId", "cId" ]
9
- }
8
+ "required" : [ "mId" ]
9
+ }
@@ -14,7 +14,7 @@
14
14
  "type" : { "$ref": "definitions.json#/component_type" },
15
15
  "name" : { "$ref": "definitions.json#/component_name" }
16
16
  },
17
- "required" : [ "id", "type", "name" ],
17
+ "required" : [ "id", "type" ],
18
18
  "additionalProperties" : false
19
19
  },
20
20
  "uniqueItems" : true
@@ -31,6 +31,13 @@
31
31
  { "pattern": "^\\-?[0-9]+$" }
32
32
  ]
33
33
  },
34
+ "number_as_string": {
35
+ "description" : "Integer or decimal number as string",
36
+ "allOf" : [
37
+ { "$ref" : "#/rsmp_string" },
38
+ { "pattern": "^-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?$" }
39
+ ]
40
+ },
34
41
  "version": {
35
42
  "description" : "Version",
36
43
  "$comment" : "Example: 1.2.3 or 1.2",
@@ -61,9 +68,23 @@
61
68
  ]
62
69
  },
63
70
  "component_id": {
64
- "description" : "Compoment id",
71
+ "description" : "Component ID",
65
72
  "allOf" : [
66
- { "$ref" : "#/rsmp_string" }
73
+ { "$ref" : "#/rsmp_string" },
74
+ { "pattern" : "^[A-Za-z0-9_+=-]+(?:/[A-Za-z0-9_+=-]+)*$" }
75
+ ]
76
+ },
77
+ "component_id_selector": {
78
+ "description" : "Component selector",
79
+ "anyOf" : [
80
+ { "$ref" : "#/component_id" },
81
+ {
82
+ "allOf" : [
83
+ { "$ref" : "#/rsmp_string" },
84
+ { "pattern" : "^[A-Za-z0-9_+=-]+(?:/[A-Za-z0-9_+=-]+)*/$" }
85
+ ]
86
+ },
87
+ { "enum" : [ "/", "", null ] }
67
88
  ]
68
89
  },
69
90
  "component_type": {
@@ -14,8 +14,11 @@
14
14
  "sCI" : { "$ref": "definitions.json#/status_code" },
15
15
  "n" : { "description" : "Unique reference of the value", "type" : "string" },
16
16
  "uRt" : {
17
- "$ref": "definitions.json#/integer",
18
- "description" : "Update interval in seconds, 0 means send when value changes"
17
+ "allOf" : [
18
+ { "$ref": "definitions.json#/number_as_string" },
19
+ { "not": { "pattern": "^-" } }
20
+ ],
21
+ "description" : "Nonnegative update interval in seconds; zero disables periodic updates and requires sOc to be true"
19
22
  },
20
23
  "sOc" : {
21
24
  "type": "boolean",
@@ -23,9 +26,16 @@
23
26
  }
24
27
  },
25
28
  "required" : [ "sCI", "n", "uRt", "sOc" ],
26
- "additionalProperties": false
29
+ "additionalProperties": false,
30
+ "if": {
31
+ "properties": { "uRt": { "pattern": "^0(?:\\.0+)?$" } },
32
+ "required": [ "uRt" ]
33
+ },
34
+ "then": {
35
+ "properties": { "sOc": { "const": true } }
36
+ }
27
37
  }
28
38
  }
29
39
  },
30
40
  "required" : [ "mId", "cId", "sS"]
31
- }
41
+ }
@@ -15,7 +15,10 @@
15
15
  "description" : "Supported RSMP versions"
16
16
  },
17
17
  "SXL" : {
18
- "$ref": "definitions.json#/version",
18
+ "anyOf" : [
19
+ { "$ref": "definitions.json#/version" },
20
+ { "const": "" }
21
+ ],
19
22
  "description" : "Primary SXL version, for backward compatibility"
20
23
  },
21
24
  "SXLS" : {
@@ -34,7 +37,15 @@
34
37
  "uniqueItems" : true
35
38
  }
36
39
  },
37
- "required" : [ "mId", "RSMP", "SXLS", "siteId" ]
40
+ "required" : [ "mId", "step", "RSMP", "SXLS", "siteId" ],
41
+ "if" : {
42
+ "properties" : { "SXLS" : { "maxItems" : 0 } },
43
+ "required" : [ "SXLS" ]
44
+ },
45
+ "then" : {
46
+ "properties" : { "SXL" : { "const" : "" } },
47
+ "required" : [ "SXL" ]
48
+ }
38
49
  },
39
50
  {
40
51
  "description" : "Version response",
@@ -66,9 +77,10 @@
66
77
  "minItems" : 0,
67
78
  "uniqueItems" : true
68
79
  },
69
- "receiveAlarms" : {
70
- "description" : "Whether the supervisor wants to receive alarms",
71
- "type" : "boolean"
80
+ "useAlarms" : {
81
+ "description" : "Whether Alarm messages may be exchanged on the connection",
82
+ "type" : "boolean",
83
+ "default" : true
72
84
  }
73
85
  },
74
86
  "required" : [ "mId", "step", "RSMP", "supervisorId", "SXLS" ]
@@ -85,8 +97,7 @@
85
97
  "description" : "RSMP version"
86
98
  }
87
99
  },
88
- "required" : [ "vers" ],
89
- "additionalProperties" : false
100
+ "required" : [ "vers" ]
90
101
  },
91
102
  "minItems" : 1,
92
103
  "uniqueItems" : true
@@ -99,8 +110,7 @@
99
110
  "minLength": 1
100
111
  }
101
112
  },
102
- "required" : [ "sId" ],
103
- "additionalProperties" : false
113
+ "required" : [ "sId" ]
104
114
  },
105
115
  "sxl_request" : {
106
116
  "type" : "object",
@@ -109,34 +119,44 @@
109
119
  "version" : { "$ref" : "definitions.json#/version" },
110
120
  "prefix" : { "$ref" : "definitions.json#/sxl_prefix" }
111
121
  },
112
- "required" : [ "name", "version" ],
113
- "additionalProperties" : false
122
+ "required" : [ "name", "version" ]
114
123
  },
115
124
  "sxl_response" : {
116
125
  "type" : "object",
126
+ "properties" : {
127
+ "name" : { "$ref" : "definitions.json#/sxl_name" },
128
+ "status" : {
129
+ "type" : "string",
130
+ "enum" : [ "ok", "unsupported", "mismatch", "expected" ]
131
+ },
132
+ "version" : { "$ref" : "definitions.json#/version" },
133
+ "supported" : {
134
+ "type" : "array",
135
+ "items" : { "$ref" : "definitions.json#/version" }
136
+ }
137
+ },
138
+ "required" : [ "name", "status" ],
117
139
  "oneOf" : [
118
140
  {
119
141
  "properties" : {
120
- "name" : { "$ref" : "definitions.json#/sxl_name" },
121
- "version" : { "$ref" : "definitions.json#/version" }
142
+ "status" : { "const" : "ok" },
143
+ "supported" : false
122
144
  },
123
- "required" : [ "name", "version" ],
124
- "additionalProperties" : false
145
+ "required" : [ "version" ]
125
146
  },
126
147
  {
127
148
  "properties" : {
128
- "name" : { "$ref" : "definitions.json#/sxl_name" },
129
- "version" : { "$ref" : "definitions.json#/version" },
130
- "rejected" : {
131
- "type" : "integer",
132
- "enum" : [ 1, 2, 3 ]
133
- },
134
- "reason" : {
135
- "type" : "string"
136
- }
149
+ "status" : { "const" : "mismatch" },
150
+ "version" : false
137
151
  },
138
- "required" : [ "name", "rejected" ],
139
- "additionalProperties" : false
152
+ "required" : [ "supported" ]
153
+ },
154
+ {
155
+ "properties" : {
156
+ "status" : { "enum" : [ "unsupported", "expected" ] },
157
+ "version" : false,
158
+ "supported" : false
159
+ }
140
160
  }
141
161
  ]
142
162
  }
@@ -17,6 +17,11 @@
17
17
  "$comment" : "Example: 123 or -123",
18
18
  "pattern": "^\\-?[0-9]+$"
19
19
  },
20
+ "number_as_string": {
21
+ "description" : "Integer or decimal number as string",
22
+ "type": "string",
23
+ "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$"
24
+ },
20
25
  "version": {
21
26
  "description" : "Version",
22
27
  "type": "string",
@@ -17,6 +17,11 @@
17
17
  "$comment" : "Example: 123 or -123",
18
18
  "pattern": "^\\-?[0-9]+$"
19
19
  },
20
+ "number_as_string": {
21
+ "description" : "Integer or decimal number as string",
22
+ "type": "string",
23
+ "pattern": "^-?[0-9]+(?:\\.[0-9]+)?$"
24
+ },
20
25
  "version": {
21
26
  "description" : "Version",
22
27
  "type": "string",