MegaD



  • Обсуждение плагина MegaD для контроллеров MegaD-328 и MegaD-2561



  • Плагин MegaD-2561 будет отличаться от MegaD-328 лишь нововведениями типа:

    1. Опрос датчиков DS18B20 по шине 1-wire (есть возможность поддержки текущей версией плагина в системе).

    2. Необходимостью установки времени при приеме сервером сообщения st=1 от MegaD и далее периодически (необходима реализация данной возможности).

    3. Поддержка команды d, которую сервер может послать для выполнения действий "по умолчанию" (есть возможность поддержки текущей версией плагина в системе).

    3. Нативная поддержка HTU21D (есть возможность поддержки текущей версией плагина в системе).

    4. Поддержка DS2413 в качестве дополнительных портов вывода (2 выхода), управляемых по 1-wire (необходима реализация данной возможности или просто надо попробовать прописать новый тип request для таких каналов).

    5. Поддержка аппаратной реализации I2C (необходима реализация данной возможности или просто надо попробовать сделать скрипт на JS для канала).

    В остальном плагины по функционалу должны совпадать. То есть можно говорить так - все что умеет MegaD-328 умеет и MegaD-2561. Разница в небольших ньюансах (например, при считывании данных с DHT22 первая сообщает их в формате "25.40/55.50", а вторая - "temp:25.40/hum:55.50").



  • Слушающий порт на сервере для каждого плагина разный.

    Что бы посмотреть где какой порт прописан нужно заходить в свойства плагина.

    Может лучше вынести слушающий порт в общую таблицу вместо [Модель] (не используется) или рядом.



  • Коллеги, расскажите пожалуйста, как подключаете MegaD к raspberry?

    Что вы подключаете к MegaD и чем управляете?



  • @chas99:

    Коллеги, расскажите пожалуйста, как подключаете MegaD к raspberry?

    Что вы подключаете к MegaD и чем управляете?

    MegaD - это Ethernet-устройство. Что подключается к ней - уже писал вам в личке. А вообще посетите сайт разработчика - там очень много хорошего и полезного материала по УД!



  • Например, датчик на одном - реле на другом. Команд может быть несколько на разные контроллеры. Или возможно на свой контроллер.

    Настройка выполняется в разделе: Сообщения от MegaD - кнопка Redirect.

    Приведите, пожалуйста, пример как это должно выглядеть, с наскока не понятно. Желательно в виде скриншота. Исходные данные:

    1. Запрос от MegaD - /mod_megad.php?pt=0 (вход 0 замкнут), команда - http://192.168.12.20/sec/?cmd=7:1 (включить 7 выход удаленного контроллера).

    2. Запрос от MegaD - /mod_megad.php?pt=0&m=1 (вход 0 разомкнут), команда - http://192.168.12.20/sec/?cmd=7:0 (выключить 7 выход удаленного контроллера).

    Я вроде что-то понял, но на данный момент получается вот такая ерунда (на MG3 каналы не срабатывают):

    26.01 01:21:42.498 192.168.12.30 => localhost:10030 HTTP GET /mod_megad.php?pt=0&m=1&cnt=5&mdid=
    26.01 01:21:42.505 MG4?0=0&
    26.01 01:21:42.507 Redirect to MG3
    26.01 01:21:42.509 localhost => 192.168.12.21:80 HTTP GET http://192.168.12.21/sec/?cmd=9:1
    26.01 01:21:42.516 MG3?9=1&
    26.01 01:21:42.517 192.168.12.30 <= localhost:10030 
    26.01 01:21:42.545 localhost <= 192.168.12.30:80 response: statusCode=401 contentType = undefined
    26.01 01:21:42.552 localhost <= 192.168.12.30:80 HTTP Unauthorized
    26.01 01:21:44.105 192.168.12.30 => localhost:10030 HTTP GET /mod_megad.php?pt=0&cnt=5&mdid=
    26.01 01:21:44.107 MG4?0=1&
    26.01 01:21:44.107 Redirect to MG3
    26.01 01:21:44.107 localhost => 192.168.12.21:80 HTTP GET http://192.168.12.21/sec/?cmd=9:0
    26.01 01:21:44.109 MG3?9=0&
    26.01 01:21:44.109 192.168.12.30 <= localhost:10030 
    26.01 01:21:44.120 localhost <= 192.168.12.30:80 response: statusCode=401 contentType = undefined
    26.01 01:21:44.123 localhost <= 192.168.12.30:80 HTTP Unauthorized
    
    


  • @Alex_Jet:

    Я вроде что-то понял, но на данный момент получается вот такая ерунда (на MG3 каналы не срабатывают):

    > > 26.01 01:21:42.507 Redirect to MG3
    > > 26.01 01:21:42.509 localhost => 192.168.12.21:80 HTTP GET http://192.168.12.21/sec/?cmd=9:1
    > > 
    > > 
    

    Вы сделали все абсолютно верно, за исключением пути - полный путь "http://192.168.12.21" прописывать не надо, адрес сам уже взялся из свойств MG3:

    26.01 01:21:44.107 localhost => 192.168.12.21:80 HTTP GET http://192.168.12.21/sec/?cmd=9:0

    Все должно работать.

    Конечно, нужно было сразу опубликовать скриншот. Но лучше поздно чем никогда 🙂
    mega_redirect.jpg

    Если остановимся на этом варианте, можно отсекать полный путь при сохранении.



  • @intrapro:

    Если остановимся на этом варианте, можно отсекать полный путь при сохранении.

    Я прочитал ваши убедительные доводы в пользу такого решения на форуме ab-log. Полностью с ними согласен, хотя есть некоторое неудобство…думаю привыкнем. Однако у меня возникло 2 проблемы:

    1. При разрешении экрана 1280х720 название плагина в первом столбце меню Redirect не отображается. На работе при 1920х1280 - все нормально.
    No_plugin_name.jpg
    2. Не изменяется состояние устройства в вебе, привязанного к каналу 9 MG3:

    26.01 22:46:36.539 192.168.12.30 => localhost:10030 HTTP GET /mod_megad.php?pt=0&m=1&cnt=16&mdid=
    26.01 22:46:36.542 MG4?0=0&
    26.01 22:46:36.543 Redirect to MG3
    26.01 22:46:36.543 localhost => 192.168.12.21:80 HTTP GET /sec/?cmd=9:1
    26.01 22:46:36.544 MG3?9=1&
    26.01 22:46:36.544 192.168.12.30 <= localhost:10030 
    26.01 22:46:36.553 localhost <= 192.168.12.30:80 response: statusCode=200 contentType = text/html
    26.01 22:46:36.555 localhost <= 192.168.12.30:80 HTTP Done
    26.01 22:46:40.698 192.168.12.30 => localhost:10030 HTTP GET /mod_megad.php?pt=0&cnt=16&mdid=
    26.01 22:46:40.702 MG4?0=1&
    26.01 22:46:40.702 Redirect to MG3
    26.01 22:46:40.702 localhost => 192.168.12.21:80 HTTP GET /sec/?cmd=9:0
    26.01 22:46:40.703 MG3?9=0&
    26.01 22:46:40.704 192.168.12.30 <= localhost:10030 
    26.01 22:46:40.711 localhost <= 192.168.12.30:80 response: statusCode=200 contentType = text/html
    26.01 22:46:40.714 localhost <= 192.168.12.30:80 HTTP Done
    
    


  • Поправим, вечером выложим обновление.



  • Еще такой момент по request от MegaD вида st=1 (контроллер стартовал). Вы по этому request какой-нибудь функционал закладывали?

    Вроде как при получении этой команды происходит новый опрос контроллера - это видно по логу:

    28.01 10:09:06.133 localhost => 192.168.12.21:80 HTTP GET /sec/?pt=31&cmd=list
    28.01 10:09:06.134 localhost <=>192.168.12.21:80 socket handle=11\. Header: GET /sec/?pt=31&cmd=list HTTP/1.1
    Host: 192.168.12.21
    Connection: close
    
    28.01 10:09:06.214 localhost <= 192.168.12.21:80 response: statusCode=200 contentType = text/html
    28.01 10:09:06.216 localhost <= 192.168.12.21:80 HTTP ff862a831501:26.31;ff6e2a831501:26.31;ff676b821503:25.93
    28.01 10:09:06.216 MG3?31_ff862a831501=26.31&31_ff6e2a831501=26.31&31_ff676b821503=25.93&
    28.01 10:09:06.217 localhost <=>192.168.12.21:80 socket closed
    28.01 10:09:06.332
    28.01 10:09:06.333 localhost => 192.168.12.21:80 HTTP GET /sec/?pt=34&scl=35&i2c_dev=htu21d&i2c_par=1
    28.01 10:09:06.334 localhost <=>192.168.12.21:80 socket handle=11\. Header: GET /sec/?pt=34&scl=35&i2c_dev=htu21d&i2c_par=1 HTTP/1.1
    Host: 192.168.12.21
    Connection: close
    
    28.01 10:09:11.339 Socket timeout - abort!
    28.01 10:09:11.341
    28.01 10:09:11.341 localhost => 192.168.12.21:80 HTTP GET /sec/?pt=34&scl=35&i2c_dev=htu21d
    28.01 10:09:11.343 localhost <=>192.168.12.21:80 socket handle=17\. Header: GET /sec/?pt=34&scl=35&i2c_dev=htu21d HTTP/1.1
    Host: 192.168.12.21
    Connection: close
    
    28.01 10:09:16.337 192.168.12.21 => localhost:10021 HTTP GET /mod_megad.php?st=1
    28.01 10:09:16.340 192.168.12.21 <= localhost:10021
    28.01 10:09:16.355 Socket timeout - abort!
    28.01 10:09:16.364
    28.01 10:09:16.364 localhost => 192.168.12.21:80 HTTP GET /sec/?cmd=all
    28.01 10:09:16.367 localhost <=>192.168.12.21:80 socket handle=19\. Header: GET /sec/?cmd=all HTTP/1.1
    Host: 192.168.12.21
    Connection: close
    
    28.01 10:09:16.489 localhost <= 192.168.12.21:80 response: statusCode=200 contentType = text/html
    28.01 10:09:16.492 localhost <= 192.168.12.21:80 HTTP OFF/0;OFF/0;OFF/0;OFF/0;OFF/0;OFF/0;OFF/0;OFF;OFF;OFF;OFF;OFF;OFF;OFF;ON;OFF/0;OFF/0;OFF/0;OFF/0;OFF/0;OFF/0;OFF/0;OFF;OFF;OFF;OFF;OFF;OFF;OFF;ON;temp:0.00/hum:0.00;;OFF;OFF;;OFF;247;ON
    28.01 10:09:16.493 Address 36
    28.01 10:09:16.493     run script: val=247 depo={ res: [] }
    28.01 10:09:16.494  script return:{ reqsek: 5 } depo={ res: [ 247 ] }
    28.01 10:09:16.494 Address 36\. Shift request interval: 5 sek.
    28.01 10:09:16.494 MG3?0=0&1=0&2=0&3=0&4=0&5=0&6=0&7=0&8=0&9=0&10=0&11=0&12=0&13=0&14=1&15=0&16=0&17=0&18=0&19=0&20=0&21=0&22=0&23=0&24=0&25=0&26=0&27=0&28=0&29=1&30_1=0&30_2=0&31=0&32=0&33=0&34=0&35=0&37=1&
    28.01 10:09:16.495 localhost <=>192.168.12.21:80 socket closed
    28.01 10:09:18.374 localhost <= 192.168.12.21:80 response: statusCode=200 contentType = text/html
    28.01 10:09:18.379 localhost <= 192.168.12.21:80 HTTP 22.67
    28.01 10:09:18.380 MG3?342=22.67&
    28.01 10:09:18.381 localhost <=>192.168.12.21:80 socket closed
    28.01 10:09:19.2 localhost <= 192.168.12.21:80 response: statusCode=200 contentType = text/html
    28.01 10:09:19.5 localhost <= 192.168.12.21:80 HTTP 26.86
    28.01 10:09:19.5 MG3?341=26.86&
    28.01 10:09:19.6 localhost <=>192.168.12.21:80 socket closed
    28.01 10:09:21.563
    28.01 10:09:21.564 localhost => 192.168.12.21:80 HTTP GET /sec/?pt=36&cmd=get
    28.01 10:09:21.566 localhost <=>192.168.12.21:80 socket handle=11\. Header: GET /sec/?pt=36&cmd=get HTTP/1.1
    Host: 192.168.12.21
    Connection: close
    
    28.01 10:09:21.571 localhost <= 192.168.12.21:80 response: statusCode=200 contentType = text/html
    28.01 10:09:21.573 localhost <= 192.168.12.21:80 HTTP 248
    28.01 10:09:21.573 Address 36
    28.01 10:09:21.574     run script: val=248 depo={ res: [ 247 ] }
    28.01 10:09:21.575  script return:{ reqsek: 5 } depo={ res: [ 247, 248 ] }
    28.01 10:09:21.575 MG3?
    28.01 10:09:21.576 localhost <=>192.168.12.21:80 socket closed
    28.01 10:09:26.572
    28.01 10:09:26.572 localhost => 192.168.12.21:80 HTTP GET /sec/?pt=36&cmd=get
    28.01 10:09:26.574 localhost <=>192.168.12.21:80 socket handle=11\. Header: GET /sec/?pt=36&cmd=get HTTP/1.1
    Host: 192.168.12.21
    Connection: close
    
    28.01 10:09:26.580 localhost <= 192.168.12.21:80 response: statusCode=200 contentType = text/html
    28.01 10:09:26.582 localhost <= 192.168.12.21:80 HTTP 240
    28.01 10:09:26.582 Address 36
    28.01 10:09:26.583     run script: val=240 depo={ res: [ 247, 248 ] }
    28.01 10:09:26.584  script return:{ reqsek: 5 } depo={ res: [ 247, 248, 240 ] }
    28.01 10:09:26.584 MG3?
    28.01 10:09:26.585 localhost <=>192.168.12.21:80 socket closed
    28.01 10:09:31.581
    28.01 10:09:31.581 localhost => 192.168.12.21:80 HTTP GET /sec/?pt=36&cmd=get
    28.01 10:09:31.584 localhost <=>192.168.12.21:80 socket handle=11\. Header: GET /sec/?pt=36&cmd=get HTTP/1.1
    Host: 192.168.12.21
    Connection: close
    
    28.01 10:09:31.590 localhost <= 192.168.12.21:80 response: statusCode=200 contentType = text/html
    28.01 10:09:31.592 localhost <= 192.168.12.21:80 HTTP 238
    28.01 10:09:31.593 Address 36
    28.01 10:09:31.594     run script: val=238 depo={ res: [ 247, 248, 240 ] }
    28.01 10:09:31.596  script return:{ reqsek: 5 } depo={ res: [ 247, 248, 240, 238 ] }
    28.01 10:09:31.596 MG3?
    28.01 10:09:31.598 localhost <=>192.168.12.21:80 socket closed
    28.01 10:09:36.590
    28.01 10:09:36.591 localhost => 192.168.12.21:80 HTTP GET /sec/?pt=36&cmd=get
    28.01 10:09:36.593 localhost <=>192.168.12.21:80 socket handle=11\. Header: GET /sec/?pt=36&cmd=get HTTP/1.1
    Host: 192.168.12.21
    Connection: close
    
    28.01 10:09:36.598 localhost <= 192.168.12.21:80 response: statusCode=200 contentType = text/html
    28.01 10:09:36.601 localhost <= 192.168.12.21:80 HTTP 244
    28.01 10:09:36.601 Address 36
    28.01 10:09:36.602     run script: val=244 depo={ res: [ 247, 248, 240, 238 ] }
    28.01 10:09:36.607  script return:{ val: 1790, reqsek: 300 } depo={ res: [] }
    28.01 10:09:36.607 Address 36\. Shift request interval: 300 sek.
    28.01 10:09:36.608 MG3?36=1790&
    28.01 10:09:36.610 localhost <=>192.168.12.21:80 socket closed
    28.01 10:10:16.459
    28.01 10:10:16.460 localhost => 192.168.12.21:80 HTTP GET /sec/?pt=31&cmd=list
    28.01 10:10:16.462 localhost <=>192.168.12.21:80 socket handle=11\. Header: GET /sec/?pt=31&cmd=list HTTP/1.1
    Host: 192.168.12.21
    Connection: close
    
    28.01 10:10:16.541 localhost <= 192.168.12.21:80 response: statusCode=200 contentType = text/html
    28.01 10:10:16.543 localhost <= 192.168.12.21:80 HTTP ff862a831501:26.31;ff6e2a831501:26.37;ff676b821503:25.93
    28.01 10:10:16.544 MG3?31_ff862a831501=26.31&31_ff6e2a831501=26.37&31_ff676b821503=25.93&
    28.01 10:10:16.545 localhost <=>192.168.12.21:80 socket closed
    28.01 10:10:16.659
    28.01 10:10:16.660 localhost => 192.168.12.21:80 HTTP GET /sec/?pt=34&scl=35&i2c_dev=htu21d&i2c_par=1
    28.01 10:10:16.662 localhost <=>192.168.12.21:80 socket handle=11\. Header: GET /sec/?pt=34&scl=35&i2c_dev=htu21d&i2c_par=1 HTTP/1.1
    Host: 192.168.12.21
    Connection: close
    
    28.01 10:10:16.715 localhost <= 192.168.12.21:80 response: statusCode=200 contentType = text/html
    28.01 10:10:16.717 localhost <= 192.168.12.21:80 HTTP 26.88
    28.01 10:10:16.717 MG3?341=26.88&
    28.01 10:10:16.718 localhost <=>192.168.12.21:80 socket closed
    28.01 10:10:16.860
    28.01 10:10:16.860 localhost => 192.168.12.21:80 HTTP GET /sec/?pt=34&scl=35&i2c_dev=htu21d
    28.01 10:10:16.862 localhost <=>192.168.12.21:80 socket handle=11\. Header: GET /sec/?pt=34&scl=35&i2c_dev=htu21d HTTP/1.1
    Host: 192.168.12.21
    Connection: close
    
    28.01 10:10:16.885 localhost <= 192.168.12.21:80 response: statusCode=200 contentType = text/html
    28.01 10:10:16.887 localhost <= 192.168.12.21:80 HTTP 22.58
    28.01 10:10:16.887 MG3?342=22.58&
    28.01 10:10:16.888 localhost <=>192.168.12.21:80 socket closed
    
    

    Однако я пытался по этому request (st=1) выполнить команду, но она не срабатывает (по логу также ничего связанного с этой командой нет):
    Request_st=1.png



  • @Alex_Jet:

    Еще такой момент по request от MegaD вида st=1 (контроллер стартовал). Вы по этому request какой-нибудь функционал закладывали?

    Сейчас как раз проверяем этот функционал. Вы правы, так как там была заложена дополнительная логика (сброс всех таймеров и первый опрос), действия при получении не выполнялись. Также проверяем перенаправление команды на другой контроллер. После тестирования выложим, надеюсь, сегодня 😞



  • @Alex_Jet:

    Еще такой момент по request от MegaD вида st=1 (контроллер стартовал)…. я пытался по этому request (st=1) выполнить команду, но она не срабатывает (по логу также ничего связанного с этой командой нет):

    Ошибку исправили, st=1 обрабатывается, но, похоже, MegaD в ответ на st=1 команду не принимает.

    Вариант с отправкой команды через Redirect - работает.

    Req:/megad?st=1   Resp:7:1 - так выход не переключается
    А такой  вариант рабочий: 
    Req:/megad?st=1      
    Req:/sec/?cmd=7:1   Resp:Done
    
    
    

    В принципе, это логично. Контроллер принимает команду только в ответ на сообщение о переключении состояния порта.

    Обновление выложили, но новость пока публиковать не будем.

    Реально проверить передачу команд на другие контроллеры мы не можем, т.к. имеем только один контроллер и тестируем на эмуляторе, что не совсем аутентично :).

    Что исправлено:

    1. Переключение состояния канала при передаче команды на другой контроллер

    2. Ширина столбца для показа названия контроллера в таблице Redirect

    Думаю, эти две ошибки и привели к тому, что разобраться получилось не сразу.

    3. На запрос st=1 можно вешать команды в Redirect



  • @intrapro:

    Ошибку исправили, st=1 обрабатывается, но, похоже, MegaD в ответ на st=1 команду не принимает.

    Как-то странно, должно все работать - потестирую. Вообще в MegaD-2561 Андрей предлагал после получения st=1 сервером, например, устанавливать время в контроллере (для работы с локальным cron).
    @intrapro:

    Реально проверить передачу команд на другие контроллеры мы не можем, т.к. имеем только один контроллер и тестируем на эмуляторе, что не совсем аутентично :).

    Проверил на том же варианте, который был настроен в прошлый раз - после обновления переключаются порты удаленного контроллера и, соответственно, меняется состояние привязанного к каналу устройства в вебе.
    @intrapro:

    Что исправлено:

    1. Переключение состояния канала при передаче команды на другой контроллер

    2. Ширина столбца для показа названия контроллера в таблице Redirect

    Думаю, эти две ошибки и привели к тому, что разобраться получилось не сразу.

    1. Работает с изменением состояния устройства, привязанного к каналу.

    2. Да, теперь в столбце на моем нетбуке отображается название контроллера.
    @intrapro:

    3. На запрос st=1 можно вешать команды в Redirect

    Это конечно очень хорошо!!! и я очень благодарен Вам за развитие плагина, но сейчас возможно вешать только простые команды, типа переключение каналов. Надо вводить возможность привязки скриптов, как это сделано у каналов. Например, при st=1 надо:

    1. Установить время в MegaD. Команда такая http://192.168.0.14/sec/?cf=7&stime=10:57:06:4, но прежде надо запросить системное время с днем недели. То есть нужен скрипт.

    2. Инициализировать OLED дисплей.

    Хотя скорее все же скрипт нужен только к request st=1. Поскольку всю остальную логику можно реализовать средствами ih (сценарии и прочее).



  • Вообще, хочу Вам дать "пищу" для реализации в плагине поддержки I2C. В варианте реализации MegaD-2561 - это все довольно просто, поскольку основные команды I2C реализованы аппаратно!

    i2c_cmd - команды (1 - инициализация; 2 - старт; 3 - стоп)
    i2c_send - отправка данных в HEX-виде
    i2c_read - считывание данных в HEX-виде (0 - на конце ACK; 1 - на конце NACK [конец связи])
    i2c_sendp - отправка пакетных данных в HEX-виде
    
    
    

    Пример последовательности команд передаваемых на контроллер MegaD-2561 для опроса датчика HTU21D:

    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=1
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=2
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=80E3
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=3
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=2
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_send=81
    //Тут нужна задержка не менее 15000 мкс
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_read=0
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_read=0
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_read=1
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=3
    Температура: 25.49°
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=1
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=2
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=80E5
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=3
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=2
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_send=81
    //Тут нужна задержка не менее 15000 мкс
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_read=0
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_read=0
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_read=1
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=3
    Относительная влажность: 25.59%
    
    
    

    Последовательность команд для инициализации OLED с контроллером SSD1306:

    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=3
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=1
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=2
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=7800AFD58081EE8D14AFA1C8A6
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=3
    
    

    Последовательность команд для очистки дисплея OLED с контроллером SSD1306:

    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=2
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=7800200021007F220007
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=3
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=2
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=7840
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=0000000000000000000000000000000000000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=00000000
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=3
    
    

    Ну и на "закуску" - тестовый php-скрипт с которого я начинал, осваивая I2C с MegaD: Считывание данных с htu21d, инициализация OLED SSD1306, вывод информации в веб и на OLED. И HTU21D, и OLED подключены к одной и той же шине I2C на MegaD - 34-порт SDA и 35-порт SCL.

    define("SCL", "35");
    define("SDA", "34");
    define("ADR", "78");	//Display adress
    define("MD", "http://192.168.12.21/sec/?");
    
    function i2c_init()
    { file_get_contents(MD."pt=".SDA."&scl=".SCL."&i2c_cmd=1");
    }
    
    function i2c_start()
    { file_get_contents(MD."pt=".SDA."&scl=".SCL."&i2c_cmd=2");
    }
    
    function i2c_stop()
    { file_get_contents(MD."pt=".SDA."&scl=".SCL."&i2c_cmd=3");
    }
    
    function i2c_send($data)
    { file_get_contents(MD."pt=".SDA."&scl=".SCL."&i2c_send=" .$data);
    }
    
    function i2c_send_p($data)
    { file_get_contents(MD."pt=".SDA."&scl=".SCL."&i2c_sendp=" .$data);
    }
    
    function i2c_read($nack = 0)
    { return file_get_contents(MD."pt=".SDA."&scl=".SCL."&i2c_read=" .$nack);
    }
    
    function check_htu21d_crc($raw_data, $crc)
    { $remainder = $raw_data << 8;
      $divsor = 0x988000;
    
      for ( $i = 0 ; $i < 16 ; $i++)
      { if ( $remainder & 1<<(23 - $i) )
    	$remainder ^= $divsor;
    	$divsor >>= 1;
      }
    
      return dechex($remainder);
    }
    
    function get_htu21d_temperature()
    { i2c_init();
    
      i2c_start();
      i2c_send_p("80E3");
      i2c_stop();
    
      i2c_start();
      i2c_send("81");
      usleep(15000);
      $msb = i2c_read();
      $lsb = i2c_read();
      $crc = i2c_read(1);
      i2c_stop();
    
      if ( strlen($msb) == 1 )
      $msb = "0$msb";
      if ( strlen($lsb) == 1 )
      $lsb = "0$lsb";
    
      $msb = hexdec($msb);
      $lsb = hexdec($lsb);
      $raw_temp = ($msb << 8) | $lsb;
    
      if ( check_htu21d_crc($raw_temp, $crc) != $crc )
      return "CRC error - $crc";
      else
      { $raw_temp &= 0xFFFC;
        $temperature = number_format(round(-46.85 + 175.72 * ($raw_temp / 65536), 2), 2);
    	return $temperature;
      }
    }
    
    function get_htu21d_humidity()
    { i2c_init();
    
      i2c_start();
      i2c_send_p("80E5");
      i2c_stop();
    
      i2c_start();
      i2c_send("81");
      usleep(15000);
      $msb = i2c_read();
      $lsb = i2c_read();
      $crc = i2c_read(1);
      i2c_stop();
    
      if ( strlen($msb) == 1 )
      $msb = "0$msb";
      if ( strlen($lsb) == 1 )
      $lsb = "0$lsb";
    
      $msb = hexdec($msb);
      $lsb = hexdec($lsb);
      $raw_hum = ($msb << 8) | $lsb;
    
      if ( check_htu21d_crc($raw_hum, $crc) != $crc )
      return "CRC error - $crc";
      else
      { $raw_hum &= 0xFFFC;
    	$humidity = number_format(round(-6 + (125 * ($raw_hum / 65536)), 2), 2);
    	if ( $humidity > 100 )
    	$humidity = 100;
    	return $humidity;
      }
    }
    
    function ssd1306_init()
    {	i2c_stop();
    	i2c_init();
    	i2c_start();
    	i2c_send_p(ADR."00AFD58081EE8D14AFA1C8A6");
    	i2c_stop();
    }
    
    function ssd1306_clear_display()
    {	i2c_start();
    	i2c_send_p(ADR."00200021007F220007");
    	i2c_stop();
    
    	i2c_start();
    	i2c_send_p(ADR."40");
    	$my_cnt = 0;
    	$data_p = "";
    	for ( $i = 0; $i < 1024; $i++ )
    	{	$data_p .= "00";
    		$my_cnt++;
    		if ( $my_cnt == 20 || $i == 1023 )
    		{	$my_cnt = 0;
    			i2c_send_p($data_p);
    			$data_p = "";
    		}
    	}
    	i2c_stop();
    }
    
    function ssd1306_write_text($string, $font = "default", $col = 0, $page = 0)
    {	$my_string = preg_split('//u', $string, -1, PREG_SPLIT_NO_EMPTY);
    	include("libs/ssd1306/mod_ssd1306_fonts.php");
    	$my_font = $$font;
    
    	i2c_start();
    	i2c_send_p(ADR. "00204121");
    	i2c_send(dechex($col));
    	i2c_send_p("7F22");
    	i2c_send(dechex($page));
    	i2c_send(dechex($page + 1));
    	i2c_stop();
    
    	i2c_start();
    	i2c_send_p(ADR."40");
    	$my_cnt = 0;
    	$data_p = "";
    
    	for ( $j = 0; $j < count($my_string); $j++ )
    	{	$flag = 1;
    		$data = "";
    		for ( $i = 0; $i < count($my_font[$my_string[$j]]); $i++ )
    		{	$data = dechex($my_font[$my_string[$j]][$i + $flag]);
    			if ( strlen($data) == 1 )
    			$data = "0$data";
    			$data_p .= $data;
    			$my_cnt++;
    			if ( $my_cnt == 20 || $i == count($my_font[$my_string[$j]]) - 1 )
    			{	$my_cnt = 0;
    				i2c_send_p($data_p);
    				$data_p = "";
    			}
    			$flag = $flag * -1;
    		}
    		i2c_send_p("0000");
    	}
    	i2c_stop();
    }
    
    $temperature = get_htu21d_temperature();
    echo "Температура: ".$temperature."°
    \n";
    
    $humidity = get_htu21d_humidity();
    echo "Относительная влажность: ".$humidity."%
    \n";
    
    $hum_compensated = $humidity + (25 - $temperature) * -0.15;
    echo "Относительная влажность (комп.): ".$hum_compensated."%
    \n";
    
    echo "
    
    * * *
    
    \n";
    
    ssd1306_init();
    echo "Дисплей инициализирован!
    \n";
    
    ssd1306_clear_display();
    echo "Дисплей очищен!
    \n";
    
    ssd1306_write_text("OLED with SSD1306", "verdana_10", 6, 0);
    ssd1306_write_text("Температура: $temperature C", "verdana_10", 2, 2);
    ssd1306_write_text("Влажность: $humidity %", "verdana_10", 7, 4);
    ssd1306_write_text("Информационная строка", "default", 0, 6);
    echo "Данные выведены на дисплей!
    \n";
    
    
    

    Собственно за такую реализацию I2C в MegaD-2561, библиотеки и примеры работы с устройствами I2C большое спасибо все тому же Андрею - автору проекта ab-log.



  • Alex_Jet, большое спасибо за быстрое тестирование 🙂



  • По поводу отправки времени по команде st=1 - можно просто заложить в плагин ( опционально, если это важно). Мы st=1 уже обрабатываем.

    По I2C - действительно, API красивое, температуру и влажность сделать можно, если из скрипта возвращать запросы. А они подряд могут идти или нужны задержки? И наверно нужны команды чтения, если как в php-скрипте?

    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=1
    // ?Подряд? или дождаться ответа? или некоторую задержку сделать?
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=2
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendp=80E3
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=3
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=2
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_send=81
    //Тут нужна задержка не менее 15000 мкс - понятно
    // ?Здесь видимо нужно чтение выполнить:
    ??http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendi2c_read=0 - и получить 1 байт
    ??http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendi2c_read=0 - и 2 байт
    ??http://192.168.12.21/sec/?pt=34&scl=35&i2c_sendi2c_read=1 - закончить чтение и выполнить преобразование значения
    http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=3
    
    
    

    А по поводу дисплея…Их может быть несколько? как они адресуются?

    include("libs/ssd1306/mod_ssd1306_fonts.php"); - это видимо таблица символов разными шрифтами?

    Ее и саму процедуру вывода значения на дисплей можно, наверно, включить в плагин, если это штатное оборудование для MegaD. Организовать некую библиотеку плагина.

    Как выводить на дисплей, когда? Можно отдельные сегменты (только температуру) или нужно все переписывать? Там ведь могут быть данные не только с каналов MegaD? В общем, нужно подумать 😉



  • @intrapro:

    По поводу отправки времени по команде st=1 - можно просто заложить в плагин ( опционально, если это важно). Мы st=1 уже обрабатываем.

    Можно заложить, но только опционально, поскольку MegaD-328 этот функционал не поддерживает.
    @intrapro:

    По I2C - действительно, API красивое, температуру и влажность сделать можно, если из скрипта возвращать запросы. А они подряд могут идти или нужны задержки? И наверно нужны команды чтения, если как в php-скрипте?

    Идут подряд, но как вы говорите PHP сам по себе медленный…надо учесть что I2C обычно работает с частотой 10кГц (медленный режим - как раз для нас, поскольку датчики от контроллера надо располагать на расстоянии 5-10 м). Команды чтения - конечно нужны.

    Вообще строго говоря нужен функционал:

    • например, создать скрипт на том же 34-м канале или на "виртуальных" каналах 341,342....349 уже можем

    • в скрипте написать нужные функции для обработки результатов чтения и их возврат/присвоение каналу. Тут как минимум нужен пример как обращаться к функциям I2C, как связать эти функции с IP контроллера и т.д. Пользователи напишут сами нужные функции в скрипте.

    По коду (немного ошибся в предыдущем посте, но уже все поправил). Про скорость уже написал. Ниже "рукопашный" код считывания температуры с HTU21D и вывод в веб. На почту скинул damp обмена данными. В принципе видно, что при команде read=0 контроллер отвечает 200 ОК со значением 68, потом b8, а при read=1 - 64 (см.вывод веба).

    function Read_Temp()
    { file_get_contents("http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=1");			//init
      file_get_contents("http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=2");			//start
      file_get_contents("http://192.168.12.21/sec/?pt=34&scl=35&i2c_send=80");			//adress + write
      file_get_contents("http://192.168.12.21/sec/?pt=34&scl=35&i2c_send=E3");			//trigger temperature measurement
      file_get_contents("http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=3");			//stop
    
      file_get_contents("http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=2");			//start
      file_get_contents("http://192.168.12.21/sec/?pt=34&scl=35&i2c_send=81");			//adress + read
      usleep(15000);
    
      $msb = file_get_contents("http://192.168.12.21/sec/?pt=34&scl=35&i2c_read=0");	//ACK
      $lsb = file_get_contents("http://192.168.12.21/sec/?pt=34&scl=35&i2c_read=0");	//ACK
      $crc = file_get_contents("http://192.168.12.21/sec/?pt=34&scl=35&i2c_read=1");	//NACK
      file_get_contents("http://192.168.12.21/sec/?pt=34&scl=35&i2c_cmd=3");			//stop
    
      echo "Data (MSB): " .$msb. "
    \n";
      echo "Data (LSB): " .$lsb. "
    \n";
      echo "Checksum: " .$crc. "
    \n";
    
      $msb = hexdec($msb);
      $lsb = hexdec($lsb);
      $raw = ($msb << 8) | $lsb;
      echo "Raw: " .$raw. "
    \n";
    
      $temp = round((-46.85 + 175.72*(($raw)/65536)), 2);
      echo "Температура: " .$temp. "°";
    }
    
    
    
    Data (MSB): 68
    Data (LSB): b8
    Checksum: 64
    Raw: 26808
    Температура: 25.03°
    
    

    @intrapro:

    А по поводу дисплея…Их может быть несколько? как они адресуются?

    На самом деле многие I2C устройства могут иметь несколько адресов. В частности OLED дисплеи могут иметь 2 адреса. Датчик освещенности TSL2561 - 3 шт.
    @intrapro:

    include("libs/ssd1306/mod_ssd1306_fonts.php"); - это видимо таблица символов разными шрифтами?

    Ее и саму процедуру вывода значения на дисплей можно, наверно, включить в плагин, если это штатное оборудование для MegaD. Организовать некую библиотеку плагина.

    Да, эту таблицу я так понимаю сгенерировал Андрей. Там сейчас есть 3 шрифта. Главное правильно продумать процедуру вывода, поскольку дисплеи могут быть разного формата. Пока сообщество использует самый дешевый 0,96" дисплей.
    @intrapro:

    Как выводить на дисплей, когда? Можно отдельные сегменты (только температуру) или нужно все переписывать? Там ведь могут быть данные не только с каналов MegaD? В общем, нужно подумать 😉

    Периодичность обновления данных, думаю, надо задавать. Вообще для чего эти дисплеи можно использовать? - например, встроить в заглушку подрозетника - туда же где будет размещаться датчик температуры. Это своеобразный "железный" термогигрометр, который кроме температуры, влажности, может отобразить уровень СО2 и другие показатели - по пути подошел и посмотрел какой же климат в данном помещении. Поэтому период обновления от 5 до 10 минут. Для больших дисплеев же применение не ограничено…

    Можно переписывать отдельные сегменты, но это вероятно должно определяться в пользовательском скрипте. Конечно же на дисплей можно выводить любые данные. Поэтому как вариант для MegaD-2561 нужен свой раздел, например, "I2C display".



  • @Alex_Jet:

    Как-то странно, должно все работать - потестирую. Вообще в MegaD-2561 Андрей предлагал после получения st=1 сервером, например, устанавливать время в контроллере (для работы с локальным cron).

    Если давать команду на включение порта через request, то контроллер не отрабатывает! А если через redirect, то все хорошо. Вот лог не успешного включения канала через request:

    29.01 11:31:39.0545 192.168.12.21 => localhost:10021 HTTP GET /mod_megad.php?st=1
    29.01 11:31:39.0553 MG3?22=1&
    29.01 11:31:39.0554 192.168.12.21 <= localhost:10021 22:1
    29.01 11:31:39.0661 localhost => 192.168.12.21:80 HTTP GET /sec/?cmd=all
    29.01 11:31:39.0785 localhost <= 192.168.12.21:80 HTTP OFF/0;OFF/0;OFF/0;OFF/0;OFF/0;OFF/0;OFF/0;OFF;OFF;OFF;OFF;OFF;OFF;OFF;OFF;OFF/0;OFF/0;OFF/0;OFF/0;OFF/0;OFF/0;OFF/0;OFF;OFF;OFF;OFF;OFF;OFF;OFF;ON;temp:0.00/hum:0.00;;OFF;OFF;;OFF;256;ON
    
    
    

    По логу видно, что сервер дает команду контроллеру не по 80-му порту… сравните действие 29.01 11:31:39.0554 и 29.01 11:31:39.0661 localhost

    Лог при redirect:

    29.01 11:39:24.0895 192.168.12.21 => localhost:10021 HTTP GET /mod_megad.php?st=1
    29.01 11:39:24.0900 192.168.12.21 <= localhost:10021 
    29.01 11:39:24.0911 Redirect to MG3
    29.01 11:39:24.0913 localhost => 192.168.12.21:80 HTTP GET /sec/?cmd=22:1
    29.01 11:39:24.0915 MG3?22=1&
    29.01 11:39:24.0935 localhost <= 192.168.12.21:80 HTTP Done
    
    


  • @Alex_Jet:

    Если давать команду на включение порта через request, то контроллер не отрабатывает! А если через redirect, то все хорошо.

    По логу видно, что сервер дает команду контроллеру не по 80-му порту… сравните действие 29.01 11:31:39.0554 и 29.01 11:31:39.0661 localhost

    Но включение порта ведь работает через request, если входящий запрос имеет вид /megad?pt=1 ?

    Не работает только для запроса st=1. Порт здесь не при чем.

    Разница в том, что в первом случае сервер отвечает на входящий запрос (слушает порт 10021 и просто посылает команду В ОТВЕТ на запрос).

    Если порт вывести - это будет просто динамически назначенный порт входящего запроса.

    192.168.12.21 => localhost:10021 HTTP GET /mod_megad.php?st=1 - Request от MegaD
    192.168.12.21 <= localhost:10021 22:1 - Response на request, кто послал, тому и отвечаем.
    
    
    

    Во втором случае - инициатива исходит от сервера, поэтому от адресуется к IP и порту.

    Если послать такую команду, то она работает, неважно, какой перед этим был запрос.

    localhost => 192.168.12.21:80 HTTP GET /sec/?cmd=22:1 - Request от сервера
    localhost <= 192.168.12.21:80 HTTP Done - Response на request от MegaD
    
    
    

    Сейчас реакция на сообщения так и реализована: если прописываете Response в ответ на Request - работает по первому варианту.

    Если через Redirect - по второму.



  • Да, вы во всем правы!

    Для удобства использования redirect необходим столбец с признаком наличия хотя бы одного правила для redirect у соответствующего request. Иначе при большом количестве request сложно соориентироваться у каких есть redirect.


Log in to reply