mqtt

package module
v0.0.0-...-6a0c198 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 29, 2021 License: MIT Imports: 13 Imported by: 42

README

API Reference

  • Host: <Region>.thethings.network, where <Region> is last part of the handler you registered your application to, e.g. eu.
  • Port: 1883, or 8883 for TLS
  • For TLS, the server uses a Let's Encrypt certificate. If your server does not trust that yet, you might want to include the Let's Encrypt Roots in your certificate chain. Alternatively you can use our PEM-encoded CA certificate, which includes those roots as well: mqtt-ca.pem
  • Username: Application ID
  • Password: Application Access Key

Topic: <AppID>/devices/<DevID>/up

Message:

{
  "app_id": "my-app-id",              // Same as in the topic
  "dev_id": "my-dev-id",              // Same as in the topic
  "hardware_serial": "0102030405060708", // In case of LoRaWAN: the DevEUI
  "port": 1,                          // LoRaWAN FPort
  "counter": 2,                       // LoRaWAN frame counter
  "is_retry": false,                  // Is set to true if this message is a retry (you could also detect this from the counter)
  "confirmed": false,                 // Is set to true if this message was a confirmed message
  "payload_raw": "AQIDBA==",          // Base64 encoded payload: [0x01, 0x02, 0x03, 0x04]
  "payload_fields": {},               // Object containing the results from the payload functions - left out when empty
  "metadata": {
    "airtime": 46336000,              // Airtime in nanoseconds
    "time": "1970-01-01T00:00:00Z",   // Time when the server received the message
    "frequency": 868.1,               // Frequency at which the message was sent
    "modulation": "LORA",             // Modulation that was used - LORA or FSK
    "data_rate": "SF7BW125",          // Data rate that was used - if LORA modulation
    "bit_rate": 50000,                // Bit rate that was used - if FSK modulation
    "coding_rate": "4/5",             // Coding rate that was used
    "gateways": [
      {
        "gtw_id": "ttn-herengracht-ams", // EUI of the gateway
        "timestamp": 12345,              // Timestamp when the gateway received the message
        "time": "1970-01-01T00:00:00Z",  // Time when the gateway received the message - left out when gateway does not have synchronized time
        "channel": 0,                    // Channel where the gateway received the message
        "rssi": -25,                     // Signal strength of the received message
        "snr": 5,                        // Signal to noise ratio of the received message
        "rf_chain": 0,                   // RF chain where the gateway received the message
        "latitude": 52.1234,             // Latitude of the gateway reported in its status updates
        "longitude": 6.1234,             // Longitude of the gateway
        "altitude": 6                    // Altitude of the gateway
      },
      //...more if received by more gateways...
    ],
    "latitude": 52.2345,              // Latitude of the device
    "longitude": 6.2345,              // Longitude of the device
    "altitude": 2                     // Altitude of the device
  }
}

Note: Some values may be omitted if they are null, false, "" or 0.

Usage (Mosquitto): mosquitto_sub -h <Region>.thethings.network -d -t 'my-app-id/devices/my-dev-id/up'

Usage (Go client):

import (
	"github.com/TheThingsNetwork/go-utils/log"
	"github.com/TheThingsNetwork/go-utils/log/apex"
	"github.com/TheThingsNetwork/ttn/core/types"
	"github.com/TheThingsNetwork/ttn/mqtt"
)

func main() {
	ctx := apex.Stdout().WithField("Example", "Go Client")
	log.Set(ctx)

	client := mqtt.NewClient(ctx, "ttnctl", "my-app-id", "my-access-key", "<Region>.thethings.network:1883")
	if err := client.Connect(); err != nil {
		ctx.WithError(err).Fatal("Could not connect")
	}
	token := client.SubscribeDeviceUplink("my-app-id", "my-dev-id", func(client mqtt.Client, appID string, devID string, req types.UplinkMessage) {
		// Do something with the uplink message
	})
	token.Wait()
	if err := token.Error(); err != nil {
		ctx.WithError(err).Fatal("Could not subscribe")
	}
}

Each uplink field will be published to its own topic my-app-id/devices/my-dev-id/up/<field>. The payload will be a string with the value in a JSON-style encoding.

If your fields look like the following:

{
  "water": true,
  "analog": [0, 255, 500, 1000],
  "gps": {
    "lat": 52.3736735,
    "lon": 4.886663
  },
  "text": "why are you using text?"
}

you will see this on MQTT:

  • my-app-id/devices/my-dev-id/up/water: true
  • my-app-id/devices/my-dev-id/up/analog: [0, 255, 500, 1000]
  • my-app-id/devices/my-dev-id/up/gps: {"lat":52.3736735,"lon":4.886663}
  • my-app-id/devices/my-dev-id/up/gps/lat: 52.3736735
  • my-app-id/devices/my-dev-id/up/gps/lon: 4.886663
  • my-app-id/devices/my-dev-id/up/text: "why are you using text?"

Topic: <AppID>/devices/<DevID>/down

Message:

{
  "port": 1,                 // LoRaWAN FPort
  "confirmed": false,        // Whether the downlink should be confirmed by the device
  "payload_raw": "AQIDBA==", // Base64 encoded payload: [0x01, 0x02, 0x03, 0x04]
}

Usage (Mosquitto): mosquitto_pub -h <Region>.thethings.network -d -t 'my-app-id/devices/my-dev-id/down' -m '{"port":1,"payload_raw":"AQIDBA=="}'

Usage (Go client):

for setup, see Uplink Messages

token := client.PublishDownlink(types.DownlinkMessage{
  AppID:   "my-app-id",
  DevID:   "my-dev-id",
  FPort:   1,
  Payload: []byte{0x01, 0x02, 0x03, 0x04},
})
token.Wait()
if err := token.Error(); err != nil {
  ctx.WithError(err).Fatal("Could not publish")
}

Instead of payload_raw you can also use payload_fields with an object of fields. This requires the application to be configured with an Encoder Payload Function which encodes the fields into a Buffer.

Message:

{
  "port": 1,                 // LoRaWAN FPort
  "confirmed": false,        // Whether the downlink should be confirmed by the device
  "payload_fields": {
    "led": true
  }
}

Usage (Mosquitto): mosquitto_pub -h <Region>.thethings.network -d -t 'my-app-id/devices/my-dev-id/down' -m '{"port":1,"payload_fields":{"led":true}}'

Usage (Go client):

for setup, see Uplink Messages

token := client.PublishDownlink(types.DownlinkMessage{
  AppID:   "my-app-id",
  DevID:   "my-dev-id",
  FPort:   1,
  Fields: map[string]interface{}{
    "led": true,
  },
})
token.Wait()
if err := token.Error(); err != nil {
  ctx.WithError(err).Fatal("Could not publish")
}

By default, the downlink will replace the currently scheduled downlink, if any. It is also possible to schedule the downlink as the first or last item in a the downlink queue.

{
  "port": 1,
  "confirmed": false,
  // payload_raw or payload_fields
  "schedule": "replace", // allowed values: "replace" (default), "first", "last"
}

Device Activations

Topic: <AppID>/devices/<DevID>/events/activations

Message:

{
  "app_eui": "0102030405060708", // EUI of the application
  "dev_eui": "0102030405060708", // EUI of the device
  "dev_addr": "26001716",        // Assigned address of the device
  "metadata": {
    // Same as with Uplink Message
  }
}

Usage (Mosquitto): mosquitto_sub -h <Region>.thethings.network -d -t 'my-app-id/devices/my-dev-id/events/activations'

Usage (Go client):

for setup, see Uplink Messages

token := client.SubscribeDeviceActivations("my-app-id", "my-dev-id", func(client Client, appID string, devID string, req Activation) {
  // Do something with the activation
})
token.Wait()
if err := token.Error(); err != nil {
  ctx.WithError(err).Fatal("Could not subscribe")
}

Device Events

Management Events

Created: <AppID>/devices/<DevID>/events/create Updated: <AppID>/devices/<DevID>/events/update Deleted: <AppID>/devices/<DevID>/events/delete

Downlink Scheduled: <AppID>/devices/<DevID>/events/down/scheduled
payload: null

Downlink Sent: <AppID>/devices/<DevID>/events/down/sent

{
  "payload": "Base64 encoded LoRaWAN packet",
  "gateway_id": "some-gateway",
  "config": {
    "modulation": "LORA",
    "data_rate": "SF7BW125",
    "airtime": 46336000,
    "counter": 123,
    "frequency": 868300000,
    "power": 14
  }
}

Downlink Acknowledgements: <AppID>/devices/<DevID>/events/down/acks
payload: null

Error Events

The payload of error events is a JSON object with the error's description.

Uplink Errors: <AppID>/devices/<DevID>/events/up/errors
Downlink Errors: <AppID>/devices/<DevID>/events/down/errors
Activation Errors: <AppID>/devices/<DevID>/events/activations/errors

Example: {"error":"Activation DevNonce not valid: already used"}

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	PublishQoS   byte = 0x00
	SubscribeQoS byte = 0x00
)

QoS indicates the MQTT Quality of Service level. 0: The broker/client will deliver the message once, with no confirmation. 1: The broker/client will deliver the message at least once, with confirmation required. 2: The broker/client will deliver the message exactly once by using a four step handshake.

View Source
var (
	// ConnectRetries says how many times the client should retry a failed connection
	ConnectRetries = 10
	// ConnectRetryDelay says how long the client should wait between retries
	ConnectRetryDelay = time.Second
)
View Source
var RootCAs *x509.CertPool

RootCAs to use in API connections

Functions

This section is empty.

Types

type ActivationHandler

type ActivationHandler func(client Client, appID string, devID string, req types.Activation)

ActivationHandler is called for activations

type AppEventHandler

type AppEventHandler func(client Client, appID string, eventType types.EventType, payload []byte)

AppEventHandler is called for events

type ApplicationTopic

type ApplicationTopic struct {
	AppID string
	Type  ApplicationTopicType
	Field string
}

ApplicationTopic represents an MQTT topic for applications

func ParseApplicationTopic

func ParseApplicationTopic(topic string) (*ApplicationTopic, error)

ParseApplicationTopic parses an MQTT device topic string to an ApplicationTopic struct

func (ApplicationTopic) String

func (t ApplicationTopic) String() string

String implements the Stringer interface

type ApplicationTopicType

type ApplicationTopicType string

ApplicationTopicType represents the type of an application topic

const (
	AppEvents ApplicationTopicType = "events"
)

Topic types for Applications

type Client

type Client interface {
	Connect() error
	Disconnect()

	IsConnected() bool

	// Uplink pub/sub
	PublishUplink(payload types.UplinkMessage) Token
	PublishUplinkFields(appID string, devID string, fields map[string]interface{}) Token
	SubscribeDeviceUplink(appID string, devID string, handler UplinkHandler) Token
	SubscribeAppUplink(appID string, handler UplinkHandler) Token
	SubscribeUplink(handler UplinkHandler) Token
	UnsubscribeDeviceUplink(appID string, devID string) Token
	UnsubscribeAppUplink(appID string) Token
	UnsubscribeUplink() Token

	// Downlink pub/sub
	PublishDownlink(payload types.DownlinkMessage) Token
	SubscribeDeviceDownlink(appID string, devID string, handler DownlinkHandler) Token
	SubscribeAppDownlink(appID string, handler DownlinkHandler) Token
	SubscribeDownlink(handler DownlinkHandler) Token
	UnsubscribeDeviceDownlink(appID string, devID string) Token
	UnsubscribeAppDownlink(appID string) Token
	UnsubscribeDownlink() Token

	// Event pub/sub
	PublishAppEvent(appID string, eventType types.EventType, payload interface{}) Token
	PublishDeviceEvent(appID string, devID string, eventType types.EventType, payload interface{}) Token
	SubscribeAppEvents(appID string, eventType types.EventType, handler AppEventHandler) Token
	SubscribeDeviceEvents(appID string, devID string, eventType types.EventType, handler DeviceEventHandler) Token
	UnsubscribeAppEvents(appID string, eventType types.EventType) Token
	UnsubscribeDeviceEvents(appID string, devID string, eventType types.EventType) Token

	// Activation pub/sub
	PublishActivation(payload types.Activation) Token
	SubscribeDeviceActivations(appID string, devID string, handler ActivationHandler) Token
	SubscribeAppActivations(appID string, handler ActivationHandler) Token
	SubscribeActivations(handler ActivationHandler) Token
	UnsubscribeDeviceActivations(appID string, devID string) Token
	UnsubscribeAppActivations(appID string) Token
	UnsubscribeActivations() Token
}

Client connects to the MQTT server and can publish/subscribe on uplink, downlink and activations from devices

func NewClient

func NewClient(ctx log.Interface, id, username, password string, brokers ...string) Client

NewClient creates a new DefaultClient

Example
ctx := apex.Stdout().WithField("Example", "NewClient")
exampleClient := NewClient(ctx, "ttnctl", "my-app-id", "my-access-key", "eu.thethings.network:1883")
err := exampleClient.Connect()
if err != nil {
	ctx.WithError(err).Fatal("Could not connect")
}
Output:

func NewTLSClient

func NewTLSClient(ctx log.Interface, id, username, password string, tlsConfig *tls.Config, brokers ...string) Client

NewTLSClient creates a new DefaultClient with TLS enabled

type DefaultClient

type DefaultClient struct {
	// contains filtered or unexported fields
}

DefaultClient is the default MQTT client for The Things Network

func (*DefaultClient) Connect

func (c *DefaultClient) Connect() error

Connect to the MQTT broker. It will retry for ConnectRetries times with a delay of ConnectRetryDelay between retries

func (*DefaultClient) Disconnect

func (c *DefaultClient) Disconnect()

Disconnect from the MQTT broker

func (*DefaultClient) IsConnected

func (c *DefaultClient) IsConnected() bool

IsConnected returns true if there is a connection to the MQTT broker

func (*DefaultClient) PublishActivation

func (c *DefaultClient) PublishActivation(activation types.Activation) Token

PublishActivation publishes an activation

func (*DefaultClient) PublishAppEvent

func (c *DefaultClient) PublishAppEvent(appID string, eventType types.EventType, payload interface{}) Token

PublishAppEvent publishes an event to the topic for application events of the given type it will marshal the payload to json

func (*DefaultClient) PublishDeviceEvent

func (c *DefaultClient) PublishDeviceEvent(appID string, devID string, eventType types.EventType, payload interface{}) Token

PublishDeviceEvent publishes an event to the topic for device events of the given type it will marshal the payload to json

func (c *DefaultClient) PublishDownlink(dataDown types.DownlinkMessage) Token

PublishDownlink publishes a downlink message

func (c *DefaultClient) PublishUplink(dataUp types.UplinkMessage) Token

PublishUplink publishes an uplink message to the MQTT broker

func (*DefaultClient) PublishUplinkFields

func (c *DefaultClient) PublishUplinkFields(appID string, devID string, fields map[string]interface{}) Token

PublishUplinkFields publishes uplink fields to MQTT

func (*DefaultClient) SubscribeActivations

func (c *DefaultClient) SubscribeActivations(handler ActivationHandler) Token

SubscribeActivations subscribes to all activations that the current user has access to

func (*DefaultClient) SubscribeAppActivations

func (c *DefaultClient) SubscribeAppActivations(appID string, handler ActivationHandler) Token

SubscribeAppActivations subscribes to all activations for the given application

func (c *DefaultClient) SubscribeAppDownlink(appID string, handler DownlinkHandler) Token

SubscribeAppDownlink subscribes to all downlink messages for the given application

func (*DefaultClient) SubscribeAppEvents

func (c *DefaultClient) SubscribeAppEvents(appID string, eventType types.EventType, handler AppEventHandler) Token

SubscribeAppEvents subscribes to events of the given type for the given application. In order to subscribe to application events from all applications the user has access to, pass an empty string as appID.

func (c *DefaultClient) SubscribeAppUplink(appID string, handler UplinkHandler) Token

SubscribeAppUplink subscribes to all uplink messages for the given application

func (*DefaultClient) SubscribeDeviceActivations

func (c *DefaultClient) SubscribeDeviceActivations(appID string, devID string, handler ActivationHandler) Token

SubscribeDeviceActivations subscribes to all activations for the given application and device

func (c *DefaultClient) SubscribeDeviceDownlink(appID string, devID string, handler DownlinkHandler) Token

SubscribeDeviceDownlink subscribes to all downlink messages for the given application and device

func (*DefaultClient) SubscribeDeviceEvents

func (c *DefaultClient) SubscribeDeviceEvents(appID string, devID string, eventType types.EventType, handler DeviceEventHandler) Token

SubscribeDeviceEvents subscribes to events of the given type for the given device. In order to subscribe to events from all devices within an application, pass an empty string as devID. In order to subscribe to all events from all devices in all applications the user has access to, pass an empty string as appID.

func (c *DefaultClient) SubscribeDeviceUplink(appID string, devID string, handler UplinkHandler) Token

SubscribeDeviceUplink subscribes to all uplink messages for the given application and device

func (c *DefaultClient) SubscribeDownlink(handler DownlinkHandler) Token

SubscribeDownlink subscribes to all downlink messages that the current user has access to

func (c *DefaultClient) SubscribeUplink(handler UplinkHandler) Token

SubscribeUplink subscribes to all uplink messages that the current user has access to

func (*DefaultClient) UnsubscribeActivations

func (c *DefaultClient) UnsubscribeActivations() Token

UnsubscribeActivations unsubscribes from the activations that the current user has access to

func (*DefaultClient) UnsubscribeAppActivations

func (c *DefaultClient) UnsubscribeAppActivations(appID string) Token

UnsubscribeAppActivations unsubscribes from the activations for the given application

func (c *DefaultClient) UnsubscribeAppDownlink(appID string) Token

UnsubscribeAppDownlink unsubscribes from the downlink messages for the given application

func (*DefaultClient) UnsubscribeAppEvents

func (c *DefaultClient) UnsubscribeAppEvents(appID string, eventType types.EventType) Token

UnsubscribeAppEvents unsubscribes from the events that were subscribed to by SubscribeAppEvents

func (c *DefaultClient) UnsubscribeAppUplink(appID string) Token

UnsubscribeAppUplink unsubscribes from the uplink messages for the given application

func (*DefaultClient) UnsubscribeDeviceActivations

func (c *DefaultClient) UnsubscribeDeviceActivations(appID string, devID string) Token

UnsubscribeDeviceActivations unsubscribes from the activations for the given application and device

func (c *DefaultClient) UnsubscribeDeviceDownlink(appID string, devID string) Token

UnsubscribeDeviceDownlink unsubscribes from the downlink messages for the given application and device

func (*DefaultClient) UnsubscribeDeviceEvents

func (c *DefaultClient) UnsubscribeDeviceEvents(appID string, devID string, eventType types.EventType) Token

UnsubscribeDeviceEvents unsubscribes from the events that were subscribed to by SubscribeDeviceEvents

func (c *DefaultClient) UnsubscribeDeviceUplink(appID string, devID string) Token

UnsubscribeDeviceUplink unsubscribes from the uplink messages for the given application and device

func (c *DefaultClient) UnsubscribeDownlink() Token

UnsubscribeDownlink unsubscribes from the downlink messages that the current user has access to

func (c *DefaultClient) UnsubscribeUplink() Token

UnsubscribeUplink unsubscribes from the uplink messages that the current user has access to

type DeviceEventHandler

type DeviceEventHandler func(client Client, appID string, devID string, eventType types.EventType, payload []byte)

DeviceEventHandler is called for events

type DeviceTopic

type DeviceTopic struct {
	AppID string
	DevID string
	Type  DeviceTopicType
	Field string
}

DeviceTopic represents an MQTT topic for devices

func ParseDeviceTopic

func ParseDeviceTopic(topic string) (*DeviceTopic, error)

ParseDeviceTopic parses an MQTT device topic string to a DeviceTopic struct

func (DeviceTopic) String

func (t DeviceTopic) String() string

String implements the Stringer interface

func (DeviceTopic) ValidField

func (t DeviceTopic) ValidField() bool

ValidField indicates whether the field of the device topic is valid.

type DeviceTopicType

type DeviceTopicType string

DeviceTopicType represents the type of a device topic

const (
	DeviceEvents   DeviceTopicType = "events"
	DeviceUplink   DeviceTopicType = "up"
	DeviceDownlink DeviceTopicType = "down"
)

Topic types for Devices

type DownlinkHandler

type DownlinkHandler func(client Client, appID string, devID string, req types.DownlinkMessage)

DownlinkHandler is called for downlink messages

type Token

type Token interface {
	// Wait for the function to finish
	Wait() bool
	// Wait for the function to finish or return false after a certain time
	WaitTimeout(time.Duration) bool
	// The error associated with the result of the function (nil if everything okay)
	Error() error
}

Token is returned on asyncronous functions

type UplinkHandler

type UplinkHandler func(client Client, appID string, devID string, req types.UplinkMessage)

UplinkHandler is called for uplink messages

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL