«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Отправка данных устройства IoT через брокер MQTT.

Отправка данных устройства IoT через брокер MQTT.

Опубликовано 8 ноября 2024 г.
Просматривать:339

Sending IoT Device Data via MQTT broker.

В предыдущем посте мы показали, как отправлять и получать сообщения с устройств IoT с помощью брокера MQTT. В этом посте мы распространим эту идею на реальный пример.

Предположим, у вас есть устройство Интернета вещей, которое измеряет температуру и влажность в теплице (Нетрудно сделать его с помощью Raspberry Pi или Arduino).

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

Вместо того, чтобы просто отправлять строку «температура — x, влажность — y», давайте определим структуру сообщения и устройства. Предположим, у вас есть (или вы хотите добавить в будущем) устройство для мониторинга влажности или осадков, и вы также хотите подключить его.

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

type Message struct {
    Time   time.Time `json:"time"`
    Device Device    `json:"device"`
}

type Device interface {
    ID() string
    Name() string
}

type TempRHDevice struct {
    Id         string  `json:"id"`
    DeviceName string  `json:"name,omitempty"`
    Temp       float32 `json:"temp,omitempty"`
    Rh         float32 `json:"rh,omitempty"`
}

func (t TempRHDevice) ID() string {
    return t.Id
}

func (t TempRHDevice) Name() string {
    return t.DeviceName
}

Структура сообщения — это то, что будет отправлено брокеру MQTT. Мы создали интерфейс для обработки общих атрибутов наших устройств Интернета вещей и абстрагирования деталей конкретных устройств.

TempRHDevice — это наше устройство, которое измеряет температуру и влажность. Он реализует интерфейс устройства, поэтому его можно использовать в сообщении.

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

message := generateRandomMessage()
payload, err := json.Marshal(message)
if err != nil {
    panic(err)
}
token := client.Publish(topic, 0, false, payload)

Go упрощает маршалинг в JSON. После маршалирования сообщение json отправляется брокеру.

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

На принимающей стороне нам просто нужно демаршалировать json в структуру. Мы будем использовать структуру, аналогичную той, которая используется на отправляющей стороне; но нам нужен способ демаршалинга в конкретный тип, а не интерфейс устройства в сообщении. Мы добавим собственный метод демаршалинга в Message, чтобы сделать код немного чище

type rawMessage struct {
    Time   time.Time `json:"time"`
    Device TempRHDevice    `json:"device"`
}
func (m *Message) UnmarshalJSON(data []byte) error {
    var raw rawMessage
    if err := json.Unmarshal(data, &raw); err != nil {
        return err
    }
    m.Time = raw.Time
    m.Device = &raw.Device
    return nil
}

...

func processMsg(ctx context.Context, ....

...

    case msg, ok := 



Здесь уместно отметить, что этот метод усложняется при добавлении большего количества типов устройств. Например, как метод UnmarshalJSON узнает, какой тип устройства содержит сообщение. Мы могли бы использовать хитрую логику в UnmarshalJSON, чтобы определить тип.

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

В примере с теплицей названия тем могут быть структурированы следующим образом:

/greenhouse/temprh/deviceid
/greenhouse/moisture/deviceid

В MQTT мы можем подписаться на темы, используя тему с подстановочным знаком, например:

if token := client.Subscribe("/greenhouse/#", 0, nil); token.Wait() && token.Error() != nil {
        fmt.Println(token.Error())
        os.Exit(1)
    }

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

Теперь, когда у нас есть сообщение устройства в удобной для использования форме, что с ним делать? В следующем посте этой серии мы продемонстрируем наш подход к сохранению сообщения в PostGres.

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

Поделитесь своим мнением в комментариях.

Спасибо!

Заявление о выпуске Эта статья воспроизведена по адресу: https://dev.to/johnscode/sending-iot-device-data-via-mqtt-broker-3ji6?1. В случае нарушения авторских прав свяжитесь с [email protected], чтобы удалить ее.
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3