[PYTHON] "Honwaka Notification Lamp" on Raspberry Pi Part 3

Help monitor with Raspberry Pi

In this series, we will make a notification lamp using Raspberry Pi. Blue.GIF

This time, the third time, is the main part that controls the entire "notification lamp". This series is now complete.

SystemDiagram2.png

Introducing Abu

Alert Buster (Abu for short) is responsible for acquiring OpsGenie Alert information via the Detector, identifying the status of the monitored object, and setting the LED display. It's also Abu's job to ring the chime only once when a new Alert occurs.

Only one status can display the "notification lamp" for the Alert status that may exist more than once at the same time. Therefore, prioritize the states to display the highest priority state.

Relationship between the state handled by Abu and the display

Abu handles the following 6 types of states. There are two levels, "Error" and "Warning". An "error" is something that you need to deal with in a hurry, and a "warning" is something that you are not in a hurry but need to confirm. There are two states, whether or not they have been recognized.

"Unknown" is used when the status is unknown, such as immediately after startup or due to a network problem. Decide the color to be assigned to each state and the blinking cycle. For the color names such as "Magenta", use the ones defined in Led.COLORS of the previous article.

priority Alert type Cognitive status State value color Flickering cycle Note
1 unknown - 1 Magenta 0 (no blinking)
2 error Unrecognized 2 Red 0.5 seconds
3 Warning Unrecognized 4 Yellow 2 seconds
4 error Recognized 8 Green 2 seconds
5 Warning Recognized 16 Green 6 seconds
6 New error - 32 - - For chimes
7 New warning - 64 - - For chimes
8 normal - 0 Blue 8 seconds

Abu treats these states as a single integer value "state value". "State value" is assigned each bit value of the binary number so that it can be easily handled by bit operation. In "normal", all bits are 0, so there is no bit allocation.

Internally, the logical sum of 7 bits including the chime control flag in the above table is used as one state value. For example, if there is a new error that has not yet been recognized (before the chime sounds), the state value is 0x22.

The state value is represented by a single integer value that has a meaning for each bit, but you may use Python's Set type with an emphasis on readability.

chime

How to ring

When a new error or warning is found, the chime will sound only once to make it easier to notice. The chime plays the prepared sound file by passing it to the aplay command.

python


$ aplay --quiet /usr/share/sounds/alsa/Rear_Center.wav

In advance, connect a speaker to the earphone jack or USB port of the main unit and set it so that sound can be heard. Reference: https://www.google.co.jp/search?q=raspberrypi+aplay

sound source

The chime sound source can be any format supported by aplay. In Abu, I used the following from freesound.org. If you register as a user, you can download it, so check the license and use it.

How Abu works

Abu's work is as follows.

--Initialize Detector --Launch LED Deamon --Repeat the following --Call Detector to get a list of Alerts --Collect Alert Lists and Create Status Values --Set LED display according to the status value --Sound a chime if there is a new error or warning --Sleep for 1 minute

starting method

$ ./abu.py ********-****-****-****-************

********-****-****-****-************For the part, specify the opsgenie api key introduced in the previous article. When registering in cron so that it starts automatically when the OS starts, it is recommended to add it to cron as follows, for example.

$ crontab -e
@reboot cd path-to-module-dir;./abu.py ********-****-****-****-************ >/dev/nul 2>&1

Source code

abu.py


#!/usr/bin/env python
#coding:utf-8


import time
import os
from opsgenie import OpsGenie
from led_deamon import LedDeamon


class Abu(object):
    DOWN = 1
    ERR_UNACKED = 2
    WARN_UNACKED = 4
    ERR_ACKED = 8
    WARN_ACKED = 16
    ERR_NEW = 32
    WARN_NEW = 64
    NORMAL = 0
    ERROR_SOUND = "./204425__jaraxe__alarm-2.wav"
    WARNING_SOUND = "./112860__paulnorthyorks__eighties-synth.wav"

    STATE_MAP = {
        DOWN: {"color": "Magenta", "interval": "0"},
        ERR_UNACKED: {"color": "Red", "interval": "0.5"},
        WARN_UNACKED: {"color": "Yellow", "interval": "4"},
        ERR_ACKED: {"color": "Green", "interval": "4"},
        WARN_ACKED: {"color": "Green", "interval": "8"},
        NORMAL: {"color": "Blue", "interval": "8"}}

    def _state2mode(self, state):
        if state == Abu.NORMAL:
            return Abu.STATE_MAP[Abu.NORMAL]
        for s in (Abu.DOWN, Abu.ERR_UNACKED, Abu.WARN_UNACKED,
                  Abu.ERR_ACKED, Abu.WARN_ACKED):
            if state & s:
                return Abu.STATE_MAP[s]
        else:
            return Abu.STATE_MAP[Abu.NORMAL]
            return None

    def __init__(self, url, api_key):
        self.opsgenie = OpsGenie(url, api_key)

    def _summarize(self, list):
        state = Abu.NORMAL
        if list is None:
            state = Abu.DOWN
        else:
            for l in list:
                if l["error"]:
                    if l["acknowledged"]:
                        state |= Abu.ERR_ACKED
                    else:
                        state |= Abu.ERR_UNACKED
                        if l["new"]:
                            state |= Abu.ERR_NEW
                else:
                    if l["acknowledged"]:
                        state |= Abu.WARN_ACKED
                    else:
                        state |= Abu.WARN_UNACKED
                        if l["new"]:
                            state |= Abu.WARN_NEW
        return state

    def start(self):
        ld = LedDeamon()
        ld.set_mode(self._state2mode(Abu.DOWN))
        ld.start()
        while True:
            alert_list = self.opsgenie.detector()
            # print alert_list
            state = self._summarize(alert_list)
            # print hex(state)
            mode = self._state2mode(state)
            if mode:
                ld.set_mode(mode)
            if state & Abu.ERR_NEW:
                os.system("aplay " + Abu.ERROR_SOUND + "&")
            else:
                if state & Abu.WARN_NEW:
                    os.system("aplay " + Abu.WARNING_SOUND + "&")
            time.sleep(60)

if __name__ == '__main__':
    import sys

    if len(sys.argv) != 2:
        print("Usage: %s 'api-key for your OpsGenie account'." % sys.argv[0])
        print("Example: %s ********-****-****-****-************." % sys.argv[0])
        print("You can get your OpsGenie account at https://www.opsgenie.com.")
        exit()
    apiKey = sys.argv[1]
    a = Abu(apiKey)
    a.start()

Looking back

Python studyers I tried using Raspberry Pi. There are also libraries that are cheap, powerful and easy to use GPIOs, and I found that they are a great match for these uses. There were some problems such as LED color control by PWM, asynchronous processing, handling of state values, OpsGenie cooperation, etc., but fortunately, we were able to find a reasonable solution for each, and we were able to complete it. I did. The "notification lamp" produced this time blends into the atmosphere of the workplace without any discomfort, and is useful in actual operation. If you are interested, please give it a try.

This series concludes with this article, but I'll post it again when I have the next idea.

Recommended Posts

"Honwaka Notification Lamp" on Raspberry Pi Part 2
"Honwaka Notification Lamp" on Raspberry Pi Part 1
"Honwaka Notification Lamp" on Raspberry Pi Part 3
Matrix multiplication on Raspberry Pi GPU (Part 2)
pigpio on Raspberry pi
Cython on Raspberry Pi
Introduced pyenv on Raspberry Pi
Use NeoPixel on Raspberry Pi
Install OpenCV4 on Raspberry Pi 3
Install TensorFlow 1.15.0 on Raspberry Pi
Testing uart communication on Raspberry Pi
raspberry pi 1 model b, node-red part 17
MQTT on Raspberry Pi and Mac
raspberry pi 4 centos7 install on docker
Install ghoto2 on Raspberry Pi (memo)
Try using ArUco on Raspberry Pi
OpenCV installation procedure on Raspberry Pi
Power on / off Raspberry pi on Arduino
Detect switch status on Raspberry Pi 3
Install OpenMedia Vault 5 on Raspberry Pi 4
L Chika on Raspberry Pi C #
Build wxPython on Ubuntu 20.04 on raspberry pi 4
Phone notification when surveillance camera motion is detected on Raspberry Pi
Detect "brightness" using python on Raspberry Pi 3!
Enable UART + serial communication on Raspberry Pi
Accelerate Deep Learning on Raspberry Pi 4 CPU
Set swap space on Ubuntu on Raspberry Pi
Programming normally with Node-RED programming on Raspberry Pi 3
Use the Grove sensor on the Raspberry Pi
Install 64-bit OS (bate) on Raspberry Pi
Install docker-compose on 64-bit Raspberry Pi OS
Run servomotor on Raspberry Pi 3 using python
Working with sensors on Mathematica on Raspberry Pi
Build OpenCV-Python environment on Raspberry Pi B +
Detect temperature using python on Raspberry Pi 3!
Mount Windows shared folder on Raspberry Pi
How to install NumPy on Raspberry Pi
I installed OpenCV-Python on my Raspberry Pi
Working with GPS on Raspberry Pi 3 Python
Make a thermometer with Raspberry Pi and make it visible on the browser Part 3
Easy Raspberry Pi GUI App Development Beginner Part 1
Why detectMultiScale () is slow on Raspberry Pi B +
Detect slide switches using python on Raspberry Pi 3!
Build a Django environment on Raspberry Pi (MySQL)
Try using a QR code on a Raspberry Pi
Detect magnet switches using python on Raspberry Pi 3!
Raspberry Pi backup
Enjoy electronic work with GPIO on Raspberry Pi
Power on / off your PC with raspberry pi
Easy Raspberry Pi GUI App Development Beginner Part 2
Use Grove-Temperature & Humidity Sensor (DHT11) on Raspberry Pi
Make DHT11 available on Raspberry Pi + python (memo)
Beginning cross-compilation for Raspberry Pi Zero on Ubuntu
Sound the buzzer using python on Raspberry Pi 3!
Create a visitor notification system using Raspberry Pi
Play with your Ubuntu desktop on your Raspberry Pi 4
Display CPU temperature every 5 seconds on Raspberry Pi 4
Introduced Ceph on Kubernetes on Raspberry Pi 4B (ARM64)
Connect to MySQL with Python on Raspberry Pi
Build a Python development environment on Raspberry Pi
Build an Arch Linux environment on Raspberry Pi