@echo off
SET portname=COM12
:loop
set /p x="~U" <nul >\\.\%portname%
ping -n 2 127.0.0.1 > nul
goto loop
#!/bin/bash
PORT=/dev/ttyACM0
while true
do
echo -n "~U" > $PORT
sleep 1
done
@echo off
SET hostname=ya.ru
SET portname=COM12
:loop
ping -n 1 -l 4 -w 1000 %hostname% >nul
if %errorlevel%==0 set /p x="~U" <nul >\\.\%portname%
ping -n 2 127.0.0.1 > nul
goto loop
#!/usr/bin/env bash
HOST="ya.ru"
PORT=/dev/ttyACM0
while true
do
if ping -c 1 $HOST; then
echo -n "~U" > $PORT
fi
sleep 3
done
#!/usr/bin/env bash
PORT=/dev/ttyACM0
PROCESS=crond
if [ ! -z "$1" ];then
PROCESS="$1"
echo "Monitor $PROCESS"
fi
while true; do
if pgrep "$PROCESS" > /dev/null; then
echo -n "~U" > $PORT
fi
sleep 3
done
#!/usr/bin/env bash
PORT=/dev/ttyACM0
URL=ya.ru
PROCESS=crond
while getopts ":ha:p:" opt; do
case ${opt} in
a)
URL=$OPTARG
;;
p)
PROCESS=$OPTARG
;;
h)
echo "Usage: $0 -a <url> -p <process>" 1>&2
exit 1
;;
\?)
echo "Invalid option: -$OPTARG" 1>&2
exit 1
;;
esac
done
echo "Ping $URL"
echo "Monitor $PROCESS"
while true; do
ping -n -c 1 -w 1 "$URL" 2>/dev/null 1>&2 && pgrep "$PROCESS" 2>/dev/null 1>&2 && echo -n "~U" > $PORT
sleep 3
done
#!/bin/bash
# Путь к последовательному порту (измените при необходимости)
SERIAL_PORT="/dev/ttyACM0"
BAUD_RATE="9600"
# Время ожидания ответа в секундах, после которого будет выполнено "действие"
N=30
# Команды для отправки и ожидаемого ответа
COMMAND="~U"
EXPECTED_RESPONSE="~A"
# ----------------------------
# Обработка сигналов для корректного завершения
# ----------------------------
cleanup() {
echo "$(date +"%Y-%m-%d %H:%M:%S") - Завершение работы скрипта."
exec 3<&-
exit 0
}
# Установка ловушек на сигналы
trap cleanup SIGINT SIGTERM EXIT
# ----------------------------
# Функция инициализации последовательного порта
# ----------------------------
init_serial_port() {
echo "$(date +"%Y-%m-%d %H:%M:%S") - Настройка последовательного порта $SERIAL_PORT с скоростью $BAUD_RATE."
stty -F "$SERIAL_PORT" "$BAUD_RATE" cs8 -cstopb -parenb -ixon -ixoff -icanon -echo
if [[ $? -ne 0 ]]; then
echo "$(date +"%Y-%m-%d %H:%M:%S") - Не удалось настроить последовательный порт $SERIAL_PORT."
exit 1
fi
# Открытие последовательного порта на FD 3
exec 3< "$SERIAL_PORT"
}
# ----------------------------
# Функция действия при отсутствии ответа
# ----------------------------
action() {
echo "$(date +"%Y-%m-%d %H:%M:%S") - Ответ не получен в течение $N секунд. Выполнение действия."
# Здесь можно определить необходимое действие.
# sudo shutdown -h now
}
# ----------------------------
# Функция основной логики
# ----------------------------
main() {
# Инициализация времени последнего успешного ответа
last_response_time=$(date +%s)
while true; do
# Отправка команды в последовательный порт
echo -ne "$COMMAND" > "$SERIAL_PORT"
echo "$(date +"%Y-%m-%d %H:%M:%S") - Отправлена команда: $COMMAND"
# Переменная для хранения полученного ответа
RESPONSE=""
# Запуск таймера для ожидания ответа до 1 секунды
RESPONSE_START_TIME=$(date +%s%N) # Текущее время в наносекундах
while true; do
# Текущее время
CURRENT_TIME_NS=$(date +%s%N)
ELAPSED_NS=$(( CURRENT_TIME_NS - RESPONSE_START_TIME ))
# Проверка, прошло ли 1 секунда (1,000,000,000 наносекунд)
if (( ELAPSED_NS >= 1000000000 )); then
break
fi
# Чтение одного символа из последовательного порта с небольшим таймаутом через FD 3
if read -r -n1 -t 0.1 CHAR <&3; then
RESPONSE+="$CHAR"
# Проверка, содержит ли накопленный буфер ожидаемый ответ
if [[ "$RESPONSE" == *"$EXPECTED_RESPONSE"* ]]; then
echo "$(date +"%Y-%m-%d %H:%M:%S") - Получен ожидаемый ответ: $EXPECTED_RESPONSE"
last_response_time=$(date +%s)
break
fi
# Ограничение размера буфера для предотвращения переполнения
if (( ${#RESPONSE} > 10 )); then
RESPONSE="${RESPONSE: -10}"
fi
fi
done
# Проверка, прошло ли N секунд с последнего успешного ответа
CURRENT_TIME=$(date +%s)
ELAPSED=$(( CURRENT_TIME - last_response_time ))
if (( ELAPSED >= N )); then
action
# После выполнения действия (например, выключение), скрипт завершится
# Если действие не завершает скрипт, можно сбросить last_response_time здесь
last_response_time=$(date +%s)
else
echo "$(date +"%Y-%m-%d %H:%M:%S") - Последний успешный ответ был $ELAPSED секунд назад."
fi
# Ожидание 1 секунды перед следующей отправкой команды
sleep 1
done
}
# ----------------------------
# Главная логика скрипта
# ----------------------------
# Проверка наличия прав на доступ к последовательному порту
if [[ ! -r "$SERIAL_PORT" || ! -w "$SERIAL_PORT" ]]; then
echo "$(date +"%Y-%m-%d %H:%M:%S") - Нет прав на доступ к последовательному порту $SERIAL_PORT."
exit 1
fi
# Инициализация последовательного порта
init_serial_port
echo "$(date +"%Y-%m-%d %H:%M:%S") - Скрипт запущен. Отправка команды '$COMMAND' каждые 1 секунду с ожиданием ответа '$EXPECTED_RESPONSE' в течение $N секунд."
# Запуск основной функции
main
from time import sleep
import serial
port = '/dev/tty.usbmodem14201'
ser = serial.Serial(port)
while True:
ser.write(b'~G')
ser_data = ser.readline()
if ser_data:
data = ser_data.decode("utf-8")
if data.startswith('~G'):
try:
print('Temperature is {0}'.format(int(data[2:])/10))
except ValueError:
print("Error")
sleep(1)
#!/usr/bin/env python3
import hid
from time import sleep
from argparse import ArgumentParser
# Определение команд для отправки на устройство
COMMANDS = {
'reload': 1, # HID_RELOAD
'reboot': 2, # HID_REBOOT
'hreboot': 3, # HID_HREBOOT
'shut': 4, # HID_SHUT
'test': 5, # HID_TEST
'mreboot': 6, # HID_MREBOOT
'mhreboot': 7, # HID_MHREBOOT
'ch1_hi': 8, # HID_CH1_HI
'ch1_low': 9, # HID_CH1_LOW
'ch2_hi': 10, # HID_CH2_HI
'ch2_low': 11, # HID_CH2_LOW
'cht_hi': 12, # HID_CHT_HI
'cht_low': 13, # HID_CHT_LOW
'led_g_off': 14, # HID_LED_G_OFF
'led_g_on': 15, # HID_LED_G_ON
'tim_off': 16, # HID_TIM_OFF
'tim_on': 17, # HID_TIM_ON
'boot_sdfu': 18, # HID_BOOT_SDFU
'boot_udfu': 19, # HID_BOOT_UDFU
}
def run(period=3):
"""
Функция, реализующая бесконечную отправку пингов (команда HID_RELOAD)
с заданным интервалом.
"""
hd = hid.Device(0x0483, 0xa26d)
print('Opened HID')
try:
# По умолчанию отправляется команда HID_RELOAD (код 1)
report = b'\x01\x01'
while True:
if hd.write(report) != 2:
raise RuntimeError('IO error')
print('Pinged')
sleep(period)
except Exception as e:
print(f'HID exception {e} ({type(e)})')
finally:
try:
hd.close()
except Exception:
pass
def send_command(command_name):
"""
Отправка одиночной команды на устройство.
Аргумент command_name – строка (например, 'reboot', 'shut', 'test' и т.д.),
которая преобразуется в числовой код по словарю COMMANDS.
"""
cmd_code = COMMANDS.get(command_name.lower())
if not cmd_code:
raise ValueError(f'Неизвестная команда: {command_name}')
report = bytes([0x01, cmd_code])
hd = hid.Device(0x0483, 0xa26d)
print('Opened HID')
try:
if hd.write(report) != 2:
raise RuntimeError('IO error')
print(f"Команда '{command_name}' (код {cmd_code}) успешно отправлена")
except Exception as e:
print(f'HID exception {e} ({type(e)})')
finally:
try:
hd.close()
except Exception:
pass
def read_channel():
"""
Считывает значения каналов с устройства HID, включая канал 3.
Предполагается, что устройство возвращает отчёт из 17 байт, где:
- байт 0 – идентификатор отчёта (ожидается 4, HID_ID_DATA),
- байт 1 – значение канала 1,
- байт 2 – значение канала 2.
Для устройств Pro (у которых значение байта 2 не равно 0xFF)
байт 3 содержит тип канала 3, а байты 4–6 – данные канала 3.
"""
hd = hid.Device(0x0483, 0xa26d)
print("Opened HID для чтения данных")
try:
# Получаем отчёт с report_id = 4 и длиной 17 байт
report = hd.get_feature_report(4, 17)
if len(report) != 17:
print(f"Ошибка: получен отчёт неверной длины: {len(report)} байт")
return
# Разбор полученного отчёта
# report[0] – report_id (ожидается 4)
ch1 = report[1]
ch2 = report[2]
print(f"Канал 1: {ch1}")
print(f"Канал 2: {ch2}")
if ch2 == 0xFF:
print("Lite устройство. Канал 3 недоступен.")
else:
ch3_type = report[3]
# Определяем тип канала 3.
ODC_WDGPRO2_CHANNELSETTINGS_TEMP_OFF = 0 # канал выключен
ODC_WDGPRO2_CHANNELSETTINGS_TEMP_INPUT = 1 # входной режим
ODC_WDGPRO2_CHANNELSETTINGS_TEMP_OUTPUT = 2 # выходной режим
ODC_WDGPRO2_CHANNELSETTINGS_TEMP_TEMP = 3 # температурный режим
if ch3_type == ODC_WDGPRO2_CHANNELSETTINGS_TEMP_INPUT:
ch3_val = report[4]
print(f"Канал 3 (INPUT): {ch3_val}")
elif ch3_type == ODC_WDGPRO2_CHANNELSETTINGS_TEMP_OUTPUT:
ch3_val = report[4]
print(f"Канал 3 (OUTPUT): {ch3_val}")
elif ch3_type == ODC_WDGPRO2_CHANNELSETTINGS_TEMP_TEMP:
if report[4] == 0xFF:
print("Канал 3 (TEMPERATURE): n/a")
else:
temp_int = int.from_bytes(report[4:5], byteorder='little', signed=True)
temp_frac = (report[6] << 8) | report[5]
temperature = temp_int + (temp_frac / 10000.0)
print(f"Канал 3 (TEMPERATURE): {temperature:.2f}°C")
else:
print("Канал 3: не используется или неизвестный режим.")
except Exception as e:
print(f"HID exception при чтении канала: {e} ({type(e)})")
finally:
try:
hd.close()
except Exception:
pass
if __name__ == '__main__':
parser = ArgumentParser()
parser.add_argument('-s', '--sleep',
default=3, type=float,
help='Интервал пинга (секунды)')
parser.add_argument('-c', '--command',
default=None,
help='Отправить одиночную команду (например, reboot, shut, test и т.д.)')
parser.add_argument('-r', '--read', action='store_true',
help='Считать и вывести значения каналов, включая канал 3')
args = parser.parse_args()
if args.command:
send_command(args.command)
elif args.read:
read_channel()
else:
run(period=(args.sleep or 3))