ЦИФРОВОЙ USB ТЕРМОДАТЧИК
ODTEMP-1
Маленький размер и лёгкое подключение
Удобный интерфейс и богатый функционал
Множество задач опирается на температуру, как на один из важнейших показателей.
Например, по температуре устройства можно определить режим его работы, по температуре помещения - включить вентиляцию или обогрев.

Цифровой USB термометр ODTEMP-1 позволяет определять температуру окружающей среды и передавать значения в удобном для пользователя виде.

Данные можно считывать, как в графическом виде, так и в текстовом, а также передавать по сети, что делает его удобным участником мира IoT.
Характеристики
1. Интерфейс подключения: USB
2. Шаг измерения температуры: 0.5С
3. Габариты: 13х18х58мм
4. Программа под Win7+/Linux/macOS
5. Возможность передавать показания по сети с помощью управляющей программы.

Содержание
Подробная инструкция с картинками
  • Установка USB термометра ODTEMP-1
  • ODTEMP-logger (основная программа)
    odtemp-logger: мини-программа для сохранения логов температуры в файл и/или показа на экране. Работает в графическом и консольном режиме через USB HID интерфейс.
  • Мини-версия программы на технологии PWA (Progressive Web Application) - может работать, как онлайн, так и локально на ПК.
    Проверено на Chromium/Chrome.
  • Основная программа для работы с устройством
  • Подключение к облаку (отдельный сервис, не является частью продукта)
  • Предыдущая версия программы
  • Для случаев, когда драйвер из ОС не заработал
  • Примеры работы с устройством без программ с помощью BASH/BAT-скриптов или Python.
  • Дополнительные материалы: документация на устройства, ссылки на программы.
Установка USB термометра ODTEMP-1
1. Термодатчик устанавливается в USB разъём управляющего ПК.
2. При выборе места установки следует избегать способов подключения, при которых сам датчик нагревается от материнской платы ПК, т.к. это может негативно сказаться на точности показаний.
3. Для работы с устройством доступно кроссплатформенное ПО. Также можно работать с помощью BAT/BASH скриптов.
ODTEMP-logger
Маленькая программа для показа температуры и сохранения логов температуры в файл.
Работает через USB HID интерфейс.
Не требует настроек и драйверов.
Оконный режим программы odtemp-logger
В графическом режиме программа отображает окно для удобного визуального контроля.

Режимы работы определяются параметрами командной строки:
-cli
запуск без GUI
-path string
переопределяет путь записи лога
-period int
период записи в секундах
-silent
не писать лог
Окно вывода консольной программы odtemp-logger
При каждом запуске программы создается новый лог с текущим временем.

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

В Linux, вероятно, понадобится отдельное udev-правило (либо повышение прав для программы).

С версии 1.5S прошивки и 1.1.0 программы можно установить период меньше 2 с (до 0.2).
Пример создания ярлыка с параметрами в Windows
Программа сохраняет данные каждые 60 секунд.
Время можно изменить параметром -period X, где X - время в секундах между запросами.
Например odtemp-logger -period 5 -cli задаст команду на опрос каждые 5 секунд.

На картинке пример создания ярлыка в Windows с параметром программы (выделено синим).
ODTEMP Mini

Online/Offline программа на базе PWA
PWA (Progressive Web Application) - технология, позволяющая веб-страницам работать похожим на программу образом.
Мы разработали небольшую программу для максимальной легкого начала работы с нашим устройством.
С программой можно работать как с браузера, так и оффлайн - установив ее на пк.
Программа доступна на https://odtemp.unitx.pro
Установка программы:
Вид самостоятельной программы:
ODTEMP Monitor
Особенности программы
  • Консольная программа
    Программа запускается из консоли, что позволяет её использовать также в ОС без графического интерфейса и удобно ставить в автозагрузку.
  • Можно запускать как службу в Windows
    Как службу в Windows можно запускать только программы без графического интерфейса.
  • Встроенный веб-сервер
    Для того, чтобы увидеть интерфейс программы, нужно открыть адрес http://localhost:8000 в web-браузере.
    С другого компьютера этой локальной сети можно открыть по адресу http://<ip_компьютера>:8000
  • Встроенный монитор загрузки
    Встроенный монитор для контроля загруженности системы через web-интерфейс.
  • Встроенный облачный клиент
    Встроенный клиент для работы с облачной системой connect.unitx.pro
Перед работой в Windows7 понадобится установить драйвер CDC.
В Windows 8, Windows 10, Linux, macOS установка драйвера не требуется.
Работа в ОС ниже Windows7 не поддерживается.

С большой вероятностью в современных *nix системах для работы с последовательным портом понадобится повышение прав пользователя или настройка прав доступа к устройству.
Установка и работа
Скачайте подходящую версию под свою ОС
2
Узнайте номер COM-порта (для win-систем) или имя устройства (для *nix) своего устройства. Для старых Win-систем может понадобится установка драйвера.
3
В консоли перейдите в папку с программой и запустите её в формате odtemp... /dev/ttyACM0
Где odtemp... - название вашего исполняемого файла (в зависимости от платформы),
/dev/ttyACM0 - название файла устройства или, например, COM3 для Windows.
В *nix системах убедитесь, что у пользователя, запускающего программу, достаточно прав для открытия файла устройства.
На этом всё: в консоль раз в секунду начнет выводиться значение температуры. Если больше ничего не требуется, остальное можно пропустить.
4
Если вам нужен интерфейс для настроек или контроля, то добавьте дополнительно параметр -w
Возможно, в вашей ОС также понадобятся дополнительные права/разрешения для открытия вебсервера.
Откройте web-браузер с адресом http://localhost:8000
Если всё прошло нормально, вы должны увидеть такую страницу:
5
Перед вами страница управления. На ней можно увидеть версию устройства, его состояние. Время работы программы. Температуру термодатчика.
6
Ссылка "Монитор" позволяет открыть страницу на которой можно получить некоторые сведения о загруженности системы (бывает полезно при удаленном контроле).
7
Раздел "Connect" позволяет настроить клиента нашего облачного сервиса Connect.UnitX
Для регистрации не нужно никаких персональных данных. Вы получаете токен, который используется как логин/пароль/идентификатор пользователя.
Сервис не является частью продукта.
8
Чтобы сервис передавал данные в облако, программа должна быть запущена с дополнительным параметром -c. При этом web-интерфейс может быть как включен, так и выключен.
9
Настройки (для платных тарифов):
Имя устройства - имя, как устройство будет отображаться в сервисе.
Оповещения - включить уведомление в Telegram или приложении, при переходе через значение "Значение".
Значение - градусы цельсия.
Период - через какие промежутки времени отправлять в облако данные, в минутах.

В бесплатном тарифе облака можно смотреть только текущее значение.
В платном тарифе: хранение данных и оповещения.

10
При нажатии на ссылку Аккаунт можно перейти на экран своего аккаунта в сервисе.
11
Уведомления в Telegram (для платных тарифов)
1. Подключитесь к боту @connect.unitx
2. Включите бота командой /start
3. Привяжите к своему аккаунту командой
/connect UID, где UID - ваш токен облачного сервиса
4. Командой /now можно смотреть текущее состояние активных (за текущие сутки) датчиков.
5. Автоматические уведомления, согласно настройкам устройства, также будут приходить боту.
IOT Sensor Monitor (скачать)
Предыдущая версия программы для odtemp1
Главное окно программы
Получение данных от программы
по сети в JSON
В программы можно включить передачу данных о термодатчиках в JSON формате.
Например, по адресу http://<ip>:34242/json в браузере можно получить данные следующего вида
для ODTEMP-1Ux:
{
    "sensors": [
        {
            "id": "/DS18B20/20323939554B43120010800A",
            "max": 125,
            "min": -55,
            "serial": "20323939554B43120010800A",
            "state": 0,
            "type": "DS18B20",
            "unit": "℃",
            "value": 25.5
        }
    ],
    "timestamp": 1528660156476
}
Для ODTEMP-1Wx:
{
    "sensors": [
        {
            "alias": "TEST-2080-H",
            "id": "/HDC2080/20313337584D430100290008",
            "max": 125,
            "min": -40,
            "serial": "20313337584D430100290008",
            "state": 0,
            "type": "HDC2080",
            "unit": "℃",
            "value": 28.13
        },
        {
            "alias": "TEST-2080-H",
            "id": "/HDC2080_RH/20313337584D430100290008",
            "max": 100,
            "min": 0,
            "serial": "20313337584D430100290008",
            "state": 2,
            "type": "HDC2080_RH",
            "unit": "%",
            "value": 26.86
        }
    ],
    "timestamp": 1539980752561,
    "version": "1.0.1"
}
CDC драйвер
В Windows 8, Windows 10, Linux, macOS установка CDC драйвера не требуется.
Перед работой с уcтройством в Windows7 понадобится установить драйвер CDC.

Если вы всё же хотите запустить устройство на другом оборудовании - напишите нам и мы расскажем, возможно ли это сделать!

Установка драйвера CDC для Windows7
Данная мини-инструкция показывает основные моменты установки драйвера виртуального COM-порта под Windows7. Версии Windows ниже 7 драйвером не поддерживаются.
Драйвер можно скачать по ссылке.
Скрипты и примеры
Для тех, кто хочет использовать текстовый протокол для интеграции со своим программным обеспечением
Получить температуру
Однократно получить значение темературы
Запрос:
~G

Ответ:
 ~G25.0
где 25.0 - текущая температуры термодатчика
Задать передачу температуры по таймеру
Термодатчик будет передавать значение температуры раз в 1000 мс (раз 1 секунду).
Настройки режима работы сохраняются во внутренней памяти.
Запрос:
~W1000

Ответ:
~F1000
~G24.0
~G24.0
...
Передача параметров с помощью echo
Пример загрузки параметров с помощью echo в Linux
echo "~W1000" > /dev/ttyACM0
Передача данных о температуре по сети в UDP формате (Linux)
В режиме автоматической передачи значений термодатчиком
cat USBPORT | sed 's/~G//' | socat - udp-sendto:127.0.0.1:5000
Однострочный скрипт для выполнения каких-либо действий при превышении температуры (Linux)
В режиме автоматической передачи значений термодатчиком. Сравнивается с 30 градусами.
cat /dev/ttyACM1 | sed 's/~G//' | { read temp; if [[ -z "$temp" ]]; then echo 'No data'; elif [[ $(echo "$temp>30" | bc -l) -ne 0 ]]; then echo 'Overtemp'; else echo 'Normal'; fi; }
Однострочный скрипт для выполнения каких-либо действий при превышении температуры (Windows Powershell)
В режиме автоматической передачи значений термодатчиком. Сравнивается с 30 градусами.
$port = new-object System.IO.Ports.SerialPort COM8, 9600, None, 8, One; $port.Open(); $data = $port.ReadLine(); $port.Close(); if (-not $data) { "no data" } else { $temp = $data -replace '~G', ''; if ([float]$temp -gt 30) { "Overtemp" } else { "Normal" } }
Остановить автоматическую передачу температуры
Термодатчик перестанет передавать значение температуры раз в ХХ мс и будет передавать только по запросу ~G.
Настройки режима работы сохраняются во внутренней памяти.
Запрос:
~W0

Ответ:
~F0
Работа с устройством по сети через socat
Пример socat tcp-сервера, который подключается к порту ACM0 устройства, обеспечивает прозрачную передачу данных и не требует установки автоматического режима
socat -d -d TCP4-LISTEN:6000,fork /dev/ttyACM0,raw,echo=0
Получение температуры
с помощью Python
Пример программы для получения температуры от датчика. Не забудьте установить pyserial.
import serial
import time
import argparse
import datetime  # Добавляем модуль для работы с датой и временем

# Парсинг аргументов командной строки
parser = argparse.ArgumentParser(description='Опрос ODTEMP-1 командой ~G')
parser.add_argument('--port', required=True, help='Последовательный порт (например, COM3 или /dev/ttyUSB0)')
parser.add_argument('--timeout', type=float, default=1.0, help='Время между опросами в секундах (по умолчанию: 1.0)')
args = parser.parse_args()

# Открытие соединения
ser = serial.Serial(args.port, 115200, timeout=1)

try:
    print(f"Подключено к {args.port}")
    print(f"Опрос каждые {args.timeout} секунд")
    
    while True:
        # Получаем текущую дату и время
        current_time = datetime.datetime.now().strftime("%d-%m-%Y %H:%M:%S")
        
        ser.write(b"~G")
        # Чтение ответа
        data = ser.readline().decode('utf-8', errors='replace').strip()
        if data.startswith('~GE'):
            print(f"[{current_time}] Ошибка получения данных с сенсора")
        elif data.startswith('~G'):
            print(f"[{current_time}] Температура: {float(data[2:])}")
        else:
            print(f"[{current_time}] Неожиданный ответ: {data}")
        # Ожидание перед следующим опросом
        time.sleep(args.timeout)
except KeyboardInterrupt:
    print("\nОпрос остановлен пользователем")
except Exception as e:
    print(f"Ошибка: {e}")
finally:
    # Закрытие соединения
    ser.close()
    print("Соединение закрыто")
Python-аналог консольной программы odtemp-logger

Пример небольшой программы для сохранения данных в лог, который работает с интерфейсом HID вместо CDC.

Для работы нужен python3 и библиотека hidapi.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import hid
import time
import sys
import re

# Константы устройства
OD_VID = 0x0483
OD_IOT_PID = 0xA26A

# HID report IDs
HID_DATA_REPORT_ID   = 1
HID_EVENT_REPORT_ID  = 2
HID_FW_REPORT_ID     = 3
HID_CMD_REPORT_ID    = 4
HID_CMD_REPORT_SIZE  = 7

def available_devices():
    """
    Функция возвращает список найденных HID-устройств.
    """
    devices = hid.enumerate(OD_VID, OD_IOT_PID)
    found_devices = []
    iot_product = re.compile(r"IOT ([^\s]+)(?: HID)?")

    for d in devices:
        vendor = d.get('manufacturer_string', '')
        product = d.get('product_string', '')
        serial = d.get('serial_number', '')
        print(f"Найдено устройство: {vendor} / {product} @ {serial}")

        if vendor == "Open Development" and iot_product.match(product):
            match = iot_product.match(product)
            device_type = match.group(1)
            if not serial:
                serial = "S/N"
            found_devices.append((device_type, serial))
        else:
            print("Устройство не соответствует критериям OD HID")

    return found_devices

def open_device(serial_number):
    """
    Открывает устройство с заданным серийным номером.
    """
    try:
        dev = hid.device()
        
        devices = hid.enumerate(OD_VID, OD_IOT_PID)
        if not devices:
            print("Устройства не найдены")
            sys.exit(0)
            
        device_path = None
        for d in devices:
            if d.get('serial_number', '') == serial_number:
                device_path = d['path']
                break
                
        if device_path is None:
            print(f"Устройство с серийным номером {serial_number} не найдено, используем первое доступное")
            device_path = devices[0]['path']
            
        # Open the device using its path
        dev.open_path(device_path)
        
        return dev
    except Exception as e:
        # просто пытаемся вернуть первый попавшийся вариант
        return hid.Device(OD_VID, OD_IOT_PID)

def process_data_report(data):
    if len(data) >= 2:
        value = int.from_bytes(data[:2], byteorder='little', signed=False)
        return value / 100.0
    return None

def process_custom_command(cmd, payload):
    print(f"Получена нестандартная команда {cmd} с полезными данными: {payload.hex()}")

def sensor_state_changed(state):
    """
    Обработка изменения состояния сенсора (HID_EVENT_REPORT_ID).
    """
    print(f"Изменение состояния сенсора: {state}")

def main():
    # Поиск доступных устройств
    devices = available_devices()
    if not devices:
        print("Устройства не найдены")
        sys.exit(0)

    device_type, serial = devices[0]
    print(f"\nОткрываем устройство: {device_type} ({serial})")
    dev = open_device(serial)

    try:
        last_data_time = time.time()  # Время последнего полученного отчета
        timeout_period = 10  # Таймаут в секундах
        
        while True:
            # Пытаемся прочитать отчет (до 64 байт)
            try:
                report = dev.read(64, timeout=100)  # либо timeout_ms в зависимости от библиотеки
                if report:
                    report = bytes(report)
                    report_id = report[0]
                    last_data_time = time.time()  # Обновляем время последних данных
                    
                    if report_id == HID_DATA_REPORT_ID:
                        # Отчет с данными: остальные байты содержат полезную нагрузку
                        data_value = process_data_report(report[1:])
                        print(f"Температура: {data_value}")

                    elif report_id == HID_EVENT_REPORT_ID:
                        # Отчет об изменении состояния: второй байт – код состояния
                        state_value = report[1]
                        sensor_state_changed(state_value)

                    elif report_id == HID_FW_REPORT_ID:
                        # Отчет с версией прошивки:
                        # Второй байт содержит длину строки, начиная с третьего байта – сама строка
                        length = report[1]
                        firmware_version = report[2:2+length].decode('latin1')
                        print(f"[FW] Версия прошивки: {firmware_version}")

                    elif report_id == HID_CMD_REPORT_ID:
                        process_custom_command(report[1], report[2:])
                    else:
                        print(f"Неизвестный report id: {report_id}")
                
                # Проверяем таймаут по времени с момента последних данных
                if time.time() - last_data_time > timeout_period:
                    print(f"Устройство не отвечает более {timeout_period} секунд")
                    break
                    
            except IOError as e:
                print(f"Ошибка чтения: {e}")
                # Не выходим при ошибке чтения, продолжаем попытки
                time.sleep(0.5)
                
    except KeyboardInterrupt:
        print("Прерывание пользователем")
    finally:
        dev.close()
        print("Устройство закрыто")

if __name__ == '__main__':
    main()

Обновление устройства
Для перевода в режим загрузчика нужно подключиться по CDC интерфейсу и отправить команду "~D".
После чего запустить загрузчик и далее по инструкции.
Дополнительные ресуры
  1. Техподдержка,
  2. Инструкция на устройство в pdf.
  3. Прошивка версии 1.5 (если нужен опрос чаще, чем раз 2 секунды).
  4. Инструкция по обновлению.