core5277, продолжение

Небольшое обновление.

Я столкнулся с критической ошибкой в своем ядре. Пришел к выводу, что метод резервирования памяти драйвера(при его инициализации) работает не корректно. Из-за этой причины я не могу закончить пару драйверов.
Поэтому пришлось увеличить заголовок задачи с 10 байт до 13, и приступить к реализации динамического выделения памяти(мелочь, а приятно). Здесь как обычно, ничего нового, просто еще один велосипед. Запланировано три метода ядра - переопределение объема выделенной памяти(изменение размера), выделение дополнительной памяти и освобождение эннного количества байт. При этом, задача или драйвер всегда будет знать сколько памяти ему выделено из заголовка задачи/драйвера. Ну и теперь задача тоже сможет выделять себе память.

Я еще у меня в руках модуль Dipex'а  SIM868 с переферией:
- 1x DS18B20
- 2x I2C EEPROM(вроде на 32KB каждая)
- 1x RS232
- 1x I2C DS3231(часы реального времени)
- 1x RS485
- BK-868 v2.1(2x SIM модуль)

Хорошая борда для реализации драйвера выделения внешней памяти(EEPROM), драйвера часов реального времени и работы с SIM модулем посредством AT комманд.
Кстати, по сути, на этой железке будет задйствовано 2 устройства на I2C шине и 4 UART'а, при этом встроенный только один.

Кстати, как оказалось, не так давно на Speccy появилась достойная ОСь - NedoOS и сетевая карта ZXNetUSB.
Куда мир катится? Как с такими решениями Intel, Microsoft и Google будут шпионить за пользователями? Там ведь, даже в процессор шпиона не встроишь.

Сценарии, начало.

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

  Итак, выбираем в меню 'Настройка сценариев'.


  Мы видим форму групп сценариев, она достаточно проста, здесь можно делать базовые действия с группами: создать, удалить, редактировать, обновить и закрыть. Ничего особенного. Единственное, что необходимо знать - здесь нет механизма блокировки редактирования как в конструкторе(редактор проекта). Описанные операции над группами выполняются сразу же.


Создаем группу.
  Изначальное состояние группы - заблокировано, это означает, что контроллер не будет выполнять сценарии внутри этой группы. Рекомендую снять галку только после описания всех сценариев группы.
Объединение сценариев в группы имеет больше тематический характер, хотя есть и особенность, ведь группу можно включать и отключать(а также можно создать сценарий который будет выполнятся при этих действиях).
Этим можно воспользоваться, к примеру, занести в группу 'Сигнализация' все сценарии отвечающие за контроль дверей и прочее. Ну или скажем создать группу содержащую сценарии имеющие отношение ко временам года(хотя в самих сценариях можно указать периоды работы, например определенные месяцы).
  На этой форме, как и на предыдущей, есть кнопки стандартных действий: добавить, удалить, редактировать, обновить и клонировать. Последняя позволяет быстро сделать копию сценария.
  Также, внизу формы, есть кнопка 'Активировать изменения'. Эта кнопка передает все ваши текущие наработки в данной группе на сервер(или контроллер). До нажатия этой кнопки все изменения хранятся только на данной форме.


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

Создаем сценарий.
  Стандартный заголовок, опять же галка 'заблокировать', имя и комментарий(который можно не заполнять).
Далее идут блоки:
1) Причина запуска - описывает причину запуска, т.е. при каких условиях контроллер приступит к анализу данного сценария.
2) Внешние факторы - по сути это дополнительные условия, которые могут влиять на выполнение сценария, например отменить его анализ или заставить контроллер проигнорировать другие условия(например период действия).
3) Период действия - по сути, это фильтр, позволяет указывать когда разрешать дальнейший анализ сценария.
4) Условие - здесь мы можем задать различные условия на базе показаний от устройств, которые также повлияют на дальнейший анализ сценария.
5) Информирование - а это уже исполнительная часть, ее выполнит контроллер только если предыдущие условия это позволили. Здесь мы можем сказать системе что сообщать и куда сообщать.
6) Управление - тоже исполнительная часть, заключительная. Здесь мы можем указать различные действия, например послать команду конечному исполнительному устройству, или запустить другой сценарий на другом контроллере, или выполнить внешний скрипт на машине где запущен контроллер.


  Теперь детально:
