rsmp 0.12.3 → 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: d97c24017cb23ab7159bebda96f262f50813d902365e2fa1fabeb90d4771df01
4
- data.tar.gz: fde070792556ef05d68ebfe5d7757d696f81921d75e64ced80f2a1c4878d39ef
3
+ metadata.gz: 39bc5e9f248ab2db6d21e7a3c1e7c9e5ccb7c72e6e2be09dd28cbbaf5f6225d4
4
+ data.tar.gz: 3215d99759e3fb98f97c591ff9c9a3b2f1b1080306284b50429c46b0f677b137
5
5
  SHA512:
6
- metadata.gz: 2b58d0ed3307893fdd43fcd361b5da63e541baf199ac21860fa11cca756fe4339a63b4bf3420164232c248667e3cf75fe0b467928642e9fcd99f951308fa6e67
7
- data.tar.gz: 3c5cb9a04f22a56a16f51c41faff55a5d587fe51dd2774e6a018846da40b5bf066f08bbbfc7848382ec2a76c64a0b17cad372972b0357d7182359e934864b771
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.3)
4
+ rsmp (0.13.0)
5
5
  async (~> 1.29.1)
6
6
  async-io (~> 1.32.2)
7
7
  colorize (~> 0.8.1)
@@ -1,33 +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
23
30
  end
24
31
 
25
32
  def activate
26
- @active = true
33
+ change, @active = !@active, true
34
+ update_timestamp if change
35
+ change
27
36
  end
28
37
 
29
38
  def deactivate
30
- @active = false
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
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
+ )
31
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
+
32
93
  end
33
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,40 +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
17
  alarm = get_alarm_state alarm_code
24
- return if alarm.suspended
25
- log "Suspending alarm #{alarm_code}", level: :info
26
- alarm.suspend
27
- @node.alarm_changed alarm
18
+ if alarm.suspend
19
+ log "Suspending alarm #{alarm_code}", level: :info
20
+ @node.alarm_suspended_or_resumed alarm
21
+ else
22
+ log "Alarm #{alarm_code} already suspended", level: :info
23
+ end
28
24
  end
29
25
 
30
26
  def resume_alarm alarm_code
31
27
  alarm = get_alarm_state alarm_code
32
- return unless alarm.suspended
33
- log "Resuming alarm #{alarm_code}", level: :info
34
- alarm.resume
35
- @node.alarm_changed alarm
28
+ if alarm.resume
29
+ log "Resuming alarm #{alarm_code}", level: :info
30
+ @node.alarm_suspended_or_resumed alarm
31
+ else
32
+ log "Alarm #{alarm_code} already resumed", level: :info
33
+ end
36
34
  end
37
35
 
38
36
  def activate_alarm alarm_code
39
37
  alarm = get_alarm_state alarm_code
40
- return if alarm.active
38
+ return unless alarm.activate
41
39
  log "Activating alarm #{alarm_code}", level: :info
42
- alarm.activate
43
- @node.alarm_changed alarm
40
+ @node.alarm_activated_or_deactivated alarm
44
41
  end
45
42
 
46
43
  def deactivate_alarm alarm_code
47
44
  alarm = get_alarm_state alarm_code
48
- return unless alarm.active
45
+ return unless alarm.deactivate
49
46
  log "Deactivating alarm #{alarm_code}", level: :info
50
- alarm.deactivate
51
- @node.alarm_changed alarm
47
+ @node.alarm_activated_or_deactivated alarm
52
48
  end
53
49
  end
54
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
+ }
108
+ end
109
+
110
+ def alarm_suspended_or_resumed 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
109
118
  end
110
119
 
111
- def alarm_changed alarm_state
112
- alarm = alarm_state_to_message alarm_state
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
data/lib/rsmp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RSMP
2
- VERSION = "0.12.3"
2
+ VERSION = "0.13.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rsmp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.3
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emil Tin