rsmp 0.12.1 → 0.13.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: 278c4df55b2efbff06abd016ab49e09e6dec047cf873ad77a73346d7de08c54f
4
- data.tar.gz: bbd4ee23b200713574c483461be11116c35b7f08be0000e3eb008dbdf7c2c224
3
+ metadata.gz: 39bc5e9f248ab2db6d21e7a3c1e7c9e5ccb7c72e6e2be09dd28cbbaf5f6225d4
4
+ data.tar.gz: 3215d99759e3fb98f97c591ff9c9a3b2f1b1080306284b50429c46b0f677b137
5
5
  SHA512:
6
- metadata.gz: 8373359d1b9401273e6b71cadb0f5eb634c40239bc1054c0602c92fe5de9d1ca70cbd307362278f802369201f68e4d6702c5f962124d88fe9ec80c1cbb1513a9
7
- data.tar.gz: a20bd432dd787c6b50b507dde36b76aff0592fd9a8f97126ab2ce5684c2f8209c8402fd500e9a67e075b99ec35e388abafec40761e59724eb6a4fdd56ceec868
6
+ metadata.gz: 3f1be038f5bee13b83ecc2a5fe9ca79ae4e06ee906aa00d9766874193a24b12bda38752041c8e8fe1436aa98f93f026d9fcd0afbdfcf1b9366e0531a8d5c48f8
7
+ data.tar.gz: c52b47df3b59b30271c81b71b902fb55e2674de58c36e7458df091e39f1158641b98dcf94c840f8ab4673c35b7484b08770c0c8db1de30647f90df38ad590c34
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rsmp (0.12.1)
4
+ rsmp (0.13.0)
5
5
  async (~> 1.29.1)
6
6
  async-io (~> 1.32.2)
7
7
  colorize (~> 0.8.1)
@@ -68,7 +68,7 @@ GEM
68
68
  ffi (1.15.5-x64-mingw32)
69
69
  fiber-local (1.0.0)
70
70
  hana (1.3.7)
71
- json_schemer (0.2.19)
71
+ json_schemer (0.2.20)
72
72
  ecma-re-validator (~> 0.3)
73
73
  hana (~> 1.3)
74
74
  regexp_parser (~> 2.0)
@@ -80,7 +80,7 @@ GEM
80
80
  nio4r (2.5.8)
81
81
  rake (13.0.6)
82
82
  regexp_parser (2.2.1)
83
- rsmp_schemer (0.3.2)
83
+ rsmp_schemer (0.4.0)
84
84
  json_schemer (~> 0.2.18)
85
85
  rspec (3.10.0)
86
86
  rspec-core (~> 3.10.0)
@@ -1,25 +1,94 @@
1
1
  module RSMP
2
2
  # class that tracks the state of an alarm
3
3
  class AlarmState
4
- attr_reader :component_id, :code, :acknowledged, :suspended, :active, :timestamp, :category, :priority
4
+ attr_reader :component_id, :code, :acknowledged, :suspended, :active, :timestamp, :category, :priority, :rvs
5
5
 
6
- def initialize component_id:, code:
7
- @component_id = component_id
6
+ def initialize component:, code:
7
+ @component = component
8
+ @component_id = component.c_id
8
9
  @code = code
10
+ @suspended = false
9
11
  @acknowledged = false
10
12
  @suspended = false
11
13
  @active = false
12
14
  @timestamp = nil
13
- @category = nil
14
- @priority = nil
15
+ @category = 'D'
16
+ @priority = 2
17
+ @rvs = []
15
18
  end
16
19
 
17
20
  def suspend
18
- @suspended = true
21
+ change, @suspended = !@suspended, true
22
+ update_timestamp if change
23
+ change
19
24
  end
20
25
 
21
26
  def resume
22
- @suspended = false
27
+ change, @suspended = @suspended, false
28
+ update_timestamp if change
29
+ change
30
+ end
31
+
32
+ def activate
33
+ change, @active = !@active, true
34
+ update_timestamp if change
35
+ change
36
+ end
37
+
38
+ def deactivate
39
+ change, @active = @active, false
40
+ update_timestamp if change
41
+ change
42
+ end
43
+
44
+ def update_timestamp
45
+ @timestamp = @component.node.clock.now
23
46
  end
47
+
48
+ def to_message specialization:
49
+ Alarm.new(
50
+ 'cId' => @component_id,
51
+ 'aSp' => specialization,
52
+ 'aCId' => @code,
53
+ 'aTs' => Clock.to_s(@timestamp),
54
+ 'ack' => (@acknowledged ? 'Acknowledged' : 'notAcknowledged'),
55
+ 'sS' => (@suspended ? 'suspended' : 'notSuspended'),
56
+ 'aS' => (@active ? 'Active' : 'inActive'),
57
+ 'cat' => @category,
58
+ 'pri' => @priority.to_s,
59
+ 'rvs' => @rvs
60
+ )
61
+ end
62
+
63
+ def differ_from_message? message
64
+ return true if @timestamp != message.attribute('aTs')
65
+ return true if message.attribute('ack') && @acknowledged != (message.attribute('ack') == 'True')
66
+ return true if message.attribute('sS') && @suspended != (message.attribute('sS') == 'True')
67
+ return true if message.attribute('aS') && @active != (message.attribute('aS') == 'True')
68
+ return true if message.attribute('cat') && @category != message.attribute('cat')
69
+ return true if message.attribute('pri') && @priority != message.attribute('pri').to_i
70
+ #return true @rvs = message.attribute('rvs')
71
+ false
72
+ end
73
+
74
+ # update from rsmp message
75
+ # component id, alarm code and specialization are not updated
76
+ def update_from_message message
77
+ unless differ_from_message? message
78
+ raise RepeatedAlarmError.new("no changes from previous alarm #{message.m_id_short}")
79
+ end
80
+ if Time.parse(message.attribute('aTs')) < Time.parse(message.attribute('aTs'))
81
+ raise TimestampError.new("timestamp is earlier than previous alarm #{message.m_id_short}")
82
+ end
83
+ ensure
84
+ @timestamp = message.attribute('aTs')
85
+ @acknowledged = message.attribute('ack') == 'True'
86
+ @suspended = message.attribute('sS') == 'True'
87
+ @active = message.attribute('aS') == 'True'
88
+ @category = message.attribute('cat')
89
+ @priority = message.attribute('pri').to_i
90
+ @rvs = message.attribute('rvs')
91
+ end
92
+
24
93
  end
25
94
  end
@@ -1,7 +1,5 @@
1
1
  module RSMP
2
-
3
2
  # RSMP component
4
-
5
3
  class Component < ComponentBase
6
4
  def initialize node:, id:, grouped: false
7
5
  super
@@ -15,36 +13,38 @@ module RSMP
15
13
  raise UnknownStatus.new "Status #{status_code}/#{status_name} not implemented by #{self.class}"
16
14
  end
17
15
 
18
- def get_alarm_state alarm_code
19
- alarm = @alarms[alarm_code] ||= RSMP::AlarmState.new component_id: c_id, code: alarm_code
20
- end
21
-
22
16
  def suspend_alarm alarm_code
23
- alarm_state = get_alarm_state alarm_code
24
- if alarm.suspended == false
17
+ alarm = get_alarm_state alarm_code
18
+ if alarm.suspend
25
19
  log "Suspending alarm #{alarm_code}", level: :info
26
- alarm.suspend
27
20
  @node.alarm_suspended_or_resumed alarm
28
21
  else
29
22
  log "Alarm #{alarm_code} already suspended", level: :info
30
- end
23
+ end
31
24
  end
32
25
 
33
26
  def resume_alarm alarm_code
34
- alarm_state = get_alarm_state alarm_code
35
- if alarm.suspended
27
+ alarm = get_alarm_state alarm_code
28
+ if alarm.resume
36
29
  log "Resuming alarm #{alarm_code}", level: :info
