Heim > Backend-Entwicklung > Golang > Senden von IoT-Gerätedaten über einen MQTT-Broker.

Senden von IoT-Gerätedaten über einen MQTT-Broker.

Patricia Arquette
Freigeben: 2024-09-23 14:19:29
Original
1021 Leute haben es durchsucht

Sending IoT Device Data via MQTT broker.

In einem früheren Beitrag haben wir gezeigt, wie man mithilfe eines MQTT-Brokers Nachrichten von IoT-Geräten sendet und empfängt. In diesem Beitrag erweitern wir diese Idee auf ein Beispiel aus der Praxis.

Angenommen, Sie haben ein IoT-Gerät, das Temperatur und Luftfeuchtigkeit in einem Gewächshaus misst (Es ist nicht schwer, eines mit Raspberry Pi oder Arduino herzustellen).

Wir möchten die Gewächshausbedingungen von einem anderen Computer oder vielleicht von einem zentralen Protokollierungsdienst aus fernüberwachen. Im vorherigen Beitrag haben wir eine Go-Implementierung des Codes zum Senden von Nachrichten gezeigt, daher werden wir dieses Beispiel erweitern.

Anstatt nur eine Zeichenfolge mit der Aufschrift „Temperatur ist x, Luftfeuchtigkeit ist y“ zu senden, definieren wir eine Struktur für die Nachricht und das Gerät. Bedenken Sie, dass Sie ein Gerät zur Überwachung von Feuchtigkeit oder Niederschlag haben (oder in Zukunft hinzufügen möchten) und dieses auch anschließen möchten.

Um die Möglichkeit mehrerer Geräte und Typen offen zu lassen, benötigen wir ein Datenmodell, um damit umzugehen.

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
}
Nach dem Login kopieren

Die Nachrichtenstruktur ist das, was an den MQTT-Broker gesendet wird. Wir haben eine Schnittstelle erstellt, um die gemeinsamen Attribute unserer IoT-Geräte zu verarbeiten und die Details der spezifischen Geräte zu abstrahieren.

Das TempRHDevice ist unser Gerät, das Temperatur und Luftfeuchtigkeit misst. Es implementiert die Geräteschnittstelle und kann daher in einer Nachricht verwendet werden.

Als nächstes müssen wir die Nachricht an den Broker senden. Der Einfachheit halber verwenden wir in diesem Beispiel das JSON-Format. Beachten Sie, dass wir in einem großen System mit Tausenden oder mehr Geräten möglicherweise ein kompakteres Format verwenden möchten.

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

Go macht das Marshalling in JSON ziemlich einfach. Nach dem Marshalling wird die JSON-Nachricht an den Broker gesendet.

Was möchten wir sonst noch mit den Daten machen, wenn wir sie haben: Sie in einer Datenbank speichern, auf einem Dashboard anzeigen, die Werte auf Alarmbedingungen überprüfen. Wir müssen den JSON konvertieren, um ihn nutzbar zu machen.

Auf der Empfangsseite müssen wir nur den JSON in eine Struktur entmarshalieren. Wir verwenden eine ähnliche Struktur wie auf der Absenderseite. Wir brauchen jedoch eine Möglichkeit zum Unmarshalieren in einen konkreten Typ und nicht in die Geräteschnittstelle in Message. Wir werden Message eine benutzerdefinierte Unmarshal-Methode hinzufügen, um den Code ebenfalls etwas sauberer zu machen

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
    }

...

Nach dem Login kopieren

An dieser Stelle sei darauf hingewiesen, dass diese Methode komplizierter wird, wenn weitere Gerätetypen hinzugefügt werden. Wie erkennt die UnmarshalJSON-Methode beispielsweise, welchen Gerätetyp die Nachricht enthält? Wir könnten in UnmarshalJSON eine clevere Logik verwenden, um den Typ zu erkennen.

Bedenken Sie als weitere Alternative, dass MQTT zum Veröffentlichen in mehreren Themen verwendet werden kann und es gängige Praxis ist, eine hierarchische Namenskonvention für Themen zu verwenden. Im Falle mehrerer Gerätetypen im Gewächshausbeispiel besteht die empfohlene Vorgehensweise darin, unterschiedliche Gerätetypen zu unterschiedlichen Themen veröffentlichen zu lassen. So werden wir künftig vorgehen, wenn wir neue Gerätetypen hinzufügen.

Im Gewächshaus-Beispiel könnten die Themennamen wie folgt aufgebaut sein:

/greenhouse/temprh/deviceid
/greenhouse/moisture/deviceid
Nach dem Login kopieren

In MQTT können wir Themen mit einem Platzhalterthema abonnieren, wie zum Beispiel:

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

was mit allen Geräten im Gewächshaus-Namespace übereinstimmt. Dann müssten wir nur noch Logik zu „processMsg()“ hinzufügen, um uns das Thema der eingehenden Nachricht anzusehen und zu wissen, wie man sie entmarshallt.

Da wir nun eine Gerätemeldung in verwendbarer Form haben, fragen wir uns, was damit geschehen soll. Im nächsten Beitrag dieser Reihe demonstrieren wir unseren Ansatz, die Nachricht in PostGres beizubehalten.

Wie üblich finden Sie hier den vollständigen Quellcode des Absenders und hier den Abonnentencode.

Teilen Sie mir Ihre Gedanken in den Kommentaren mit.

Danke!

Das obige ist der detaillierte Inhalt vonSenden von IoT-Gerätedaten über einen MQTT-Broker.. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage