blob: 932855cb70fa23ada1f75c120e90ed800481c141 [file] [log] [blame]
William Kurkian6f436d02019-02-06 16:25:01 -05001#
2# Copyright 2018 the original author or authors.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17import arrow
William Kurkian44cd7bb2019-02-11 16:39:12 -050018from pyvoltha.adapters.extensions.alarms.adapter_alarms import AdapterAlarms
19from pyvoltha.adapters.extensions.alarms.simulator.simulate_alarms import AdapterAlarmSimulator
20from pyvoltha.adapters.extensions.alarms.olt.olt_los_alarm import OltLosAlarm
21from pyvoltha.adapters.extensions.alarms.onu.onu_dying_gasp_alarm import OnuDyingGaspAlarm
22from pyvoltha.adapters.extensions.alarms.onu.onu_los_alarm import OnuLosAlarm
23from pyvoltha.adapters.extensions.alarms.onu.onu_lopc_miss_alarm import OnuLopcMissAlarm
24from pyvoltha.adapters.extensions.alarms.onu.onu_lopc_mic_error_alarm import OnuLopcMicErrorAlarm
25from pyvoltha.adapters.extensions.alarms.onu.onu_lob_alarm import OnuLobAlarm
William Kurkian6f436d02019-02-06 16:25:01 -050026
William Kurkian44cd7bb2019-02-11 16:39:12 -050027from pyvoltha.adapters.extensions.alarms.onu.onu_startup_alarm import OnuStartupAlarm
28from pyvoltha.adapters.extensions.alarms.onu.onu_signal_degrade_alarm import OnuSignalDegradeAlarm
29from pyvoltha.adapters.extensions.alarms.onu.onu_signal_fail_alarm import OnuSignalFailAlarm
30from pyvoltha.adapters.extensions.alarms.onu.onu_window_drift_alarm import OnuWindowDriftAlarm
31from pyvoltha.adapters.extensions.alarms.onu.onu_activation_fail_alarm import OnuActivationFailAlarm
William Kurkian6f436d02019-02-06 16:25:01 -050032
William Kurkian8b1690c2019-03-04 16:53:22 -050033import voltha_protos.openolt_pb2 as openolt_pb2
34import voltha_protos.device_pb2 as device_pb2
William Kurkian6f436d02019-02-06 16:25:01 -050035
36
37class OpenOltAlarmMgr(object):
38 def __init__(self, log, adapter_agent, device_id, logical_device_id,
39 platform):
40 """
41 20180711 - Addition of adapter_agent and device_id
42 to facilitate alarm processing and kafka posting
43 :param log:
44 :param adapter_agent:
45 :param device_id:
46 """
47 self.log = log
48 self.adapter_agent = adapter_agent
49 self.device_id = device_id
50 self.logical_device_id = logical_device_id
51 self.platform = platform
52 """
53 The following is added to reduce the continual posting of OLT LOS alarming
54 to Kafka. Set enable_alarm_suppress = true to enable otherwise the
55 current openolt bal will send continuous olt los alarm cleared messages
56 ONU disc raised counter is place holder for a future addition
57 """
58 self.enable_alarm_suppress = True
59 self.alarm_suppress = {"olt_los_clear": 0, "onu_disc_raised": []} # Keep count of alarms to limit.
60 try:
61 self.alarms = AdapterAlarms(self.adapter_agent, self.device_id, self.logical_device_id)
62 self.simulator = AdapterAlarmSimulator(self.alarms)
63 except Exception as initerr:
64 self.log.exception("alarmhandler-init-error", errmsg=initerr.message)
65 raise Exception(initerr)
66
67 def process_alarms(self, alarm_ind):
68 try:
69 self.log.debug('alarm-indication', alarm=alarm_ind, device_id=self.device_id)
70 if alarm_ind.HasField('los_ind'):
71 self.los_indication(alarm_ind.los_ind)
72 elif alarm_ind.HasField('dying_gasp_ind'):
73 self.dying_gasp_indication(alarm_ind.dying_gasp_ind)
74 elif alarm_ind.HasField('onu_alarm_ind'):
75 self.onu_alarm_indication(alarm_ind.onu_alarm_ind)
76 elif alarm_ind.HasField('onu_startup_fail_ind'):
77 self.onu_startup_failure_indication(
78 alarm_ind.onu_startup_fail_ind)
79 elif alarm_ind.HasField('onu_signal_degrade_ind'):
80 self.onu_signal_degrade_indication(
81 alarm_ind.onu_signal_degrade_ind)
82 elif alarm_ind.HasField('onu_drift_of_window_ind'):
83 self.onu_drift_of_window_indication(
84 alarm_ind.onu_drift_of_window_ind)
85 elif alarm_ind.HasField('onu_loss_omci_ind'):
86 self.onu_loss_omci_indication(alarm_ind.onu_loss_omci_ind)
87 elif alarm_ind.HasField('onu_signals_fail_ind'):
88 self.onu_signals_failure_indication(
89 alarm_ind.onu_signals_fail_ind)
90 elif alarm_ind.HasField('onu_tiwi_ind'):
91 self.onu_transmission_interference_warning(
92 alarm_ind.onu_tiwi_ind)
93 elif alarm_ind.HasField('onu_activation_fail_ind'):
94 self.onu_activation_failure_indication(
95 alarm_ind.onu_activation_fail_ind)
96 elif alarm_ind.HasField('onu_processing_error_ind'):
97 self.onu_processing_error_indication(
98 alarm_ind.onu_processing_error_ind)
99 else:
100 self.log.warn('unknown alarm type', alarm=alarm_ind)
101
102 except Exception as e:
103 self.log.error('sorting of alarm went wrong', error=e,
104 alarm=alarm_ind)
105
106 def simulate_alarm(self, alarm):
107 self.simulator.simulate_alarm(alarm)
108
109 def los_indication(self, los_ind):
110
111 try:
112 self.log.debug('los indication received', los_ind=los_ind,
113 int_id=los_ind.intf_id, status=los_ind.status)
114 try:
115 port_type_name = self.platform.intf_id_to_port_type_name(los_ind.intf_id)
116 if los_ind.status == 1 or los_ind.status == "on":
117 # Zero out the suppression counter on OLT_LOS raise
118 self.alarm_suppress['olt_los_clear'] = 0
119 OltLosAlarm(self.alarms, intf_id=los_ind.intf_id, port_type_name=port_type_name).raise_alarm()
120 else:
121 """
122 Check if there has been more that one los clear following a previous los
123 """
124 if self.alarm_suppress['olt_los_clear'] == 0 and self.enable_alarm_suppress:
125 OltLosAlarm(self.alarms, intf_id=los_ind.intf_id, port_type_name=port_type_name).clear_alarm()
126 self.alarm_suppress['olt_los_clear'] += 1
127
128 except Exception as alarm_err:
129 self.log.error('los-indication', errmsg=alarm_err.message)
130 except Exception as e:
131 self.log.error('los-indication', errmsg=e.message)
132
133 def dying_gasp_indication(self, dying_gasp_ind):
134 try:
135 alarm_dgi = dying_gasp_ind
136 onu_id = alarm_dgi.onu_id
137 self.log.debug('openolt-alarmindication-dispatch-dying-gasp', int_id=alarm_dgi.intf_id,
138 onu_id=alarm_dgi.onu_id, status=alarm_dgi.status)
139 try:
140 """
141 Get the specific onu device information for the onu generating the alarm.
142 Extract the id. In the future extract the serial number as well
143 """
144 onu_device_id = "unresolved"
145 onu_serial_number = "unresolved"
146 onu_device = self.resolve_onu_id(onu_id, port_intf_id=alarm_dgi.intf_id)
147 if onu_device != None:
148 onu_device_id = onu_device.id
149 onu_serial_number = onu_device.serial_number
150
151 if dying_gasp_ind.status == 1 or dying_gasp_ind.status == "on":
152 OnuDyingGaspAlarm(self.alarms, dying_gasp_ind.intf_id,
153 onu_device_id).raise_alarm()
154 else:
155 OnuDyingGaspAlarm(self.alarms, dying_gasp_ind.intf_id,
156 onu_device_id).clear_alarm()
157 except Exception as alarm_err:
158 self.log.exception('dying-gasp-indication', errmsg=alarm_err.message)
159
160 except Exception as e:
161 self.log.error('dying_gasp_indication', error=e)
162
163 def onu_alarm_indication(self, onu_alarm_ind):
164 """
165 LOB = Los of burst
166 LOPC = Loss of PLOAM miss channel
167
168 :param onu_alarm_ind: Alarm indication which currently contains
169 onu_id:
170 los_status:
171 lob_status:
172 lopc_miss_status:
173 lopc_mic_error_status:
174 :return:
175 """
176 self.log.info('onu-alarm-indication')
177
178 try:
179 self.log.debug('onu alarm indication received', los_status=onu_alarm_ind.los_status,
180 onu_intf_id=onu_alarm_ind.onu_id,
181 lob_status=onu_alarm_ind.lob_status,
182 lopc_miss_status=onu_alarm_ind.lopc_miss_status,
183 lopc_mic_error_status=onu_alarm_ind.lopc_mic_error_status,
184 intf_id=onu_alarm_ind.intf_id
185 )
186
187 try:
188 """
189 Get the specific onu device information for the onu generating the alarm.
190 Extract the id. In the future extract the serial number as well
191 """
192 onu_device_id = "unresolved"
193 serial_number = "unresolved"
194 onu_device = self.resolve_onu_id(onu_alarm_ind.onu_id, port_intf_id=onu_alarm_ind.intf_id)
195 if onu_device != None:
196 onu_device_id = onu_device.id
197 serial_number = onu_device.serial_number
198
199 if onu_alarm_ind.los_status == 1 or onu_alarm_ind.los_status == "on":
200 OnuLosAlarm(self.alarms, onu_id=onu_device_id, intf_id=onu_alarm_ind.intf_id).raise_alarm()
201 elif onu_alarm_ind.los_status == 0 or onu_alarm_ind.los_status == "off":
202 OnuLosAlarm(self.alarms, onu_id=onu_device_id, intf_id=onu_alarm_ind.intf_id).clear_alarm()
203 else: # No Change
204 pass
205
206 if onu_alarm_ind.lopc_miss_status == 1 or onu_alarm_ind.lopc_miss_status == "on":
207 OnuLopcMissAlarm(self.alarms, onu_id=onu_device_id, intf_id=onu_alarm_ind.intf_id).raise_alarm()
208 elif (onu_alarm_ind.lopc_miss_status == 0 or onu_alarm_ind.lopc_miss_status == "off"):
209 OnuLopcMissAlarm(self.alarms, onu_id=onu_device_id, intf_id=onu_alarm_ind.intf_id).clear_alarm()
210 else: # No Change
211 pass
212
213 if onu_alarm_ind.lopc_mic_error_status == 1 or onu_alarm_ind.lopc_mic_error_status == "on":
214 OnuLopcMicErrorAlarm(self.alarms, onu_id=onu_device_id, intf_id=onu_alarm_ind.intf_id).raise_alarm()
215 elif onu_alarm_ind.lopc_mic_error_status == 0 or onu_alarm_ind.lopc_mic_error_status == "off":
216 OnuLopcMicErrorAlarm(self.alarms, onu_id=onu_device_id, intf_id=onu_alarm_ind.intf_id).clear_alarm()
217 else: # No Change
218 pass
219
220 if onu_alarm_ind.lob_status == 1 or onu_alarm_ind.lob_status == "on":
221 OnuLobAlarm(self.alarms, onu_id=onu_device_id, intf_id=onu_alarm_ind.intf_id).raise_alarm()
222 elif onu_alarm_ind.lob_status == 0 or onu_alarm_ind.lob_status == "off":
223 OnuLobAlarm(self.alarms, onu_id=onu_device_id, intf_id=onu_alarm_ind.intf_id).clear_alarm()
224 else: # No Change
225 pass
226 except Exception as alarm_err:
227 self.log.exception('onu-alarm-indication', errmsg=alarm_err.message)
228
229 except Exception as e:
230 self.log.exception('onu-alarm-indication', errmsg=e.message)
231
232 def onu_startup_failure_indication(self, onu_startup_fail_ind):
233 """
234 Current protobuf indicator:
235 message OnuStartupFailureIndication {
236 fixed32 intf_id = 1;
237 fixed32 onu_id = 2;
238 string status = 3;
239 }
240
241 :param onu_startup_fail_ind:
242 :return:
243 """
244 try:
245 ind = onu_startup_fail_ind
246 label = "onu-startup-failure-indication"
247 self.log.debug(label + " received", onu_startup_fail_ind=ind, int_id=ind.intf_id, onu_id=ind.onu_id, status=ind.status)
248 try:
249 if ind.status == 1 or ind.status == "on":
250 OnuStartupAlarm(self.alarms, intf_id=ind.intf_id,onu_id=ind.onu_id).raise_alarm()
251 else:
252 OnuStartupAlarm(self.alarms, intf_id=ind.intf_id, onu_id=ind.onu_id).clear_alarm()
253 except Exception as alarm_err:
254 self.log.exception(label, errmsg=alarm_err.message)
255
256 except Exception as e:
257 self.log.exception(label, errmsg=e.message)
258
259 def onu_signal_degrade_indication(self, onu_signal_degrade_ind):
260 """
261 Current protobuf indicator:
262 OnuSignalDegradeIndication {
263 fixed32 intf_id = 1;
264 fixed32 onu_id = 2;
265 string status = 3;
266 fixed32 inverse_bit_error_rate = 4;
267 }
268 :param onu_signal_degrade_ind:
269 :return:
270 """
271 try:
272 ind = onu_signal_degrade_ind
273 label = "onu-signal-degrade-indication"
274 self.log.debug(label + ' received',
275 onu_startup_fail_ind=ind,
276 int_id=ind.intf_id,
277 onu_id=ind.onu_id,
278 inverse_bit_error_rate=ind.inverse_bit_error_rate,
279 status=ind.status)
280 try:
281 if ind.status == 1 or ind.status == "on":
282 OnuSignalDegradeAlarm(self.alarms, intf_id=ind.intf_id, onu_id=ind.onu_id,
283 inverse_bit_error_rate=ind.inverse_bit_error_rate).raise_alarm()
284 else:
285 OnuSignalDegradeAlarm(self.alarms, intf_id=ind.intf_id, onu_id=ind.onu_id,
286 inverse_bit_error_rate=ind.inverse_bit_error_rate).clear_alarm()
287 except Exception as alarm_err:
288 self.log.exception(label, errmsg=alarm_err.message)
289
290 except Exception as e:
291 self.log.exception(label, errmsg=e.message)
292
293 def onu_drift_of_window_indication(self, onu_drift_of_window_ind):
294 """
295 Current protobuf indicator:
296 OnuDriftOfWindowIndication {
297 fixed32 intf_id = 1;
298 fixed32 onu_id = 2;
299 string status = 3;
300 fixed32 drift = 4;
301 fixed32 new_eqd = 5;
302 }
303
304 :param onu_drift_of_window_ind:
305 :return:
306 """
307 try:
308 ind = onu_drift_of_window_ind
309 label = "onu-window-drift-indication"
310
311 onu_device_id, onu_serial_number = self.resolve_onudev_id_onudev_serialnum(
312 self.resolve_onu_id(ind.onu_id, port_intf_id=ind.intf_id))
313
314 self.log.debug(label + ' received',
315 onu_drift_of_window_ind=ind,
316 int_id=ind.intf_id,
317 onu_id=ind.onu_id,
318 onu_device_id=onu_device_id,
319 drift=ind.drift,
320 new_eqd=ind.new_eqd,
321 status=ind.status)
322 try:
323 if ind.status == 1 or ind.status == "on":
324 OnuWindowDriftAlarm(self.alarms, intf_id=ind.intf_id,
325 onu_id=onu_device_id,
326 drift=ind.drift,
327 new_eqd=ind.new_eqd).raise_alarm()
328 else:
329 OnuWindowDriftAlarm(self.alarms, intf_id=ind.intf_id,
330 onu_id=onu_device_id,
331 drift=ind.drift,
332 new_eqd=ind.new_eqd).clear_alarm()
333 except Exception as alarm_err:
334 self.log.exception(label, errmsg=alarm_err.message)
335
336 except Exception as e:
337 self.log.exception(label, errmsg=e.message)
338
339 def onu_loss_omci_indication(self, onu_loss_omci_ind):
340 self.log.info('not implemented yet')
341
342 def onu_signals_failure_indication(self, onu_signals_fail_ind):
343 """
344 Current protobuf indicator:
345 OnuSignalsFailureIndication {
346 fixed32 intf_id = 1;
347 fixed32 onu_id = 2;
348 string status = 3;
349 fixed32 inverse_bit_error_rate = 4;
350 }
351
352 :param onu_signals_fail_ind:
353 :return:
354 """
355 try:
356 ind = onu_signals_fail_ind
357 label = "onu-signal-failure-indication"
358
359 onu_device_id, onu_serial_number = self.resolve_onudev_id_onudev_serialnum(
360 self.resolve_onu_id(ind.onu_id, port_intf_id=ind.intf_id))
361
362 self.log.debug(label + ' received',
363 onu_startup_fail_ind=ind,
364 int_id=ind.intf_id,
365 onu_id=ind.onu_id,
366 onu_device_id=onu_device_id,
367 onu_serial_number=onu_serial_number,
368 inverse_bit_error_rate=ind.inverse_bit_error_rate,
369 status=ind.status)
370 try:
371 if ind.status == 1 or ind.status == "on":
372 OnuSignalFailAlarm(self.alarms, intf_id=ind.intf_id,
373 onu_id=onu_device_id,
374 inverse_bit_error_rate=ind.inverse_bit_error_rate).raise_alarm()
375 else:
376 OnuSignalFailAlarm(self.alarms, intf_id=ind.intf_id,
377 onu_id=onu_device_id,
378 inverse_bit_error_rate=ind.inverse_bit_error_rate).clear_alarm()
379 except Exception as alarm_err:
380 self.log.exception(label, errmsg=alarm_err.message)
381
382 except Exception as e:
383 self.log.exception(label, errmsg=e.message)
384
385
386 def onu_transmission_interference_warning(self, onu_tiwi_ind):
387 self.log.info('not implemented yet')
388
389 def onu_activation_failure_indication(self, onu_activation_fail_ind):
390 """
391
392 No status is currently passed with this alarm. Consequently it will always just raise
393 :param onu_activation_fail_ind:
394 :return:
395 """
396 try:
397 ind = onu_activation_fail_ind
398 label = "onu-activation-failure-indication"
399
400 onu_device_id, onu_serial_number = self.resolve_onudev_id_onudev_serialnum(
401 self.resolve_onu_id(ind.onu_id, port_intf_id=ind.intf_id))
402
403 self.log.debug(label + ' received',
404 onu_startup_fail_ind=ind,
405 int_id=ind.intf_id,
406 onu_id=ind.onu_id,
407 onu_device_id=onu_device_id,
408 onu_serial_number=onu_serial_number)
409 try:
410
411 OnuActivationFailAlarm(self.alarms, intf_id=ind.intf_id,
412 onu_id=onu_device_id).raise_alarm()
413 except Exception as alarm_err:
414 self.log.exception(label, errmsg=alarm_err.message)
415
416 except Exception as e:
417 self.log.exception(label, errmsg=e.message)
418
419 def onu_processing_error_indication(self, onu_processing_error_ind):
420 self.log.info('not implemented yet')
421
422 """
423 Helper Methods
424 """
425
426 def resolve_onudev_id_onudev_serialnum(self,onu_device):
427 """
428 Convenience wrapper to resolve device_id and serial number
429 :param onu_device:
430 :return: tuple: onu_device_id, onu_serial_number
431 """
432 try:
433 onu_device_id = "unresolved"
434 onu_serial_number = "unresolved"
435 if onu_device != None:
436 onu_device_id = onu_device.id
437 onu_serial_number = onu_device.serial_number
438 except Exception as err:
439 self.log.exception("openolt-alarms-resolve-onudev-id ", errmsg=err.message)
440 raise Exception(err)
441 return onu_device_id, onu_serial_number
442
443 def resolve_onu_id(self, onu_id, port_intf_id):
444 """
445 Resolve the onu_device from the intf_id value and port. Uses the adapter agent to
446 resolve this..
447
448 Returns None if not found. Caller will have to test for None and act accordingly.
449 :param onu_id:
450 :param port_intf_id:
451 :return:
452 """
453
454 try:
455 onu_device = None
456 onu_device = self.adapter_agent.get_child_device(
457 self.device_id,
458 parent_port_no=self.platform.intf_id_to_port_no(
459 port_intf_id, device_pb2.Port.PON_OLT),
460 onu_id=onu_id)
461 onu_device_id = onu_device.id
462 except Exception as inner:
463 self.log.exception('resolve-onu-id', errmsg=inner.message)
464
465 return onu_device
466