Здравствуйте, меня зовут Максим и я сотрудник 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. Доработать индикацию и повесить его вертикально.
Спасибо за внимание!