Smart Home Protocol

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


Для ясности:
• Контроллер – главное устройство в сети, например компьютер, в одной сети – один контроллер
• Устройство – что угодно что подключено к сети, например микроконтроллер

Теперь о протоколе. Он основан на RS-485 и 9-битном USART’е. Каждому устройству в сети полуавтоматически присваивается уникальный адрес, также имеется broadcast адрес. Что такое полуавтоматически? Мне не хотелось присваивать адрес устройству во время прошивки, либо с помощью каких-либо перемычек, так что я придумал следующую схему: новое устройство имеет адрес 77, чтобы подключить его к сети, можно прямо во время её работы подключить устройство, а затем отправить ему команду смены адреса, т.о. устройство будет иметь уникальный адрес, и может немедленно приступать к работе. Также чтобы не хранить никакие списки устройств, был придуман следующий алгоритм их поиска в сети: главное устройство отправляет broadcast команду enumerate, и каждое устройство через интервал времени равный произведению его адреса на какое-то число (например 10мс думаю этого будет достаточно), отправит в сеть свой адрес.

Для опроса устройств также придуман хитрый способ: контроллер отправляет в сеть broadcast команду 99 (пока не придумал ей названия), после чего устройства которые хотят что-то передать должны отправить в сеть свой адрес (также через определенное время, зависящее от адреса устройства). После чего контроллер опросит нужные устройства.

Естественно не осталось без внимания и энергосбережение: каждое устройство будет иметь свой уровень питания (число от 0 до 7 например) когда основной источник питания отключится и система будет питаться от батарей, можно будет с помощью broadcast сообщений переводить группы устройств в спящий режим.

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

Команды, (описание дальше):

Коды ошибок (будет пополняться):

Действие

(action) – подобие слота в Qt. Например unlock() у дверного замка. Значения не возвращает.

Событие

(event) – подобие сигнала в Qt, генерируется устройством когда что либо происходит, и устройство хочет сообщить об этом, например switchPressed().

Функция

– также выполняется устройством, например bool setPassword(string pass)
Действия, события и функции могут иметь аргументы. Функция может иметь возвращаемое значение.

Передача данных.
Любые данные в сети передаются следующим образом:
1) Контроллер: 1 байт (адрес). <254 – общаемся с одним устройством, 255 — со всеми. (9 бит установлен)
2) Контроллер: 2 байта (размер)
3) Контроллер: Данные
4) Устройство (если адрес не 255): код ошибки
5) Устройство: размер ответа (может быть 0, тогда ответа нет)
6) Устройство: данные (если размер не 0)
7) Тут бы ещё добавить чек сумму, что посоветуете чтобы не сильно нагружало мк?

Если устройство вместо ответа ничего не отправляет в течение 300мс, то считается что с ним проблемы.
Под данными подразумевается что угодно. Устройство определяет что от него хотят по номеру команды (см. выше таблицу Команды). Контроллер и так знает что хочет получить (т.к. он отправлял команду устройству(ам)).

Теперь описание команд.

7 – enumerate devices (B).
Как уже говорилось, это команда поиска устройств в сети. Контроллер отправляет в сеть следующую последовательность:
1) 255 (broadcast)
2) Uint16(1) – длина сообщения, 2 байта
3) 7
4) Чек сумма (пока неизвестно как будет выглядеть)
Затем устройства через определенные промежутки времени отправляют свой адрес. Т.о. контроллер узнаёт какие устройства есть в сети.

11 – declare actions.
В ответ на эту команду устройство должно отправить список имеющихся действий с типами и названиями аргументов.
Контроллер: адрес, uint16(1), 11, чек сумма(?)
Устройство:
1) Длина ответа (uint16)
2) Количество действий (uint8)
3) Сами действия

Действие это:
1) Название действия (string)
2) Количество аргументов (uint8)
3) Аргументы

Аргумент в свою очередь это:
1) Тип аргумента (uint8) — см. таблицу Типы данных выше
2) Имя аргумента (string)

Например, устройство может отправить в ответ следующую последовательность:
declare actions:
66	length
4	# actions

// action "led" with 2 args, 1: uint16 ("state") 2: uint16("r")
108	'l'
101	'e'
100	'd'
0	eos
2	# args
118	'v' uint16
115	's'
116	't'
97	'a'
116	't'
101	'e'
0	eos
118	'v' uint16
114	'r'
0	eos, end of action

// action "add_event" without args
97	'a'
100	'd'
100	'd'
95	'_'
101	'e'
118	'v'
101	'e'
110	'n'
116	't'
0	eos
0	# of args, 0 => no args => end of action

// action "noargs" with 3 args, 1: int8 ("arg1") 2: int8 ("arg2") 3: int8 ("arg3")
110	'n'
111	'o'
97	'a'
114	'r'
103	'g'
115	's'
0	eos
3	# of args
105	'i' int8
97	'a'
114	'r'
103	'g'
49	'1'
0	eos
105	'i' int8
97	'a'
114	'r'
103	'g'
50	'2'
0	eos
105	'i' int8
97	'a'
114	'r'
103	'g'
51	'3'
0	eos, end of action

// action "fnct3" with 1 arg, 1: int8 ("smth")
102	'f'
110	'n'
99	'c'
116	't'
51	'3'
0 	eos
1	# of args
105	'i' int8
115	's'
109	'm'
116	't'
104	'h'
0	eos, end of action, end of actions

12 – declare events.
Тут все аналогично действиям
13 – declare functions.
Здесь есть небольшие отличия, т.к. функция может иметь возвращаемое значение. Функция:
1) Имя (string)
2) Тип возвращаемого значения (uint8)
3) Количество аргументов (uint8)
4) Сами аргументы (см. выше Аргумент).
20 – get device name.
В ответ на эту команду, устройство отправляет строку – своё имя.
21 – set device name.
Установка имени устройства, ответа нет.
25 get device comment
– Комментарий к устройству. Нужно если у вас много устройств, и нужно как то понять какое за что отвечает.
26 set device command
– Установка комментария.
30 exec action
– выполнить действие. Контроллер отправляет номер действия (в том же порядке в котором устройство их отправляло контроллеру), затем идут аргументы, опять же в том же порядке.
31 exec function
– аналогично действию, только устройство может что-либо вернуть в ответ.
40 get new events
– получить новые события, в ответ устройство отправляет количество новых событий, затем номера событий и аргументы.
77 set new addr
– уже рассказывалось выше.
201 power policy changed (b)
– политика питания изменилась. Например батарея разрядилась до какого-то уровня, и не для экономии энергии контроллер посылает сообщение об отключении всех устройств с уровнем питания выше отправленного.
210 get power policy
– получить уровень питания устройства
211 set power policy
– установить уровень питания устройства.
219 power up (b)
– на всякий случай, применения пока не придумал, возможно для повторной инициализации устройств
220 prepare to power down (b)
– перед отключением питания контроллер отправляет всем сообщение об этом, т.о. у устройств есть возможность сохранить необходимые данные.

Также скажу несколько слов о программном обеспечении. Планируется создать 2 программы – серверную и «пользовательскую». С серверной частью думаю всё понятно – к ней будут подключены все сети с устройствами. А «пользовательская» позволит управлять всеми устройствами, создавать различные крутилки-вертелки на основе QML и тд. Для взаимодействия устройств между собой, нужно найти подходящий интерпретатор какого-либо языка (мне понравился picoc, но я не смог скомпилировать его под виндой, и не нашёл в нём способа вызова функции извне). Для программы интерпретатор будет выглядеть как ещё одна сеть, а скрипт – как устройство, со своими действиями, событиями и функциями. Для объединения нескольких серверов, нужно создать ещё одну виртуальную сеть, которая подключиться к удаленному серверу, и через неё станут доступны все устройства удаленного сервера (что-то вроде туннеля). Т.к. скорость RS-485 не позволяет подключить более жирные устройства (например видеокамеры) то можно подключать такие устройства по Ethernet. Т.о. получится чрезвычайно гибкая система, с помощью которой можно будет решить практически любую задачу умного дома, начиная от управления замком на двери, заканчивая компьютерным зрением, распознанием голоса и т.д.

Жду комментарии…
  • -1
  • 17 февраля 2012, 20:59
  • RomiX

Комментарии (13)

RSS свернуть / развернуть
Тема интересная. С удовольствием почитаю о Ваших успехах (и неудачах, конечно, тоже =) )
Ну и пара вопросов:
1. Какие устройства Вы планируете реализовать для своего умного дома?
2. Зачем нужен сервер? Если принцип построен на Qt слотах, то ведь можно сконфигурировать, например, слот устройства сразу на сигнал от другого. Не передавая его через сервер.
3. Ознакамливались ли Вы с сетями BacNet и LonTalk?
0
для начала: контроллер для розеток (реле + мк + включение и отключение по таймеру, по нажатию на кнопку), контроллер освещения(с регулируемой яркостью, на светодиодах), механизм автоматического открытия штор, датчик движения, ir передатчик (для управления теликом и пр техникой), выключатель на основе дальномера (махнул рукой — включился, отвёл руку — изменил яркость) и ещё много всего… сразу так и не вспомнишь

это не совсем Qt слоты, устройства не могут общаться между собой напрямую, событие отправляется на сервер, а там оно может быть сразу перенаправлено в другое(ие) устройства, либо передано скрипту а скрипт уже произведет какие-либо другие действия.

нет не слышал, прочту
0
Если проблема актуальна можно попробовать воплотить в железо.
andrey.michailov@rambler.ru Андрей.
0
и какова цель этого протокола?
даже не могу представить, где нужно столько всего и это не умный дом, а система контроля зданий
т.е. там стоят исполнительные механизмы на разных вентилях и кучи датчиков
+1
взаимодействие самых разных устройств, написание сложных сценариев, распределенные системы, применений можно много придумать, в том числе и умный дом
0
Посмотрите мой проект, может что полезное найдёте :).
Ну и ИМХО надо пытаться раскурить готовый протокол (C-Bus, LonTalk...).
0
По контрольным суммам — распространенные практически никак не нагружают МК.
Я на 16f629 строил систему, которая общалась хэшированными в MurMur2 сообщениями — летало.
0
  • avatar
  • Urvin
  • 18 февраля 2012, 08:18
Сам тоже теперь хочу умный дом.
0
Периодически подумываю эту тему. Очень полезна функция управления нагрузками подключенными к сети, через саму осветительную сеть. По инету искал, но информации очень мало. Может сбросите ссылочку?
0
Проще взять готовое и не морочить голову
например, см. linuxmce.org или pluto
DCE — типа сам протокол. Ищи исходники SendMessage
DCE Router — типа сервер. Есть урезанная версия «Hari Mini», которая (якобы) под шо угодно компилится, в тч под ARM
GSD — работает через последовательный транспорт, напр TCP, RS232, ну или 485, если приспичит.
Практически всё остальное из желаемого автором топика тоже есть.
Берите и пользуйтесь!
Есть ещё с десяток-два готовых открытых протоколов для управления/освещения/съёма данн/опроса/итд, каждый со своими + и -. ИМХО лучше отдать время на их изучение+использование.
0
Если не проблема можете перечислить и дать ссылки на открытые протоколы?
0
а у вас контроллер всегда мастер? устройство может само что-нибудь говорить, не дожидаясь опроса?
0
тож делал сервер с клиентом на диплом кенту, позже переделал на умный дом ))) smart
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.