Ещё один светофор в офисе

в 12:35, , рубрики: powershell, zabbix, Офисы IT-компаний, Производство и разработка электроники

Здравствуйте, меня зовут Максим и я сотрудник IT отдела одной торговой компании. Как то раз мы с коллегами решили, что нам не хватает в отделе светофора. Мы пока не понимали зачем именно он нам нужен, но непреодолимое "хочу" одолевало нас...

image

И вот спустя пару минут мы уже ищем его на просторах интернета. Требования были такими: настоящий, дешевый, тёплый-ламповый, можно б/у. Нашли быстро, заказали, оплатили, дождались. Получили, распаковали, разобрали, отмыли.Собрали. Поставили лампочки. Включили все сразу. В кабинете потеплело.

Задумались куда его приспособить и как им управлять.

В тумбочке стола нашёлся Ke-USB24R — по своей сути USB-модуль с четырьмя реле, которыми можно управлять с компьютера, записывая данные в виртуальный COM-порт, плюс 18 IO линий и четыре 10-и битных АЦП. Подробности и инструкции на сайте производителя http://www.kernelchip.ru/Ke-USB24R.php

Подключил через него светофор. Получилось поморгать лампочками отдельно, используя ПО с сайта производителя.

Дальше решили, что неплохо бы прикрутить светофор к системе мониторинга zabbix, которая работает в компании. Светофор должен сигнализировать о проблемах в зависимости от важности сработавших триггеров:

  • чрезвычайная и важная — красный,
  • средняя и предупреждение — жёлтый,
  • когда проблема решается — должен сработать зелёный сигнал и погаснуть жёлтый или красный.

Написал скрипт на PowerShell. Логика работы такова:

  1. На вход получает три параметра
    • числовой идентификатор триггера
    • статус триггера (0 — ОК, 1 — Problem)
    • числовая важность триггера
  2. Если пришёл триггер с проблемой — добавляем его в массив, если пришёл триггер с решением проблемы — удаляем его из массива
  3. Исходя из того какие значения триггеров есть в массиве включается тот или иной сигнал светофора.

Массив триггеров с идентификаторами проблемных триггеров хранится в xml файле.

Я не программист. Сделал как знал и умел, вроде работает без сбоев. Если есть замечания выслушаю и постараюсь учесть в будущем.

Код скрипта traffic_lights.ps1

#идентификатор триггера
$trigger_id = $args[0] 
#0 - ОК, 1 - Problem
$trigger_status = $args[1] 
# Числовая важность триггера. 0 - Не классифицировано, 1 - Информация, 2 - Предупреждение, 3 - Средняя, 4 - Высокая, 5 - Чрезвычайная.
$trigger_nsev = $args[2] 

#номера реле к которым подключены сигналы
$red = 1
$yellow = 2
$green = 3

#пустой ассоциативный массив триггеров Key - ID триггера, Value - Числовая важность триггера
$triggers=@{}

#читаем файл с ассоциативным массивом триггеров
$triggers = Import-Clixml -Path C:UsersUserDesktopDB_traffic_lights.xml

#если пришёл триггер с проблемой
if ($trigger_status -eq 1)
    {
        #проверяем нет ли его массиве и тогда добавляем
        if (!$triggers.ContainsKey($trigger_id))
            {
                #добавляем в массив триггеров
                $triggers.Add($trigger_id,$trigger_nsev)
            }
    }
    #если пришёл триггер с решением проблемы
    else
    {
        #проверяем есть ли он в массиве и тогда удаляем
        if ($triggers.ContainsKey($trigger_id))
            {
                #удаляем запись и массива триггеров
                $triggers.Remove($trigger_id)
            }
    }

#записываем файл с ассоциативным массивом триггеров
$triggers | Export-Clixml -Path C:UsersUserDesktopDB_traffic_lights.xml

#по-умолчаню все сигналы выключены
$red_turn_on = $false
$yellow_turn_on = $false

#перебираем массив триггеров
foreach ($trigger in $triggers)
{
        switch ($trigger.Values)
        {
            #0 - Не классифицировано
            0 {  }

            #1 - Информация
            1 {  }

            #2 - Предупреждение
            2 { $yellow_turn_on = $true }

            #3 - Средняя
            3 { $yellow_turn_on = $true }

            #4 - Высокая
            4 { $red_turn_on = $true }

            #5 - Чрезвычайная
            5 { $red_turn_on = $true }
        }
}

#[System.IO.Ports.SerialPort]::getportnames()
$port = New-Object System.IO.Ports.SerialPort
$port.PortName = 'COM4'
$port.BaudRate = '9600'
$port.Parity = "None"
$port.Handshake = "None"
$port.DataBits = 8
$port.StopBits = 1
$port.ReadTimeout = 500
$port.WriteTimeout = 500
$port.DtrEnable = $true
$port.RtsEnable = $true

$port.Open()

if ($port.IsOpen -eq $true)
    {
        #если пришёл триггер со статусом ОК
        if($trigger_status -eq "0")
        {
                #выключаем красный и жёлтый
                $command = '$KE,REL,' + $red + ',0'+"`r"
                $port.WriteLine($command)
                $command = '$KE,REL,' + $yellow + ',0'+"`r"
                $port.WriteLine($command)         

                #дважды моргаем зелёным
                $command = '$KE,REL,' + $green + ',1'+"`r"
                $port.WriteLine($command)
                Start-Sleep -Milliseconds 300

                $command = '$KE,REL,' + $green + ',0'+"`r"
                $port.WriteLine($command)
                Start-Sleep -Milliseconds 300

                $command = '$KE,REL,' + $green + ',1'+"`r"
                $port.WriteLine($command)
                Start-Sleep -Milliseconds 300

                $command = '$KE,REL,' + $green + ',0'+"`r"
                $port.WriteLine($command)
                Start-Sleep -Milliseconds 300
        }

        #если нужно включить красный
        if ($red_turn_on)
            {
                $command = '$KE,REL,' + $red + ',1'+"`r"
                $port.WriteLine($command)
            }

        #если нужно включить жёлтый
        if ($yellow_turn_on)
            {
                $command = '$KE,REL,' + $yellow + ',1'+"`r"
                $port.WriteLine($command)
            }
    }   

$port.Close()

В настройках zabbix-сервера я добавил действие (Настройка -> Действия), в котором в условиях указал: Значение триггера = ПРОБЛЕМА, Значение триггера = OK.

Скриншот

image

А в Операциях указал "Выполнить удалённые команды на узлах в сети". Удалённый узел — это компьютер с запущенным zabbix-агентом:

powershell.exe -File C:UsersUserDesktoptraffic_lights.ps1 {TRIGGER.ID} {TRIGGER.VALUE} {TRIGGER.NSEVERITY}

Скриншот

image

Таким образом при срабатывании какого-нибудь триггера, выполняется скрипт с нужными параметрами на удалённом компьютере, к которому подключен модуль управления светофором. Загорается или гаснет сигнал.

В итоге получился интересный и функциональный элемент интерьера, очень сильно привлекающий внимание. Приходится отвечать на уйму вопросов типа где мы его взяли и для чего он нам нужен, сколько стоит и так далее. В будущем планирую сделать устройство автономным, уйти от использования компьютера и USB-контроллера. Заменить его каким-нибудь Ethernet-Relay модулем и перенести логику работы на сервер zabbix. Доработать индикацию и повесить его вертикально.

Спасибо за внимание!

Автор: tonny_bennet

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js