MQTT Broker Service
MQTT Protocol Specification for LX2-Pagers
Connection Details
- Server:
pager.dexa.gmbh - Port: 443 (HTTPS/WebSocket)
- WebSocket URL:
wss://pager.dexa.gmbh/mqtt - Protocol: MQTT over WebSocket (Secure)
- Authentication: Currently disabled (anonymous), will be enabled later
Topic Structure
Inbound Topics (Pager → Server)
| Topic Pattern | Description | QoS |
|---|---|---|
p/u/<uid>/reg |
Pager registration on startup | 1 |
p/u/<uid>/ka |
Keep-alive / Heartbeat | 0 |
p/u/<uid>/status |
Status updates (battery, GPS, signal) | 1 |
p/u/<uid>/ack/<alarm_id> |
Alarm acknowledgment | 1 |
p/u/<uid>/lwt |
Last Will & Testament (offline) | 1 |
Outbound Topics (Server → Pager)
| Topic Pattern | Description | QoS |
|---|---|---|
p/u/<uid>/r/<ric> |
Alarm messages for specific RIC | 1 |
Variables:
<uid>: Pager unique ID (14 digits, e.g.,24702004551000)<ric>: RIC code (e.g.,1379996A)<alarm_id>: Alarm ID from database
Message Formats
All messages use JSON format.
1. Registration Message
Topic: p/u/24702004551000/reg
Payload:
{
"type": "reg",
"uid": "24702004551000",
"rics": ["1379996A", "1379997B"],
"ts": 1700123456
}
Fields:
type: Always"reg"uid: Pager unique ID (14 digits)rics: Array of RIC codes this pager subscribes to (optional)ts: Unix timestamp (seconds since epoch)
What happens:
- Pager is automatically switched from TCP to MQTT in database
last_seen_mqttis updatedconnection_typeis set to'mqtt'activeis set toTRUE- RICs are stored in database
2. Keep-Alive / Heartbeat
Topic: p/u/24702004551000/ka
Payload:
{
"type": "ka",
"uid": "24702004551000",
"bat": 78,
"sig": -68,
"ts": 1700124000
}
Fields:
type: Always"ka"uid: Pager unique IDbat: Battery percentage (0-100, optional)sig: Signal strength in dBm (e.g., -68, optional)ts: Unix timestamp
Recommended interval: 60 seconds
What happens:
last_seen_mqttis updated- Battery and signal are stored if provided
- Pager remains active
3. Status Update
Topic: p/u/24702004551000/status
Payload:
{
"type": "status",
"uid": "24702004551000",
"bat": 78,
"v": 3.85,
"lat": 51.5074,
"lon": -0.1278,
"sig": -68,
"ts": 1700124001
}
Fields:
type: Always"status"uid: Pager unique IDbat: Battery percentage (0-100, optional)v: Battery voltage in Volts (e.g., 3.85, optional)lat: GPS latitude (decimal degrees, optional)lon: GPS longitude (decimal degrees, optional)sig: Signal strength in dBm (optional)ts: Unix timestamp
When to send: Periodically (e.g., every 5-10 minutes) or on significant changes
What happens:
- All provided fields are stored in database
last_seen_mqttis updated- GUI displays updated values
4. Alarm Acknowledgment
Topic: p/u/24702004551000/ack/12345
Payload:
{
"type": "ack",
"uid": "24702004551000",
"aid": 12345,
"ric": "1379996A",
"ts": 1700124002
}
Fields:
type: Always"ack"uid: Pager unique IDaid: Alarm ID (fromtcp_outbound.idin database)ric: RIC code (optional)ts: Unix timestamp
When to send: When user acknowledges/views an alarm on the pager
What happens:
- Alarm is marked as acknowledged in
tcp_outboundtable successandsent_okare set toTRUE
5. Last Will & Testament (LWT)
Topic: p/u/24702004551000/lwt
Payload:
{
"type": "lwt",
"uid": "24702004551000",
"ts": 1700124003
}
Fields:
type: Always"lwt"uid: Pager unique IDts: Unix timestamp
How to configure: Set this as MQTT Last Will message when connecting. The broker will automatically publish it if connection is lost unexpectedly.
What happens:
- Pager is marked as
active=FALSEin database - Shows as "Offline" in GUI
Receiving Alarms
Subscription
After registration, subscribe to your alarm topics:
p/u/24702004551000/r/+ # All RICs for this pager
p/u/24702004551000/r/1379996A # Specific RIC only
Alarm Format
Alarms are sent as binary data (Latin-1 encoded) in the same format as TCP:
<STX>24702004551000#09#1379996A#TESTEINSATZ - Dies ist ein Test<ETX>
Format breakdown:
<STX>: Start of text (0x02)24702004551000: Pager UID#09#: Command code (09 = alarm)1379996A: RIC codeTESTEINSATZ - Dies ist ein Test: Alarm text<ETX>: End of text (0x03)
Connection Flow
Initial Connection
- Pager connects to
wss://pager.dexa.gmbh/mqtt - Sends registration message to
p/u/<uid>/reg - Server automatically switches pager to MQTT mode
- Pager subscribes to
p/u/<uid>/r/+ - Pager starts sending keep-alive messages every 60s
Reconnection
If connection is lost:
- Pager reconnects to broker
- Sends registration message again
- Re-subscribes to alarm topics
- Continues normal operation
Battery Optimization
To maximize battery life:
- Keep-Alive (QoS 0): Can be lost without issues, saves retransmission overhead
- Heartbeat interval: 60 seconds (can be adjusted based on needs)
- Status updates: Only when values change significantly or every 5-10 minutes
- QoS 1 for critical messages: Registration, Status, ACK to ensure delivery
- MQTT Keep-Alive: 30 minutes (server configured)
Testing with mosquitto_pub
Send Registration
mosquitto_pub -h 127.0.0.1 -p 1883 -t "p/u/24702004551000/reg" \
-m '{"type":"reg","uid":"24702004551000","rics":["1379996A"],"ts":1700123456}'
Send Keep-Alive
mosquitto_pub -h 127.0.0.1 -p 1883 -t "p/u/24702004551000/ka" \
-m '{"type":"ka","uid":"24702004551000","bat":78,"sig":-68,"ts":1700124000}'
Send Status
mosquitto_pub -h 127.0.0.1 -p 1883 -t "p/u/24702004551000/status" \
-m '{"type":"status","uid":"24702004551000","bat":78,"v":3.85,"lat":51.5074,"lon":-0.1278,"sig":-68,"ts":1700124001}'
Subscribe to Alarms
mosquitto_sub -h 127.0.0.1 -p 1883 -t "p/u/24702004551000/r/+" -v
Error Handling
- Invalid JSON: Message is logged but ignored
- Missing required fields: Partial processing (e.g., no battery update if
batmissing) - Unknown UID: Message is stored in
mqtt_inboundtable but not processed - Connection lost: Auto-reconnect with exponential backoff (10s retry interval)