Причина запуска:
1) Запуск группы сценариев - будет запущен при снятии галки 'заблокировать' данной группы. Это полезно, если необходимо при включении группы выполнять ряд действий, например послать всем устройствам управления команду 'вкл'.
2) Только системный вызов - означает что данный сценарий может запустить только другой сценарий.
3) В назначенное время - можно указать время(часы и минуты) когда требуется запустить сценарий, при этом можно указать время для повторного запуска. Контроллер будет выполнять повторы, скажем если было задано время запуска 00:00 с повтором каждый час, а текущее время создания данного сценария скажем 13:45. Т.е. запуск будет выполнен в 14:00, 15:00 и .т.д.


4) Обновление показания устройств - анализ сценария будет запущен когда обновятся данные показаний участвующих в анализе(блок 'Условие')
5) Нажатие виртуальной кнопки - в конструкторе(редактор проекта) можно добавить виртуальную кнопку. Здесь можно описать эту кнопку, таким образом можно запускать сценарий нажатием кнопки устройства в клиенте.


6) Написана/произнесена фраза - запуск осуществляется когда с точки управления(Телеграм, Алиса и прочее) поступает фраза. Здесь выполняется ее анализ. Также можно задать фразу которую получит пользователь в ответ.


7) Случайно - запуск сценария осуществляется случайно, проверка раз в минуту, здесь требуется указать вероятность(1/100 - вероятность 1 раз в 100 минут) т.е. для вероятности раз в две минуты нужно указать 50/100 или 1/2.


8) События от устройств - некоторые устройства могут посылать специальные события, по которым контроллер запускает сценарий.


9) Смена состояния контроллера - здесь речь о соединении с сервером, можно запускать сценарий при успешно
установленном соединении или при недоступности сервера. Также можно указать время ожидания.


10) Смена состояния устройства - аналогично предыдущему, но здесь также можно определять перезагрузку для некоторых устройств.


11) Остановка группы сценариев - аналогично первому пункту, но здесь срабатывает сценарий когда мы ставим галку 'заблокировать'

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


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


3)  В течении периода(расширенная форма) - здесь используется методика планировки задач в crontab. Мы можем указать время, дату и дни недели в течении которых будет продолжен анализ. Используется логическое и. Т.е. если время или дата или день недели не попадает под условие то анализ будет прерван. В полях день, месяц и год можно использовать разделитель ',' и диапазон(через '-'). При наведении на поле появится подсказка.


  Условие
  Пожалуй это самый сложный блок. В нем два элемента 'По показаниям устройств (логическое 'И')' и 'По показаниям устройств (логическое 'ИЛИ')'. Т.е. для успешного анализа, условия правил внутри блока должны быть или все истинны или истинно хотя бы одно соответственно.
  Далее видим кнопки:
  1) Добавить формулу - используется если нам нужно сделать какое-то вычисление на базе показаний в добавленных правилах или констант.
  2) Разрешает повторное выполнение сценария, если мы получили событие от устройства, даже если сам снимок показаний не изменился. Актуально для таких устройств как инфракрасный датчик для ИК пультов. Он может принять одинаковую последовательность данных, что должно быть интерпретировано как еще одна команда.
  3) Разрешает выполнение сценария при первом показании. После запуска контроллера или изменении в проекте существует ситуация, при которой старого значения показания нет, а оно нужно для анализа сценариев. Т.е. анализ выполняется только при изменении показания, отсутствие старого показания не означает, что само показание изменилось. Включенная кнопка означает, что контроллер будет считать, что показание все же изменилось.
  4) Блокировка частого выполнения сценария. Существует внутренний триггер, который после успешного выполнения сценария защелкивается и не позволяет повторное выполнение до тех пор, пока сценарий не пройдет анализ. Таким образом, к примеру,  Вы не будет получать одно и тоже сообщение каждый раз когда контроллер выполнит один и тот же успешный сценарий. Отключение кнопки отключает анализ триггера.
  5) Кнопки + и -  позволяют добавлять правила и удалять выбранное правило.


  Добавим правило.
  Мы увидим дерево устройств, в нем нам нужно выбрать устройство чьи показания мы будем анализировать.


  После выбора появился элемент списка с нашим устройством и внутренним списком условий. Который состоит из номера, названия показания, условия, значения(может иметь разный вид в зависимости от типа показания и условия) и кнопки '+'. Последующие элементы списка имеет кнопку '-', для удаления текущего элемента. Добавление новых элементов осуществляется кнопкой '+' первого элемента(первый элемент удалить нельзя, но можно удалить элемент верхнего уровня).


  Далее. Здесь мы выбираем нужное показание, указываем условие и значение этого условия(можно также указывать диапазоны и пороги).
  Порог нужен для описания работы еще одного триггера - локального триггера для каждого условия. Работает схоже с триггером описанным ранее. Его задача также не допускать повторной отработки сценария.
Принцип следующий. Он срабатывает, когда значение показания достигло указанного условия, т.е. условие истинно только при первом анализе, даже если при повторном значение также достигло указанного условия. Сброс триггера выполняется только тогда, когда показание отклонилось в обратную сторону с учетом дельты в указанный период.
  Т.е. если мы создали условие на температуру больше 20 с порогом в 1, то триггер будет установлен при температуре больше 20 и снят при температуре меньше(20-1).

  Теперь о формулах. Формула также имеет номер , поле для ввода условие и значение для условия. А также кнопку проверки корректности введенной формулы. С помощью меню(правая кнопка мыши) можно подставить показания устройств которые должны быть добавлены заранее. Как и с условиями по показаниям само условие может отсутствовать.


  Таким образом данный функционал позволяет выстраивать цепочки логического 'И' или 'ИЛИ' с любым набором устройств и с любым набором условий для каждого устройства. А также можно добавлять формулы.


Информирование
1)  Никому - блок просто игнорируется
2)  Только мне - информирование будет выполнено только автору сценария
3)  Группе - информирование будет выполнено только для участников группы(пока не реализовано)
4)  Всем - всем в проекте, кто может получать информирование

  Форма для всех типов выглядит одинаково.
  Верхняя часть элементов:
  1)   Метка - в клиенте будет подсвечено красным показания присутствующие в условиях блока 'Условие'
  2)  Сообщение - сообщение будет выведено посредством клиента.
  3)  Телеграм - сообщение получат все пользователи с точкой входа 'Телеграм'
  4)  Эл. почта - аналогично, но для эл. почты.
  5)  СМС - аналогично, но для смс(пока не реализован шлюз, смс стоят денег)
  6)  Звук - на контроллере будет проигран звуковой файл.


  Далее два поля: описание заголовка и основной текст сообщения. Здесь через меню(правая кнопка мыши) можно подставить константы, показания устройства или просто значение показания. Показания выбираются из блока 'Условие'
  Для включенного режима 'Звук' доступны галки повторять(при окончании проигрывания оно будет заново запущено) и 'Останавливать' (проигрывание будет остановлено если при повторном выполнение сценария анализ не был успешно завершен).
  Далее поле для ввода названий файлов, можно перечислять через ',', тогда контроллер будет выбирать файл случайно из указанных. И последнее поле - громкость.

Управление
1) Не управлять - игнорируем данный блок
2)  Управлять устройствами - здесь мы можем добавить несколько устройств, команды которых мы планируем выполнить.
3)  Запуск сценариев - аналогично, здесь мы добавляем сценарии, который планируем выполнить.
4)  Остановка сценариев - аналогично для остановки. На данный момент остановка нужна только для проигрывания звукового файла.
5)  Запуск внешнего скрипта - bash команда или файл выполняется на стороне контроллера
6)  Здесь можно выбрать сценарий, который не принадлежит текущему контроллеру. Т.е. текущий сценарий будет проанализирован скажем на контроллере А, а выполнен сценарий на контроллере Б.



Пример использования
  Это тестовый набор сценариев, обычного термореле(теплый пол). Задача - включать обогрев при температуре меньше или равно 35 градусам и выключать при температуре больше либо равно 36 градусам.

Первый, на включение обогрева.


Второй, на выключение обогрева.



  Заключение
  В общих чертах вроде бы все описал. Конечно есть множество деталей. Но не думаю, что на практике они будут иметь большое значение. Разве только в каких-нибудь очень сложных проектах, однако такой подход я считаю не совсем корректным. Если решение сложное, его должно выполнять специализированное, цельное решение(конечное устройство) а не набор из многих.
  И потом, можно было бы сделать скрипты, которые позволили бы реализовывать более гибкие решения,но на текущем этапе я не сталкивался с задачами, которые нельзя было бы описать здесь без скриптов.

update: добавил картинки

Dipex, взаимодействие устройств без контроллера

Небольшое вступление:

"Dipex Group" - это компания - официальный представитель данного проекта.

Т.е. это общий проект, но есть некоторые отличия:
1) Главное - парк устройств. Устройства отличаются по функционалу, внешнему виду, количеству, логике и даже реализацией шины. Разработка схемотехники устройств и их прошивок отдельная, функционал не заимствуется, разве что элементарных функций.
2) Облаком - при регистрации и авторизации пользователь выбирает площадку, в зависимости от выбора будут использоваться либо сервера Dipex'а, либо мой сервер.
3) Дополнительными сервисами и кастомизацией.

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



И так, речь идет о взаимодействии устройств посредством шины DipexBus, без контроллера.
Как известно, самый распространенный и не дорогой протокол общения железок на шине типа RS485 - Modbus.
На мой взгляд, главный недостаток этого протокола - ведомый(slave) не может инициировать передачу. Т.е. обязательное наличие ведущего(master).
Здесь создан 'свой велосипед', на шине RS485 реализован протокол поддерживающий, кроме всего прочего,  динамическую адресацию и возможность вещать любому узлу независимо от ведущего.

На видео ниже я взял два устройства:
 - датчик температуры и влажности, далее 'Термометр' (также оснащен портом для DS18B20 и контактом, например для обнаружения открытия двери),
- двухканальное реле, далее 'Реле x2' (220В, 4Вт на канал, питание реле - 5В).


https://youtu.be/frVIKQ2P0bQ

Как видно, при размыкании контакта(открытии двери) загорается светодиод на термометре и тут-же отрабатывает реле, при замыкании контакта происходит обратное действие.
Аналогично по относительной влажности, если более 50% отрабатывает второе реле, и обратное действие при влажности менее 50%.

По сути здесь ничего особенного, можно легко запрограммировать конкретное действие на конкретное событие.
Но этот проект является не каким-то решением под определенную задачу, это конструктор, функционал должен быть очень гибким не смотря на то, что здесь рассматривается только линейка устройств Dipex.

И да, есть сценарии. В них можно настроить многое, реализовать гораздо сложнее логику взаимодействия. Но эта логика будет отрабатывать на контроллере. Нет контроллера - нет логики.

В общем, переходим в клиент, и смотрим в меню 'Конфигуратор устройств'.
Эта штука позволяет посредством контроллера считать конфигурацию с устройства(любого, если это вообще возможно и поддержано библиотекой устройства), изменить ее и записать заново.
К примеру, можно назначить modbus устройству адрес на шине(если устройство позволяет задавать адрес программно), ну или какие-нибудь базовые параметры устройства.



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

Т.е. здесь используется контроллер только для разовой записи порогов и триггеров, далее мы его попросту отключили. Остались устройства соединенные шиной и USB платка как источник питания.

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


https://youtu.be/nljlGcW8-PE

Конечно я рассказал не все, например я не стал рассказывать, как устройства обрабатывают коллизии. Но данный протокол проприетарный, поэтому подробностей не будет. Скажу только, что популярные методы CAN open я не использовал. Работает достаточно надежно. Но в любом случае будет также ряд рекомендаций для использования такого режима.

update: обновил битое видео

ZX Spectrum 4ever, описание идеи.

Итак, вступление.

Я олдовый мужик, который до сих пор не забыл Спектрум.
По существу, ZX Spectrum я ассоциирую с работой энтузиастов, т.е. с деятельностью, которая направлена не на выкачивание бабла из людской массы, а на творение с замашками перфекционизма.
А я как бы помешан на этом перфекционизме, особенно учитывая мою патологию в виде мизантропии.

И вот, думаю я следующее - почему бы мне, вместо всяческого разврата, потребления кальмаров с пивами и без них, и прочей обыденной деятельности общества не запилить решение для мною любимого Спектрума? Давно думаю. Но вот проблема, помню очень мало, где взять инструментарий? Нужно же как минимум запилить на Спектруме шлюз писанный на ассемблере. Благо клон Спекрума всегда на рабочем столе(иначе и не может быть). Ну что-же, недавно я показал, что взять Gluon(не клей) и реализовать тяжелое приложение на основные платформы можно быстро и без сказок.
Так чего же боле? Я приступаю к поиску удобного ПО для данной задачи, и путь весь мир идет прахом.

Для тех, кто в танке, та же АTmega может покрыть все технические возможности Spectrum'а. Но, как обычно оно бывает, главное не железо - а общество которое с ним работает. Так что, буду банален - PC must die. А я попробую реализовать как минимум софт для Спекки для управления моими железками, а может быть и контроллером. Еще раз, Spectrum для меня суть моего творчества, всегда так было.

core5277, продолжение

Маленький отчет по работе над своим собственным ядром(ассемблер):

На текущий момент реализованы драйвера:
1) 1wire - шина 1w
2) beeper - проигрывает простые мелодии по нотам
3) ds18b20 - датчик температуры основанный на 1w
4) huart - UART основанный на встроенном UART
5) log - логирование в порт (программный UART 115200-8n1)
6) pcint8 - внешние прерывания(реакция на изменение состотояние пинов) - 8 портов максимум
Также в процессе драйвера:
1) 5277bus - моя собственная шина с большим набором возможностей, для моих устройств(как расширение).
2) buttons - обработчик нажатий кнопок(кол-во не ограничено), обрабатывает до 4 нажатий
3) pcint24 - тоже что и pcint8 но может обрабатывать все порты одновременно.
4) suart - программный UART

Также ядро поддерживает:
1) 16 одновременно выполняемых задач или драйверов
2) Программную(динамическую) настройку обработчиков прерывания
3) 4 свободных программных таймеров(при этом ядро использует только TIMER-0)
4) 64 глобальных флагов
5) 16 байт под переменные каждой задачи или драйвера
6) Динамические стеки задач
7) Выделение памяти под драйвера
8) Само собой многопоточность(переключение задач каждые 4мс)
9) Паузу для задачи/драйвера не менее 500нс(вне многопоточности)
10) Паузу для задачи/драйвера не менее 2мс(с поддержкой многопоточности) + пауза в секундах
11) Отслеживание переполнения памяти
12) Логирования
13) Различные процедуры и утилиты - конвертирование, работы с памятью, портами, математика, работа с флагами и блокировка ресурсов и прочее.
14) Теперь ядро поддерживает кроме Atmega88, еще и Atmega328.

Один проект/блок сценариев и два режима

Где-то ранее я говоил, что мой проект поддерживает несколько режимов подключения клиента.
Среди них есть режим прямого подключения через контроллер и облачный режим.

В режиме прямого подключения через контроллер можно редактировать как сам проект, так и сценарии.
Однако, понятно, что одновременно есть проект в облаке, который также можно редактировать(в том числе и его сценарии).
И возможно мы одновременно имеем два клиента, которые находятся в разных режимах одновременно и имеют отношение к одному и тому же контроллеру.



Ну так вот, я завершаю реализацию данного функционала.
Все очень просто(пример для проекта):
При внесении в контролер локальных изменений он их применяет, и сообщает на север, что у него есть локальные изменения. После чего все подключенные клиенты к серверу получают уведомления(те, в которых авторизировались админы, также клиенты получат уведомление при автоизации). Любой из клиентов отвечает либо согласием на их применение как основных, либо отказом.
В случае применения локальный проект будет передан серверу и принят как основной, в случает отказа контроллер просто вытянет текущий проект с сервера.

Аналгичное действо будет происходить и для сценариев. Баста.

Видео, регистрация проекта и активация контроллера

Следующее мини 'how to'



Здесь я создаю новый проект(подключение к интерент обязательно).
И в нем активирую недавно развернутый контроллер.

Позже будет видео, как регистрировать и активировать контроллер, если у него нет выхода в интернет.

P.S. Да, даже для режима прямого подключения через контроллер необходима облачная регистрация проекта и активация в нем контроллера.

Видео, развертывание контроллера на микрокомпьютере

Очередное мини видео:



Пока инсталляторы не делал, контроллер доступен в виде zip архивов, выбираем нужный, скачиваем, распаковываем, прописывем автозапуск и запускаем.

Остальные действия выполнятся на стороне клиента.

Видео, пример подключения клиента (режим прямого подключения)

Здесь подключение клиента непосредственно к исполнительным устройствам без контроллера и сервера(режим прямого подключения). Функционал в режиме прямого подключения сильно ограничен.

По видео можно оценить пользовательский интерфейс, понять как настраивается проект и немного познакомиться с его возможностями.



В видео включены все необходимые действия, кроме установки клиента, сборки тестового стенда и установки голой ОС на микрокомпьютер(за исключением обновления и установки mc).

А вот демонстрационное видео как это работает: