前の投稿では、MQTT ブローカーを使用して IoT デバイスからメッセージを送受信する方法を示しました。この投稿では、そのアイデアを現実世界の例に拡張します。
温室内の温度と湿度を測定する IoT デバイスがあるとします (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 ブローカーに送信されるものです。私たちは、IoT デバイスの共通属性を処理し、特定のデバイスの詳細を抽象化するインターフェイスを作成しました。
TempRHDevice は、温度と湿度を測定する当社のデバイスです。 Device インターフェイスを実装しているため、Message で使用できます。
次に、メッセージをブローカーに送信する必要があります。この例では、簡単にするために 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 の Device インターフェイスではなく、具体的な型にアンマーシャリングする方法が必要です。コードをもう少しすっきりさせるために、メッセージにカスタムのアンマーシャル メソッドを追加します
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 } ...
デバイスの種類が増えると、この方法が複雑になることをここで指摘するのは適切です。たとえば、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) }
これは、温室名前空間内のすべてのデバイスと一致します。その場合は、 processMsg() にロジックを追加して、受信メッセージのトピックを調べて、それをアンマーシャリングする方法を知る必要があります。
使用可能な形式のデバイス メッセージが得られたので、それをどうするかです。このシリーズの次の投稿では、PostGres でメッセージを永続化するアプローチを示します。
いつものように、送信者の完全なソース コードはここにあり、サブスクライバ コードはここにあります。
コメント欄であなたのご意見をお聞かせください。
ありがとうございます!
以上がMQTT ブローカー経由で IoT デバイス データを送信します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。