Maison > développement back-end > Golang > le corps du texte

Envoi de données d'appareil IoT via le courtier MQTT.

Patricia Arquette
Libérer: 2024-09-23 14:19:29
original
983 Les gens l'ont consulté

Sending IoT Device Data via MQTT broker.

Dans un article précédent, nous avons montré comment envoyer et recevoir des messages à partir d'appareils IoT à l'aide d'un courtier MQTT. Dans cet article, nous étendrons cette idée à un exemple concret.

Supposons que vous ayez un appareil IoT qui mesure la température et l'humidité dans une serre (Pas difficile d'en fabriquer un avec Raspberry Pi ou Arduino).

Nous souhaitons surveiller les conditions de la serre à distance depuis un autre ordinateur ou, peut-être, un service d'enregistrement central. Dans l'article précédent, nous avons montré une implémentation Go de code pour envoyer des messages, nous allons donc étendre cet exemple.

Au lieu de simplement envoyer une chaîne disant "la température est x, l'humidité est y", définissons une structure pour le message et l'appareil. Considérez que vous disposez (ou souhaitez ajouter à l’avenir) un appareil pour surveiller l’humidité ou les précipitations et que vous souhaitez également le connecter.

Pour laisser ouverte la possibilité de plusieurs appareils et types, nous avons besoin d'un modèle de données pour gérer cela.

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
}
Copier après la connexion

La structure Message est ce qui sera envoyé au courtier MQTT. Nous avons créé une interface pour gérer les attributs communs de nos appareils IoT et résumer les détails des appareils spécifiques.

Le TempRHDevice est notre appareil qui mesure la température et l'humidité. Il implémente l'interface Device, il peut donc être utilisé dans un message.

Ensuite, nous devons envoyer le message au courtier. Nous utiliserons le format JSON pour sa simplicité dans cet exemple. Notez que dans un système à grande échelle comprenant des milliers d'appareils ou plus, nous souhaiterons peut-être utiliser un format plus compact.

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

Go facilite le marshalling en JSON. Une fois marshalé, le message json est envoyé au courtier.

Que voudrions-nous faire d'autre avec les données une fois que nous les avons : les stocker dans une base de données, les afficher sur un tableau de bord, vérifier les valeurs des conditions d'alarme. Nous devrons convertir le json pour le rendre utilisable.

Du côté de la réception, il nous suffit de désorganiser le json dans une structure. Nous utiliserons une structure similaire à celle utilisée du côté expéditeur ; mais nous avons besoin d'un moyen de transformer en un type concret plutôt que l'interface Device dans Message. Nous ajouterons une méthode de démarshal personnalisée sur Message pour rendre le code un peu plus propre également

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 := <-input:
    if !ok {
        return
    }
    logger.Info().Msg(fmt.Sprintf("Received message: %s from topic: %s\n", msg.Payload(), msg.Topic()))
    var iotMsg Message
    err := json.Unmarshal(msg.Payload(), &iotMsg)
    if err != nil {
        logger.Error().Err(err).Msg("Error unmarshalling Message")
    } else {
        out <- iotMsg
    }

...

Copier après la connexion

Il convient de souligner ici que cette méthode se complique lorsque d'autres types d'appareils sont ajoutés. Par exemple, comment la méthode UnmarshalJSON saura-t-elle quel type de périphérique contient le message. Nous pourrions faire une logique intelligente dans UnmarshalJSON pour détecter le type.

Pour une autre alternative, n'oubliez pas que MQTT peut être utilisé pour publier sur plusieurs sujets et qu'il est courant d'utiliser une convention de dénomination hiérarchique pour les sujets. Ainsi, dans le cas de plusieurs types d'appareils dans l'exemple de serre, la méthode recommandée consiste à publier différents types d'appareils sur différents sujets. C’est ainsi que nous procéderons à l’avenir à mesure que nous ajouterons de nouveaux types d’appareils.

Dans l'exemple de la serre, les noms des sujets pourraient être structurés comme :

/greenhouse/temprh/deviceid
/greenhouse/moisture/deviceid
Copier après la connexion

Dans MQTT, nous pouvons nous abonner à des sujets en utilisant un sujet générique, tel que :

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

qui correspondra à tous les appareils de l'espace de noms de la serre. il nous suffirait alors d'ajouter une logique à processMsg() pour examiner le sujet du message entrant afin de savoir comment le désorganiser.

Maintenant que nous avons un message sur l'appareil sous une forme utilisable, que faut-il en faire ? Dans le prochain article de cette série, nous démontrerons notre approche pour conserver le message dans PostGres.

Comme d'habitude, le code source complet de l'expéditeur peut être trouvé ici et le code d'abonné peut être trouvé ici.

Faites-moi part de vos commentaires dans les commentaires.

Merci !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!