Здравствуйте, меня зовут Максим и я сотрудник IT отдела одной торговой компании. Как то раз мы с коллегами решили, что нам не хватает в отделе светофора. Мы пока не понимали зачем именно он нам нужен, но непреодолимое "хочу" одолевало нас...
И вот спустя пару минут мы уже ищем его на просторах интернета. Требования были такими: настоящий, дешевый, тёплый-ламповый, можно б/у. Нашли быстро, заказали, оплатили, дождались. Получили, распаковали, разобрали, отмыли.Собрали. Поставили лампочки. Включили все сразу. В кабинете потеплело.
Задумались куда его приспособить и как им управлять.
В тумбочке стола нашёлся Ke-USB24R — по своей сути USB-модуль с четырьмя реле, которыми можно управлять с компьютера, записывая данные в виртуальный COM-порт, плюс 18 IO линий и четыре 10-и битных АЦП. Подробности и инструкции на сайте производителя http://www.kernelchip.ru/Ke-USB24R.php
Подключил через него светофор. Получилось поморгать лампочками отдельно, используя ПО с сайта производителя.
Дальше решили, что неплохо бы прикрутить светофор к системе мониторинга zabbix, которая работает в компании. Светофор должен сигнализировать о проблемах в зависимости от важности сработавших триггеров:
- чрезвычайная и важная — красный,
- средняя и предупреждение — жёлтый,
- когда проблема решается — должен сработать зелёный сигнал и погаснуть жёлтый или красный.
Написал скрипт на PowerShell. Логика работы такова:
- На вход получает три параметра
- числовой идентификатор триггера
- статус триггера (0 — ОК, 1 — Problem)
- числовая важность триггера
- Если пришёл триггер с проблемой — добавляем его в массив, если пришёл триггер с решением проблемы — удаляем его из массива
- Исходя из того какие значения триггеров есть в массиве включается тот или иной сигнал светофора.
Массив триггеров с идентификаторами проблемных триггеров хранится в xml файле.
Я не программист. Сделал как знал и умел, вроде работает без сбоев. Если есть замечания выслушаю и постараюсь учесть в будущем.
#идентификатор триггера
$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:\Users\User\Desktop\DB_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:\Users\User\Desktop\DB_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.
А в Операциях указал "Выполнить удалённые команды на узлах в сети". Удалённый узел — это компьютер с запущенным zabbix-агентом:
powershell.exe -File C:\Users\User\Desktop\traffic_lights.ps1 {TRIGGER.ID} {TRIGGER.VALUE} {TRIGGER.NSEVERITY}
Таким образом при срабатывании какого-нибудь триггера, выполняется скрипт с нужными параметрами на удалённом компьютере, к которому подключен модуль управления светофором. Загорается или гаснет сигнал.
В итоге получился интересный и функциональный элемент интерьера, очень сильно привлекающий внимание. Приходится отвечать на уйму вопросов типа где мы его взяли и для чего он нам нужен, сколько стоит и так далее. В будущем планирую сделать устройство автономным, уйти от использования компьютера и USB-контроллера. Заменить его каким-нибудь Ethernet-Relay модулем и перенести логику работы на сервер zabbix. Доработать индикацию и повесить его вертикально.
Спасибо за внимание!