37
- alarm.resume
38
30
  @node.alarm_suspended_or_resumed alarm
39
31
  else
40
- log "Alarm #{alarm_code} not suspended", level: :info
32
+ log "Alarm #{alarm_code} already resumed", level: :info
41
33
  end
42
34
  end
43
35
 
44
- # send alarm
45
- def send_alarm code:, status:
46
- @node.alarm_changed self, alarm
36
+ def activate_alarm alarm_code
37
+ alarm = get_alarm_state alarm_code
38
+ return unless alarm.activate
39
+ log "Activating alarm #{alarm_code}", level: :info
40
+ @node.alarm_activated_or_deactivated alarm
47
41
  end
48
42
 
43
+ def deactivate_alarm alarm_code
44
+ alarm = get_alarm_state alarm_code
45
+ return unless alarm.deactivate
46
+ log "Deactivating alarm #{alarm_code}", level: :info
47
+ @node.alarm_activated_or_deactivated alarm
48
+ end
49
49
  end
50
50
  end
@@ -20,8 +20,12 @@ module RSMP
20
20
  @c_id = id
21
21
  @node = node
22
22
  @grouped = grouped
23
- @alarms = {}
24
23
  clear_aggregated_status
24
+ @alarms = {}
25
+ end
26
+
27
+ def get_alarm_state alarm_code
28
+ alarm = @alarms[alarm_code] ||= RSMP::AlarmState.new component: self, code: alarm_code
25
29
  end
26
30
 
27
31
  def clear_aggregated_status
@@ -1,10 +1,9 @@
1
1
  module RSMP
2
-
3
2
  # A proxy to a remote RSMP component.
4
-
5
3
  class ComponentProxy < ComponentBase
6
4
  def initialize node:, id:, grouped: false
7
5
  super
6
+ @alarms = {}
8
7
  @statuses = {}
9
8
  @allow_repeat_updates = {}
10
9
  end
@@ -45,23 +44,12 @@ module RSMP
45
44
  @allow_repeat_updates[sCI].delete(n) if @allow_repeat_updates[sCI]
46
45
  end
47
46
  end
48
-
47
+
49
48
  # handle incoming alarm
50
49
  def handle_alarm message
51
- # code = message.attribute('aCId')
52
- # previous = @alarms[code]
53
- # if previous
54
- # unless message.differ?(previous)
55
- # raise RepeatedAlarmError.new("no changes from previous alarm #{previous.m_id_short}")
56
- # end
57
- # if Time.parse(message.attribute('aTs')) < Time.parse(previous.attribute('aTs'))
58
- # raise TimestampError.new("timestamp is earlier than previous alarm #{previous.m_id_short}")
59
- # end
60
- # end
61
- # p message
62
- # ensure
63
- # @alarms[code] = message
50
+ code = message.attribute('aCId')
51
+ alarm = get_alarm_state code
52
+ alarm.update_from_message message
64
53
  end
65
-
66
- end
54
+ end
67
55
  end
data/lib/rsmp/message.rb CHANGED
@@ -68,7 +68,13 @@ module RSMP
68
68
  when /Acknowledge/i
69
69
  AlarmAcknowledged.new attributes
70
70
  when /Suspend/i
71
- AlarmSuspend.new attributes
71
+ if attributes['sS'] =~ /suspended/i
72
+ AlarmSuspended.new attributes
73
+ elsif attributes['sS'] =~ /notSuspended/i
74
+ AlarmResumed.new attributes
75
+ else
76
+ AlarmSuspend.new attributes
77
+ end
72
78
  when /Resume/i
73
79
  AlarmResume.new attributes
74
80
  else
@@ -264,7 +270,23 @@ module RSMP
264
270
  end
265
271
  end
266
272
 
273
+ class AlarmSuspended < Alarm
274
+ def initialize attributes = {}
275
+ super({
276
+ "aSp" => "Suspend",
277
+ "sS" => "suspended"
278
+ }.merge attributes)
279
+ end
280
+ end
267
281
 
282
+ class AlarmResumed < Alarm
283
+ def initialize attributes = {}
284
+ super({
285
+ "aSp" => "Suspend",
286
+ "sS" => "notSuspended"
287
+ }.merge attributes)
288
+ end
289
+ end
268
290
 
269
291
  class Watchdog < Message
270
292
  def initialize attributes = {}
data/lib/rsmp/site.rb CHANGED
@@ -93,23 +93,31 @@ module RSMP
93
93
  end
94
94
  end
95
95
 
96
- def alarm_state_to_message alarm_state
97
- Alarm.new(
96
+ def alarm_state_to_hash alarm_state
97
+ {
98
98
  'cId' => alarm_state.component_id,
99
- 'aTs' => clock.to_s,
100
99
  'aCId' => alarm_state.code,
101
- 'aSp' => (alarm_state.suspended ? 'Suspend' : 'Issue'),
100
+ 'aTs' => Clock.to_s(alarm_state.timestamp),
102
101
  'ack' => (alarm_state.acknowledged ? 'Acknowledged' : 'notAcknowledged'),
103
102
  'sS' => (alarm_state.suspended ? 'suspended' : 'notSuspended'),
104
103
  'aS' => (alarm_state.active ? 'Active' : 'inActive'),
105
- 'cat' => (alarm_state.category || 'D'),
106
- 'pri' => (alarm_state.priority || '2'),
107
- 'rvs' => []
108
- )
104
+ 'cat' => alarm_state.category,
105
+ 'pri' => alarm_state.priority.to_s,
106
+ 'rvs' => alarm_state.rvs
107
+ }
109
108
  end
110
109
 
111
110
  def alarm_suspended_or_resumed alarm_state
112
- alarm = alarm_state_to_message alarm_state
111
+ alarm = AlarmIssue.new( alarm_state_to_hash(alarm_state).merge('aSp' => 'Suspend') )
112
+ send_alarm alarm
113
+ end
114
+
115
+ def alarm_activated_or_deactivated alarm_state
116
+ alarm = AlarmIssue.new( alarm_state_to_hash(alarm_state).merge('aSp' => 'Issue') )
117
+ send_alarm alarm
118
+ end
119
+
120
+ def send_alarm alarm
113
121
  @proxies.each do |proxy|
114
122
  proxy.send_message alarm if proxy.ready?
115
123
  end
@@ -63,7 +63,7 @@ module RSMP
63
63
  process_aggregated_status message
64
64
  when AggregatedStatusRequest
65
65
  will_not_handle message
66
- when Alarm
66
+ when AlarmIssue, AlarmSuspended, AlarmResumed
67
67
  process_alarm message
68
68
  when CommandResponse
69
69
  process_command_response message
@@ -105,7 +105,7 @@ module RSMP
105
105
  process_status_subcribe message
106
106
  when StatusUnsubscribe
107
107
  process_status_unsubcribe message
108
- when AlarmAcknowledged, AlarmSuspend, AlarmResume, AlarmRequest
108
+ when Alarm, AlarmAcknowledged, AlarmSuspend, AlarmResume, AlarmRequest
109
109
  process_alarm message
110
110
  else
111
111
  super message
@@ -264,10 +264,10 @@ module RSMP
264
264
  alarm_code = actions['raise']
265
265
  if change
266
266
  log "Activating alarm #{alarm_code}, because input #{input} was activated", level: :info
267
- send_alarm code:alarm_code, status:'Active'
267
+ activate_alarm alarm_code
268
268
  else
269
269
  log "Deactivating alarm #{alarm_code}, because input #{input} was deactivated", level: :info
270
- send_alarm code:alarm_code, status:'inActive'
270
+ deactivate_alarm alarm_code
271
271
  end
272
272
  end
273
273
  end
data/lib/rsmp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RSMP
2
- VERSION = "0.12.1"
2
+ VERSION = "0.13.0"
3
3
  end
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.12.1
4
+ version: 0.13.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: 2022-04-01 00:00:00.000000000 Z
11
+ date: 2022-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async