Тонкий клиент vs Orange Pi +16





Это не прямое сравнение, а скорее опыт дилетанта на примере двух одноплатных компьютеров. Вообще мой дилетантский стаж большой как по отношению к компьютерам, так и к электронике.

Что касается электроники, то тянется он с времен СССР, когда я еще школьником, посещал радиотехнический кружок. Потом уже позже добавились компьютеры. Так на лабораторных довелось опробовать аналоговую вычислительную машину. Как она сохранилась непонятно, в то время уже продавались электронные калькуляторы.

Потом познакомился с СМ ЭВМ и с совместимыми с IBM XT компьютерами. На своем дилетантском уровне испробовал различные языки программирования Фортран, Паскаль, Си и др. Сейчас остановился на Python, наверно потому что человек ленив по природе, а Python способствует ленивому программированию или вернее дает возможность ленивому программировать.

Вернемся к теме. Начало истории банальное, на очередной распродаже был куплен Orange Pi PC (OPi). Опробован на простеньких программах и потом лежал без дела. Тут случилась COVID пандемия. И как многие, уехал я с семьей на дачу.

В город тем не менее возвращались, особенно после того как на работу стали пускать. На дачу хорошо возвращаться пока лето и тепло, но наступила осень и температура упала. При это желание ездить на дачу, как это было раньше, не пропало. Но приезжать в дом, где всего +5 градусов не комфортно. Хорошо бы перед приездом включать электрическое отопление, вот она задача для OPi.

Конечно, можно использовать недельный таймер, чтоб перед выходными включать отопление. А если никто не поедет или приедет раньше? Есть и другие решения, как то: WiFi розетки, GSM розетки и т.п. Все это не очень подходит для нашей конкретной дачи. В дачный сезон, а это до конца октября мобильный интернет скорее мертв чем жив. Да и вообще GSM сигнал слабый, с телефоном надо искать место, чтобы позвонить, а на модем вешать внешнюю антенну.

Таким образом, лучше делать самому. Задача вроде простая, надо подключить к OPi USB модем с антенной и управлять с помощью SMS. Для минимизации усилий стал искать готовое ПО. Попался на глаза «Home Assistant»(HA) и очень удачно, он же написан на Python. На первый взгляд, HA просто то что нужно, там есть всё. Управление по SMS — ерунда, можно развернуть настоящий «умный» дом. Стал знакомится более подробно. Оказалось, для настройки HA знать Python не надо, нужен YAML, что обидно. Не все радужно оказалось и с поддержкой OPi.

Пробный запуск с подключенным датчиком DHT22 показал, что он не работает… Первая мысль, может неисправен, попробовал другой — безрезультатно. Пришлось подключить осциллограф, и смотреть сигналы на DHT22. Обнаружил лишний импульс, который сбивал работу датчика. Стал смотреть исходную программу которая управляет датчиком (библиотека Adafruit). Поправил код, в основном методом тыка, и заработало.

По крайней мере в 30% случаев считывание показаний было удачным. Наверно это неплохо для не Real Time OS, для DHT22 все временные параметры создаются программными задержками. В чем причина, что на OPi датчик не работал? Может особенности архитектуры OPi. У DHT22 свой протокол, а если бы использовал стандартные интерфейсы I2C, SPI и т.п. может проблемы и не было бы. Почему так, что только у меня не работал датчик, не знаю.

В интернете, других жалоб не нашел. Для себя сделал вывод, что используемые в HA библиотеки не всегда подходят для OPi, и «заточены» в основном под Raspberry. Но все же покупать специально Raspberry не стал.

Решил продолжать, и тут случилось у нас жаркое лето 2021 года и OPi не выдержал, хоть и был с радиатором. Что-то случилось с одним из стабилизаторов напряжений. Что же погоревал и стал искать новый компьютер. Даже смотрел на Raspberry, но цена не гуманная. Потом подумал, а зачем покупать эти «фруктово-ягодные» компьютеры, может взять обычный.

На известной площадке где торгуют всяким разным б/у — был куплен Тонкий Клиент (ТК) модель TONK1811 по цене 1200 руб. Габариты несколько больше чем у OPi, но все равно ТК достаточно небольшой.


Что ж мы получаем за эти деньги:
  • Готовый корпус
  • 5 шт. USB2 против 3 шт.
  • Установленный радиатор, пассивное охлаждение
  • Часы реального времени
  • Блок питания
  • ОЗУ 1 Гб
  • Одно-ядерный процессор Atom N270
  • 10/100/1000 Ethernet
  • Интерфейсы — 1 x DVI-I (DB-15) — 1 х PS/2

Из бесполезного… прилагался DOM диск 1Гб с WinXP. WiFi не было, но у меня завалялся модуль, который замечательно подошел. Есть еще SATA — можно подключить SSD до 32Гб. Пока такой по сходной цене не нашел. Поэтому установил OS Debian на USB флэшку. Работает довольно шустро пожалуй даже шустрее OPi.

Может возникнуть резонный вопрос, куда же я воткну датчик DHT22, который я ранее подключал с таким трудом, т. е. где же GPIO? Есть решение — это модуль FT232H (можно купить на Али). Модуль известный, но его в основном используют как мост USB-JTAG. FT232H же может больше, это еще мост USB на I2C, SPI, UART и GPIO.

Библиотеки Python есть готовые у Аdafruit. К сожалению, в HA поддержки нет. Может сейчас уже появилась, я не проверял. Это было последней каплей и решил я с HA расстаться. Мне ж много не надо, напишу все сам на Python. Тем более, что основные «кирпичики» — библиотеки есть. Благодаря распространенности языка оказывается все уже придумано до нас, главное найти. По факту использовал библиотеки Аdafruit и Gammu.

Для начала проверил работоспособность FT232H. Подключал датчики: HTU21d, BMP280, т. е. проверил интерфейсы I2C, SPI — работают. Пробовал адресный светодиод, да и просто светодиод — без проблем. Мне же надо включать внешние устройства — радиаторы отопления, т. е. достаточно GPIO. Для этого взял, по числу потребителей, 4-х канальный радиопередатчик на 433 МГц (TX118SA-4) и к нему приемники с реле.





Приходит сигнал с передатчика реле включается. Проблема в том, что в такой схеме нет обратной связи, т. е. на стороне ТК неизвестно включено или выключено реле. Получил приемник сигнал или нет. Поэтому алгоритм работы решил поменять и дополнил схему сторожевым таймером, на время примерно 7 мин. За основу взял эту схему, найденную в интернете.

image

Теперь в схеме два реле. Первое реле приемника сбрасывает таймер, а реле таймера включает нагрузку.



Нагрузка это радиаторы отопления с мощность около 700 Вт. Реле добыты из сгоревшего ИБП. Передатчик, с интервалом примерно 5 мин, посылает сигнал и взбадривает сторожевой таймер. Если время прошло больше то нагрузка выключается. Питается приемник от монолитного маломощного блока питания на 12В.



Передатчик проверялся на тестовой плате с подключением к FT232H.



Модуль терпелив к 3,3В и 5В.

К сожалению все по времени затянулось и наступила зима. Поездки на дачу прекратились. Необходимость в подогреве отпала. Появилось время добавить еще что то.
Можно, как я уже пробовал, подключить датчик (температура, влажность, давление) и мониторить пространство рядом с ТК, но это мало информативно. Потом вспомнил, что есть у меня погодная станция Oregon WMR88, которая теоретически, может передавать свои данные по USB.



Попытка найти в интернете, что то подходящее на Python не увенчалась успехом. Вернее есть готовые завершенные решения, а так чтоб где то взять python код и вставить себе — нет. Впрочем, оказалось сделать самому не сложно. Для протокол обмена с HID устройствами есть библиотека hid.

Сложнее с протоколом данных самой станции т.к. производитель не раскрывает его, но народ в интернете, что то раскопал, а я воспользовался. Большая часть взята тут.

