Git Product home page Git Product logo

smarthub's Introduction


Проект SmartHome


Навигация

Функции, которые должны быть реализованы:

  • Научитесь подключаться к серверу и выполнять HTTP POST запросы на сервер, передавая ему уже готовые закодированные сообщения.
  • Научитесь кодировать и декодировать URL-encoded unpadded base64 для отправки на сервер и приёма данных от сервера.
  • Научитесь кодировать и декодировать пакеты из бинарной формы в ваше внутреннее представление.
  • Научитесь выявлять структуру сети устройств с помощью WHOISHERE. Научитесь управлять одной лампой и одним выключателем. Реализуйте весь требуемый функционал.

Условие задачи(проекта):

Напишите программу, которая реализует функции хаба умного дома. В умном доме размещены сенсоры, то есть устройства, измеряющие параметры окружающей среды, актуаторы, то есть устройства, воздействующие на среду в доме, таймер, передающий показания текущего времени, и хаб, то есть устройство, которое управляет всеми остальными устройствами в умном доме. Все устройства находятся в общей коммуникационной среде сети. Информация по сети передаётся с помощью пакетов. Пакет может отправляться одному устройству, либо всем устройствам одновременно broadcast. Каждое устройство, включая хаб, имеет свой уникальный 14-битный адрес в сети. Коммуникационная среда ненадёжна, то есть пакеты могут в сети теряться либо портиться, но пакеты не дублируются, то есть ситуация, когда получатель получает один и тот же пакет несколько раз, невозможна. Для моделирования функциональности хаба умного дома ваша программа должна получать данные из сети, и в качестве реакции на полученные данные отправлять данные в сеть. В рамках данной задачи получение данных из сети и отправка данных в сеть моделируется с помощью HTTP POST запроса на специальный сервер, который моделирует функционирование остальных устройств умного дома.

Описание формата пакетов

Для описания формата данных, передаваемых по сети, используются следующие типы данных:

  • byte — беззнаковое 8-битное значение (октет).

  • bytes — массив байтов переменного размера, этот тип должен конкретизироваться в описании конкретных форматов пакетов в зависимости от типа пакета и типа устройства.

  • string — строка. Первый байт строки хранит ее длину, затем идут символы строки, в строке допустимы символы (байты) с кодами 32-126 (включительно).

  • varuint — беззнаковое целое число в формате ULEB128.

  • []T — массив элементов типа T, первый байт памяти, отводимой под массив, это длина массива, далее следуют байты, кодирующие элементы массива.

  • struct — структура, состоящая из полей произвольного типа. Структура может иметь переменный размер, поскольку поля структуры могут иметь переменный размер, например varuint, string, и т. п.

Каждый пакет, передаваемый по сети, описывается следующим образом:

type packet struct {
  length byte
  payload bytes
  crc8 byte
};

Где:

  • length — это размер поля payload в октетах (байтах);
  • payload — данные, передаваемые в пакете, конкретный формат данных для каждого типа пакета описывается ниже;
  • crc8 — контрольная сумма поля payload, вычисленная по алгоритму cyclic redundancy check 8

Полезная нагрузка (поле payload) имеет следующую структуру:

type payload struct {
  src varuint
  dst varuint
  serial varuint
  dev_type byte
cmd byte
  cmd_body bytes
};

Где:

  • src - это 14-битный “адрес” устройства-отправителя;
  • dst - 14-битный “адрес” устройства-получателя, причем адреса 0x0000 и 0x3FFF (16383) зарезервированы. Адрес 0x3FFF означает “широковещательную” рассылку, то есть данные адресованы всем устройствам одновременно;
  • serial - это порядковый номер пакета, отправленного устройством, от момента его включения. serial нумеруется с 1;
  • dev_type - это тип устройства, к которому относится пакет; cmd - это команда протокола;
  • cmd_body - формат которого зависит от команды протокола. Тип устройства dev_type и команда cmd в совокупности определяют данные, которые передаются в cmd_body, как будет описано далее. Обратите внимание, что dev_type - это тип устройства, к которому относится данная команда. Например, если хаб посылает лампе команду на включение SETSTATUS, то и dev_type у соответствующего пакета должен быть равен 4 (лампа).

Описание команд протокола (cmd)

  • 0x01 - WHOISHERE — отправляется устройством, желающим обнаружить своих соседей в сети. Адрес рассылки dst должен быть широковещательным 0x3FFF. Поле cmd_body описывает характеристики самого устройства в виде структуры:
type device struct {
  dev_name string
  dev_props bytes
};

Содержимое dev_props определяется в зависимости от типа устройства.

  • 0x02 - IAMHERE — отправляется устройством, получившим команду WHOISHERE, и содержит информацию о самом устройстве в поле cmd_body. Команда IAMHERE отправляется строго в ответ на WHOISHERE. Команда отправляется на широковещательный адрес.
  • 0x03 - GETSTATUS — отправляется хабом какому-либо устройству для чтения состояния устройства. Если устройство не поддерживает команду GETSTATUS (например, таймер), команда игнорируется. Поле cmd_body должно быть пустым.
  • 0x04 - STATUS — отправляется устройством хабу и как ответ на запросы GETSTATUS, SETSTATUS, и самостоятельно при изменении состояния устройства. Например, переключатель (switch) отправляет сообщение STATUS в момент переключения. В этом случае адресом получателя устанавливается устройство, которое последнее отправило данному устройству команду GETSTATUS. Если такой команды ещё не поступало, сообщение STATUS не отправляется никому.
  • 0x05 - SETSTATUS — отправляется хабом какому-либо устройству, чтобы устройство изменило свое состояние, например, чтобы включилась лампа. Если устройство не поддерживает изменение состояния (например, таймер), команда игнорируется. dev_type должно устанавливаться в тип устройства, для которого предназначено сообщение.
  • 0x06 - TICK — тик таймера, отправляется таймером. Периодичность отправления не гарантируется, но если на некоторый момент времени запланировано событие, то срабатывание события должно наступать, когда время, передаваемое в сообщении TICK становится больше или равно запланированному. Поле cmd_body содержит следующие данные:
type timer_cmd_body struct {
  timestamp varuint
};

Типы устройств

  • 0x01 - SmartHub — это устройство, которое моделирует ваша программа, оно единственное устройство этого типа в сети;
  • 0x02 - EnvSensor — датчик характеристик окружающей среды (температура, влажность, освещенность, загрязнение воздуха);
  • 0x03 - Switch — переключатель;
  • 0x04 - Lamp — лампа;
  • 0x05 - Socket — розетка;
  • 0x06 - Clock — часы, которые широковещательно рассылают сообщения TICK. Часы гарантрированно присутствуют в сети и только в одном экземпляре.

Сценариии работы

Версия 0.2.0 поддерживает два сценария работы.

Сценарий 1

В этом сценарии в сети находится единственное устройство - таймер с именем TIMER01. Таймер шлёт сообщения о текущем времени каждые 100мс модельного времени.

Сценарий 2

В этом сценарии в сети находится таймер TIMER01, лампа LAMP02 и выключатель SWITCH03, коммутированный с лампой. Выключатель изначально находится в состоянии "выключен" и периодически меняет свое состояние. Таймер шлет сообщения о текущем времени каждые 100мс модельного времени.

Кодирование и декодирование пакетов

Демо-сервер может использоваться как утилита для кодирования и декодирования пакетов.

Обратите внимание, что JSON-формат используется только для отладочных целей. По сети передаются пакеты в бинарном формате, закодированные в Base64.

Опция -B выполняет декодирование пакета из base64 в JSON-форму, например, если выполнить из командной строки Unix команду

echo DbMG_38BBgaI0Kv6kzGK | ./smarthome -B

на стандартный поток вывода будет напечатано

[
    {
        "length": 13,
        "payload": {
            "src": 819,
            "dst": 16383,
            "serial": 1,
            "dev_type": 6,
            "cmd": 6,
            "cmd_body": {
                "timestamp": 1688984021000
            }
        },
        "crc8": 138
    }
]

Опция -J выполняет преобразование из JSON-представления в base64-представления для отправки. Например, если запустить из командной строки команду

./smarthome -J

и на стандартном потоке ввода ввести

[
    {
        "length": 13,
        "payload": {
            "src": 819,
            "dst": 16383,
            "serial": 1,
            "dev_type": 6,
            "cmd": 6,
            "cmd_body": {
                "timestamp": 1688984021000
            }
        },
        "crc8": 138
    }
]

на стандартный поток вывода будет напечатано

DbMG_38BBgaI0Kv6kzGK

Опция -K выполняет преобразование из JSON-представления в бинарное представление. Так можно посмотреть, как представляется пакет в бинарной форме до его кодирования в Base64. Например, если запустить из командной строки команду

./smarthome -K | hexdump -C

и на стандартном потоке ввода ввести

[
    {
        "length": 13,
        "payload": {
            "src": 819,
            "dst": 16383,
            "serial": 1,
            "dev_type": 6,
            "cmd": 6,
            "cmd_body": {
                "timestamp": 1688984021000
            }
        },
        "crc8": 138
    }
]

на стандартный поток вывода будет напечатано

00000000  0d b3 06 ff 7f 01 06 06  88 d0 ab fa 93 31 8a     |.............1.|

Внимание! Команды даны в предположении, что вы используете Linux или MacOS. В windows соответствующие команды могут быть другими.

Примеры пакетов

Ниже приведены примеры пакетов в base64 для всех возможных пар из типа устройства и команды.

  • SmartHub, WHOISHERE (1, 1): DAH_fwEBAQVIVUIwMeE
  • SmartHub, IAMHERE (1, 2): DAH_fwIBAgVIVUIwMak
  • EnvSensor, WHOISHERE (2, 1): OAL_fwMCAQhTRU5TT1IwMQ8EDGQGT1RIRVIxD7AJBk9USEVSMgCsjQYGT1RIRVIzCAAGT1RIRVI03Q
  • EnvSensor, IAMHERE (2, 2): OAL_fwQCAghTRU5TT1IwMQ8EDGQGT1RIRVIxD7AJBk9USEVSMgCsjQYGT1RIRVIzCAAGT1RIRVI09w
  • EnvSensor, GETSTATUS (2, 3): BQECBQIDew
  • EnvSensor, STATUS (2, 4): EQIBBgIEBKUB4AfUjgaMjfILrw
  • Switch, WHOISHERE (3, 1): IgP_fwcDAQhTV0lUQ0gwMQMFREVWMDEFREVWMDIFREVWMDO1
  • Switch, IAMHERE (3, 2): IgP_fwgDAghTV0lUQ0gwMQMFREVWMDEFREVWMDIFREVWMDMo
  • Switch, GETSTATUS (3, 3): BQEDCQMDoA
  • Switch, STATUS (3, 4): BgMBCgMEAac
  • Lamp, WHOISHERE (4, 1): DQT_fwsEAQZMQU1QMDG8
  • Lamp, IAMHERE (4, 2): DQT_fwwEAgZMQU1QMDGU
  • Lamp, GETSTATUS (4, 3): BQEEDQQDqw
  • Lamp, STATUS (4, 4): BgQBDgQEAaw
  • Lamp, SETSTATUS (4, 5): BgEEDwQFAeE
  • Socket, WHOISHERE (5, 1): DwX_fxAFAQhTT0NLRVQwMQ4
  • Socket, IAMHERE (5, 2): DwX_fxEFAghTT0NLRVQwMc0
  • Socket, GETSTATUS (5, 3): BQEFEgUD5A
  • Socket, STATUS (5, 4): BgUBEwUEAQ8
  • Socket, SETSTATUS (5, 5): BgEFFAUFAQc
  • Clock, IAMHERE (6, 2): Dgb_fxUGAgdDTE9DSzAxsw
  • Clock, TICK (6, 6): DAb_fxgGBpabldu2NNM

Что реализовано ?

  • Сценарий_1 (В этом сценарии в сети находится единственное устройство - таймер с именем TIMER01. Таймер шлёт сообщения о текущем времени каждые 100мс модельного времени.)
  • Сценарий_2 (В этом сценарии в сети находится таймер TIMER01, лампа LAMP02 и выключатель SWITCH03, коммутированный с лампой. Выключатель изначально находится в состоянии "выключен" и периодически меняет свое состояние. Таймер шлет сообщения о текущем времени каждые 100мс модельного времени.)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.