Правда передача данных очень долгая, чтобы получить информацию со всех датчиков может потребоваться от нескольких минут до десятков. Зато получаю как локальные данные так и с выносных датчиков.

Кроме температуры и влажности есть еще датчики дождя и ветра. Код всей программы не привожу, т. к. это в основном компиляция из примеров к библиотекам. В общем код находится в процессе перманентной модификации, без толковых комментариев. Приведу программу работы с погодной станцией, может кому то пригодится python версия. Код использовался для тестирования работы станции.

Python версия
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Программа считывания данных с погодной станции WMR88
за основу взят код из https://github.com/barnybug-archive/wmr100
@author: jury
"""
import hid
import time
import timeit

def read_wmr88():    
    # Код производителя
    vid = 0x0fde
    pid = 0xca01
    
    try:
        device = hid.device()
        device.open(vid, pid)
        device.set_nonblocking(1)
        # Init
        init = [0x20, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00]
        rw = device.write(bytes(init))
        inp =  [0x01, 0xd0, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00]
        time.sleep(0.05)
        rw = device.write(bytes(inp))
        dat = read_usb(device)
    except IOError as ex:
        device.close()
        print("Ошибка соединения")
    return dat

def read_usb(dev):
    time_out = 10
    print("Read the data")
    dd = []    
    tmi = timeit.default_timer()
    while timeit.default_timer()-tmi < time_out:
        d = dev.read(8,10)
        if len(d) != 0:
            dd.append(d)
            tmi = timeit.default_timer()
        else:
            time.sleep(0.5)
    print("Closing the device")
    dev.close()
    return dd

def parse_data(dat):
    m1 = []
    m2 = []
    m3 = []
    for i in dat:
        for b in i[1:1+i[0]]:
            m1.append(b)
    for i in m1:
        if i == 0xff:
            if len(m2) > 1:
                if sum(m2[:-2]) == (m2[-2] + (m2[-1] << 8)):
                    m3.append(m2)
                    m2 = []
            continue
        else:
            m2.append(i)
    return m3


def get_sensors(dat, full):
    for i in dat:    
        if i[1] == 0x42: # Thermo-Hygrometer (10 bytes)
            t = i[0] >> 4
            battery = t >> 2
            t_trend = t & 0x03
            sensor = i[2] & 0x0f # номер сесора
            st = i[2] >> 4
            h_trend = (st >> 2) & 0x03  # Humidity Trend
            h_trend -= 1
            temp = (i[3] + ((i[4] & 0x0f) << 8)) / 10.0
            if ((i[4] >> 4) == 0x8):
                temp = -temp        
            humidity = i[5]
            dewpoint = (i[6] + ((i[7] & 0x0f) << 8)) / 10.0  # точка росы
            if ((i[7] >> 4) == 0x8):
                dewpoint = -dewpoint  # точка росы
            if sensor == 0:
                weather["Temperature"][sensor] = (temp, dewpoint, trend[t_trend], lev_battery[battery])
                weather["Humidity"][sensor] = (humidity, trend[h_trend])
                full |= 0x01
            else:
                weather["Temperature"][sensor] = (temp, dewpoint, trend[t_trend], lev_battery[battery])
                weather["Humidity"][sensor] = (humidity, trend[h_trend])
                full |= 0x02
            continue
            
        if i[1] == 0x46: # Barometer (6 bytes)
            pressure = (i[2] & 0x0f) + ((i[3] & 0x0f) << 8)
            frcast = i[3] >> 4
            alt_pressure = i[4] + ((i[5] & 0x0f) << 8)
            pre_frcast = i[5] >> 4
            weather["Pressure"] = (pressure,forecast[pre_frcast],alt_pressure,forecast[frcast])
            full |= 0x04
            continue
            
        if i[1] == 0x60: # Clock (10 bytes)
            power = i[0] >> 4
            powered = power >> 3
            battery = (power & 0x4) >> 2
            rf = (power & 0x2) >> 1
            level = power & 0x1        
            mi = i[4]
            hr = i[5]
            dy = i[6]
            mo = i[7]
            yr = i[8] + 2000
            weather["Clock"] = (hr,mi,dy,mo,yr,powered,level,rf)
            full |= 0x08
            continue
        
        if i[1] == 0x48: # Anemometer (9 bytes)
            wind_dir = i[2] & 0xf
            power = i[2] >> 4
            wind_speed = i[4] / 10.0
            low_speed = i[5] >> 4
            high_speed = i[6] << 4
            avg_speed = round((high_speed + low_speed) / 10.0,1)
            weather["Wind"] = (lev_battery[power],wind_speed,low_speed,high_speed,power,avg_speed,windies[wind_dir])
            full |= 0x10
            continue

        if i[1] == 0x41: # Rain Gauge (15 bytes)            
            sensor = i[2] & 0x0f
            power = i[2] >> 4
            rate = i[3]        
            hour = round(((i[5] << 8) + i[4]) * 25.4 / 100.0,1) # /* mm */
            day = round(((i[7] << 8) + i[6]) * 25.4 / 100.0,1) # /* mm */
            total = round(((i[9] << 8) + i[8]) * 25.4 / 100.0,1) # /* mm */
            s_mi = i[10]
            s_ho = i[11]
            s_da = i[12]
            s_mo = i[13]
            s_yr = i[14] + 2000
            weather["Rain"] = (lev_battery[power],rate,hour,day,total,s_mi,s_ho,s_da,s_mo,s_yr)
            full |= 0x20
            continue
        
    return full
 
#######
#  MAIN  #

full = 0
trend = ["растущий","устойчивый","падающий"]
lev_battery = ["заряжена","разряжена"]
weather = {'Pressure':[], 'Temperature':[[],[]], 'Humidity':[[],[]],'Clock':[],'Wind':[], "Rain":[]}
forecast = ["Переменная облачность","Облачно","Дождь","Солнечно","Ясно","Снег"] 
windies = ["северный", "северо-северо-восточный", "северо-восточный", "восточно-восточно-северный", "восточный", "осточно-восточно-южный", "юго-восточный", "юго-юго-восточный", "южный", "юго-юго-западный", "юго-западный", \
           "западно-западно-южный", "западный", "западно-западно-северный", "северо-западный", "северо-северо-западный"]
tmi = timeit.default_timer()
while full != 0x3f:
    out = read_wmr88()    
    if out is not None:
        dat = parse_data(out)        
    else:
        break
    full = get_sensors(dat, full)
    print("Процент выполнения:", round(100*full/63,2))
    time.sleep(5)
    
print("Общее время:",timeit.default_timer()-tmi)    
print(weather)


Планы на будущее. Видео монитор использовать не планируется, а узнать, например, температуру на улице хотелось бы. Сейчас все сохраняется в файл. Можно организовать вывод информации по сети через web server, здравствуй НА, но нет… может потом :). Также есть мысль передавать температуру и прочее через SMS. Основные потребители такой информации, конечно те кто находится на даче.

Кроме, так сказать, зрительного канала информации есть же еще слух. Можно использовать синтезатор речи. Весьма неплох, например RHVoice и для него есть python библиотека. Для запуска синтеза нужно какое то управление извне.

Я выбрал IR пульт, с ним можно управлять удаленно. Там же где и ТК, был куплен модуль OVU4003/00, в системе определяется как «Philips (or NXP) eHome Infrared Receiver». Для управления подобными устройствами есть LIRC, однако в данном случае это не нужно. Можно воспользовался библиотекой evdev. Пока эти дополнения опробовал только на «большом» компьютере с Linux Mint, надеюсь и с ТК проблем не возникнет. Пока смущает система на флэшке. Еще USB модем, который иногда «отваливается», вероятно из-за нехватки питания. Планирую его подключать с доп. питанием.

В заключении могу сказать, что в моем случае, ТК оказался ничем не хуже OPi, а по комплектации даже лучше. Специально не проверял и могу только предполагать, что из-за давней истории система x86 имеет некоторое преимущество, например, библиотек, программ больше, чем для ARM. Я наверно ретроград, но мне x86 система как то привычней.




Комментарии (38):

  1. Jury_78
    /#23941031

    Del

  2. ZOKIDIN100
    /#23941043 / +2

    8-разрядный океан-240. Пойдёт?

    • Jury_78
      /#23941047 / +1

      Если Python поставить можно - пойдет.

      • Sdima1357
        /#23942055

        Esp32 c wifi и микропитоном за $3. Все что Вы перечислили там есть.

        • Jury_78
          /#23942679 / +1

          Да, если не лень писать аналог Gammu и HID интерфейс и т.д.

  3. Harwest
    /#23941211 / +3

    Мда, вот заморочки.
    Воткнуть в USB порт 'свисток' с zigbee координатором?
    Ну или классически (бюджетнее) sonoff/tasmota через вайфай.

    • Jury_78
      /#23941227 / +1

      Из города до дачи у меня WiFi не достает.

      • Harwest
        /#23941327

        Речь про локальную внутридачную сеть между контроллером и релюшками-датчиками.

        • Jury_78
          /#23941389

          Зачем мне сеть, если никого нет, только для реле? К чему такие сложности?

          • LPby
            /#23942767

            Как по мне, сложности описаны в статье. А реле с датчиком и WiFi плюс модем - намного проще

            • Jury_78
              /#23942971

              Что сложного в простом пердатчике на 433МГц и в таком же приемнике?

          • Harwest
            /#23942863

            Так в контроллере уже есть вай-фай модуль. Поднять на нем точку доступа и расставить в нужных местах те же sonoff простые (или с DHT22/DS18B20). Их с купонами баксов за 5 можно уже купить. В стаканы подрозетники хорошо встают Sonoff mini (но они чуть дороже).

            • Jury_78
              /#23942993

              Заморочки с перепрошивкой sonoff вас не смущают.

              • unsignedchar
                /#23943073

                Это делается 1 раз.

                • Jury_78
                  /#23943111

                  Не 1 , а 4 раза. А если что то не так в прошивке то и еще... Овчинка выделки не стоит. Понимаю еще если дом постоянного проживания, то можно и напрячься.

                  • unsignedchar
                    /#23943623

                    Трудозатраты в заливке прошивки в 1 или 4 однотипных устройства не сильно отличаются.

                    Овчинка выделки не стстоит.

                    Вы кратко описали экономическую составляющую любого хобби проекта ;)

                    • Jury_78
                      /#23943669

                      Трудозатраты в заливке прошивки в 1 или 4 однотипных устройства не сильно отличаются.

                      Если можно, что то не делать... Это же не просто воткнул usb шнур и все.

                      Вы кратко описали экономическую составляющую любого хобби проекта ;)

                      Да, но не надо доводить до абсурда. Я б наверно смог и пароход построить, но зачем? Стараюсь придерживаться принципа минимальной необходимости. Считаете мой вариант сложней чем с WiFi розетками?

                      • unsignedchar
                        /#23944207

                        Готовые розетки проще в масштабировании. Если сломается — в любой момент можно купить новую (и перешить).

                      • Jury_78
                        /#23944279

                        В моем варианте и ломаться то нечему. В крайнем случае компоненты меняются элементарно и для этого ненужен компьютер.

                      • unsignedchar
                        /#23945995

                        ненужен компьютер

                        Нужен паяльник и магазин радиодеталей ;) Вы уверены, что если через 10 лет что то сломается, вы легко сможете найти замену?

                      • Jury_78
                        /#23947913

                        Я не уверен в том, что будет через год, а вы про 10. Конденсаторы, резисторы и др. имеют долгую историю и никуда не денутся, а вот контроллеры могут не пережить.

              • Harwest
                /#23943225

                Абсолютно не смущают :)
                У меня холодильник уже с вайфай и контролем температур. И увлажнитель воздуха тоже в сети — контроллер теперь и влажностью управляет и за остатком воды следит.

                • Jury_78
                  /#23943237

                  На даче?

                  • Harwest
                    /#23943275

                    Это все дома конечно же. Но сути не меняет — если начинаешь строить умный дом/дачу, но при этом нет прокачанных навыков в программировании и пайке — проще и бюджетнее развернуть сеть управления на вайфай, зигби, з-вейв.
                    Один раз прошить к примеру Тасмоту и дальше обновление по воздуху.

                    Если навесить функции управления на gpio/usb самого контроллера (одноплатника) — это риск получить большой даунтайм при выходе из строя. Держать в ЗИП вторую идентичную плату — ну, такое…

                    • Jury_78
                      /#23943353

                      это риск получить большой даунтайм при выходе из строя

                      Чем ваш вариант лучше в этом плане?

                      Это все дома конечно же.

                      А на даче?

                      • Harwest
                        /#23943435

                        Мой вариант — это контроллер на одноплатнике. Операционка — Debian, на ней Docker в котором крутится Homeassistant с несколькими аддонами.
                        В любой момент можно сделать snapshot и перекинуть систему полностью или частями на совершенно другую аппаратную платформу. Отладку удобно делать на тестовой системе а потом переносить конфиг на 'боевую'.

                        На даче только вайфай сеть, исполнительные устройства — на sonoff basic перешитые в Tasmota (в них очень легко прицепить разнообразные датчики). В Tasmota есть возможность создать резервную копию конфигурации (сгорела релюшка — залил на другую и заменил).

                      • Jury_78
                        /#23943477

                        В любой момент можно сделать snapshot и перекинуть систему полностью или частями на совершенно другую аппаратную платформу.

                        Что то я сомневаюсь что OS c raspberry встанет, например, на orange.

                        У меня программа на Python, я могу ее перенести на любую X86 систему и возможно даже на ARM.

                      • Harwest
                        /#23943501

                        Речь не про операционку, а про контейнеры в докер.
                        Я тоже первые системы делал на питоне с примесью PHP, но замаялся все вот это актуализировать.

                      • Jury_78
                        /#23943597

                        У меня программа это единственный экземпляр, я не собираюсь ее размножать. Что мне актуализировать? Исправления мне надо вносить один раз.

  4. Sergey78
    /#23941789 / +1

    Вам видимо уже не нужно, но для dht22 в ядре уже есть драйвер. Делаете overlay на device tree и просто читаете из "файла" показания. Судя по описанию, работает через bit banging.

    Сложилось впечатление, что у вас "если в руках молоток, всё вокруг превращается в гвозди". Это про тягу к python.

  5. cryptoz
    /#23943091

    На даче имеет смысл поставить высокую мачту и на неё повесить уличный всепогодный LTE модем. Будите приятно удивлены, что у вас интернет по качеству и скорости будет почти как в городе, в то время как у других на даче кое-как 3G сеть ловит. А с нормальным интернетом открывается больше возможностей для ваших изобретений и экспериментов.

    • Jury_78
      /#23943129

      Не поможет, проверено телефоном от вышки в 3 км по прямой видимости над водой. LTE символ может висеть на экране, а скорость ноль. Операторам надо расширять канал, но какой смысл, если остальные пол года загрузка будет процентов 10.

      • Harwest
        /#23943295

        С нормальной антенной и роутером все поедет.
        У самого дача окружена лесом, прямой видимости на БС нет даже с крыши дома. БС сама на расстоянии 2,5км.
        Внутри домика LTE на 'две палки' и трафик еле ползает. После установки на чердаке древнючего RBSX (высота подвеса от уровня земли всего 5м) все заработало. Sinr +4..8, rssi -70

        • Jury_78
          /#23943333

          Рад за вас... Кому то же должно повезти. Тем не менее не надо ставить диагноз дистанционно.