CQ COMPUTING SOLUTIONS
Document: LoRaWAN Duress System Build
Version: 1.0
Date: 11 April 2026
Author: Cameron Pollack

LoRaWAN Duress Button System

Step-by-step build guide: 7x wireless duress buttons integrating with a Bosch Solution 6000 alarm panel
ℹ About this guide
This is a first-timer walkthrough. If you've never built a LoRaWAN system before, follow it in order — each phase builds on the one before it. Don't skip ahead. Every callout box is there because something will go wrong if you ignore it.
Table of Contents
  1. System Overview & How It Works1
  2. Bill of Materials3
  3. Pre-Build: Supplier Setup5
  4. Phase 1 — Head Office Hub (The Brain)6
  5. Phase 2 — Gateway (UG67)9
  6. Phase 3 — Field Nodes (UC501 + Button)11
  7. Phase 4 — ChirpStack Device Registration14
  8. Phase 5 — Node-RED Flow16
  9. Testing Protocol18
  10. Deployment Notes20
  11. Open Questions & Risks21
  12. Appendix — Files & References22

1. System Overview & How It Works

Project: 7x wireless duress buttons feeding into an existing Bosch Solution 6000 alarm panel.

Use case: Mining camp, one button per laundry, roughly 100–500m range across the park.

Target panel: Bosch Solution 6000 (existing, with CM705B expander, 4G failover, network backhaul).

Back end: Milesight UC501 LoRaWAN IoT Controllers → Milesight UG67 outdoor gateway → Raspberry Pi (Node-RED + MQTT) → 8-channel relay board → Bosch CM705B zones.

1.1 Architecture at a glance

┌─────────────────────────────────────┐ │ Laundry 1..7 (each) │ │ │ │ [Red 40mm E-Stop Button] ◄─┐ │ │ │ │ │ │ ▼ │ │ │ [Tamper Lid Switch] ────────┤ │ │ │ │ │ │ ▼ │ │ │ ┌──────────────────┐ │ │ │ │ Milesight UC501 │ ◄──────┘ │ │ │ (IP67 LoRaWAN) │ │ │ │ GPIO_1: Duress │ │ │ │ GPIO_2: Tamper │ │ │ │ Battery/Solar │ │ │ └─────┬────────────┘ │ │ │ LoRaWAN AU915 │ └────────┼────────────────────────────┘ │ │ (100m – 2km LoRaWAN link) ▼ ┌──────────────────────────────────────┐ │ HEAD OFFICE │ │ │ │ ┌────────────────────┐ │ │ │ Milesight UG67 │ (IP67, │ │ │ Outdoor Gateway │ mast-mount) │ │ │ Built-in ChirpStack│ │ │ └─────┬──────────────┘ │ │ │ PoE + MQTT │ │ ▼ │ │ ┌────────────────────┐ │ │ │ Raspberry Pi 4 │ │ │ │ Mosquitto MQTT │ │ │ │ Node-RED flows │ │ │ │ GPIO → Relay board │ │ │ └─────┬──────────────┘ │ │ │ GPIO (3.3V logic) │ │ ▼ │ │ ┌────────────────────┐ │ │ │ 8-ch Opto Relay │ │ │ │ Board (12V) │ │ │ │ Ch1-7 = 7 zones │ │ │ │ Ch8 = Supervision │ │ │ └─────┬──────────────┘ │ │ │ Dry contacts + EOL │ │ ▼ │ │ ┌────────────────────┐ │ │ │ Bosch CM705B │ │ │ │ Expander (existing)│ │ │ │ 7 zones 24hr Duress│ │ │ │ 1 zone Trouble │ │ │ └─────┬──────────────┘ │ │ │ LAN bus │ │ ▼ │ │ ┌────────────────────┐ │ │ │ Bosch Solution 6000│ │ │ │ + 4G failover │ │ │ │ → Monitoring stn │ │ │ └────────────────────┘ │ └──────────────────────────────────────┘

1.2 How it works, step by step

  1. Staff member presses the 40mm red e-stop button inside a laundry
  2. Button pulls UC501 GPIO_1 low (dry contact closed)
  3. UC501 detects the DI change and sends a LoRaWAN uplink (Class A, confirmed, up to 3 retries)
  4. UG67 at head office receives the uplink over AU915
  5. UG67 publishes an MQTT message to the local Mosquitto broker on the Pi
  6. Node-RED flow decodes the payload, matches the device EUI to a button/zone mapping, and pulses the matching GPIO high for 3 seconds
  7. Opto relay closes the dry contact — Bosch zone sees alarm
  8. Bosch Solution 6000 raises a 24-hour Duress alarm, reported to monitoring via IP + 4G failover
  9. Node-RED also publishes a push notification (optional) so head office staff see which laundry triggered

1.3 Supervision — how you know nothing is broken

💡 Why this architecture
The Bosch panel doesn't need to know anything about LoRaWAN — from its perspective it's just getting dry-contact zone triggers like any other hardwired duress button. All the wireless magic happens upstream on the Pi. This means you don't have to reprogram the Bosch in any meaningful way, and if the whole LoRaWAN stack dies, the panel still works for everything else.

2. Bill of Materials

Three groups of parts: per-laundry kit (you need 7 of these), head office kit (1 of these), and test bench gear (should already have most of it).

2.1 Per-laundry kit (×7)

QtyItemPart No.~$AU ex-GSTSupplier
7Milesight UC501 LoRaWAN IoT Controller (AU915, solar rechargeable, external antenna version)UC501-915M-EA$249IoT Store AU
740mm Red Mushroom E-Stop Pushbutton, IP65, push-to-lock / twist-release, 1NO contact, 22mm mountIEC 60947-5-5~$25RS Components / element14
7IP66 ABS enclosure ~160×120×80mm, hinged lid with key lock (or captive screws)Jaycar HB6131~$25Jaycar
7Tamper switch (momentary microswitch, lever, 1NC)Jaycar SM1039~$3Jaycar
7Cable gland, M20, IP68Generic~$2Jaycar / Bunnings
7External 3–5 dBi LoRa antenna, N-type or SMA, for UC501-EA modelMilesight stock$15–30IoT Store AU
7Mounting hardware: wall plugs, screws, anti-vandal Torx bolts~$5Bunnings
7Warning decal "EMERGENCY DURESS — PRESS TO ACTIVATE"Custom vinyl~$5Local signwriter

Per-laundry subtotal: ~$329 ex-GST × 7 = ~$2,303

2.2 Head office kit (×1)

QtyItemPart No.~$AU ex-GSTSupplier
1Milesight UG67 Outdoor LoRaWAN Gateway (AU915, 8-CH, PoE, IP67, built-in ChirpStack)UG67-L04EU-915M / UG67-L00EU-915M$749–849IoT Store AU
1External high-gain omni antenna, 5–8 dBi, N-type, outdoor ratedGeneric$80–120IoT Store AU / RF Industries
1N-type pigtail / jumper cable, 50cm (LMR-240)LMR-240$25RF Industries
1PoE injector, Gigabit, 48VUbiquiti POE-48-24W$25Scorptec / Mwave
1Raspberry Pi 4 Model B, 4GBOfficial$100Core Electronics
1Raspberry Pi 4 case with fanArgon Neo / Flirc$40Core Electronics
1Official Pi 4 PSU 5V 3A USB-COfficial$25Core Electronics
1SanDisk Industrial microSD 32GB (A1, U3)SDSDQAF3-032G$30Core Electronics
18-channel 12V opto-isolated relay board (SPDT contacts)Generic$20–30Core Electronics / Jaycar
112V 1A regulated DC plugpackJaycar MP3307$25Jaycar
1DIN rail + terminal blocks + 6-way cage clampPhoenix Contact$60element14
1Wall-mount enclosure ~300×200×100mm for Pi + relay boardJaycar HB6308$60Jaycar
Cat6 outdoor UV cable to gateway (~20m)$40Bunnings
EOL resistors (3.74kΩ 1%, 6.8kΩ 1% — confirm with Bosch config)$5Jaycar
Duplex hookup wire, ferrules, heatshrink$30Jaycar

Head office subtotal: ~$1,290 ex-GST

2.3 Test bench gear

QtyItemPurpose
1Spare Bosch Solution 6000 panel + CM705B (or dev panel)End-to-end test target
112V 7Ah SLA battery + chargerBench power for Bosch + relays
1Android phone with NFCMilesight ToolBox app config for UC501/WS101
1MultimeterRelay / zone verification
1Ethernet switch + laptopGateway/Pi access
1Second laptop with WiresharkVerify LoRa MQTT messages
⚠ Total estimated cost
~$3,600 ex-GST for one full 7-button system (no labour, no shipping). Budget ~$4,500 landed. Add freight surcharges for any site deliveries and a buffer for one spare UC501 + one spare e-stop.

3. Pre-Build: Supplier Setup

Do these four things before you order anything.

1
Create an account with IoT Store AU

iot-store.com.au — they're the main AU Milesight distributor at retail. Ask for a trade or reseller account. You'll likely get 10–20% off list.

2
Contact Tekdis AU

tekdis.com.au — the official Milesight distributor for AU/NZ. Better pricing on volume (5+ UC501s) and access to project pricing on the UG67. This is where you'd buy for a real client deployment.

3
Register for a Milesight IoT Developer account

Sign up at cloud.milesight-iot.com. It's free and lets you test their cloud if you ever want a secondary dashboard alongside ChirpStack.

4
Install the Milesight ToolBox app

Free on the Google Play Store. This is how you configure UC501 and WS101 devices over NFC. Get this on the Android phone you'll be using in the field.

ℹ iOS doesn't work
ToolBox is Android-only because iPhones don't expose NFC the right way for writing to peripheral devices. Borrow an Android if needed.

4. Phase 1 — Head Office Hub (The Brain)

Build this first, fully on your bench. It's the core of the system. Don't try to build at the site — build it here, test it here, then bring a working unit to install.

4.1 Flash the Raspberry Pi

1
Download Raspberry Pi Imager
2
Choose Raspberry Pi OS Lite (64-bit)

No desktop, headless. You'll only ever SSH into this thing.

3
Set the bootstrap options before writing

Click the gear icon in Imager and set:

  • Hostname: lora-bridge
  • Enable SSH, public-key auth (paste your key)
  • Username: cameron / password of choice
  • Wi-Fi for initial bootstrap if needed
  • Locale: en_AU.UTF-8, Australia/Brisbane
4
Flash, boot, and SSH in

Flash the 32GB SD, boot the Pi on the bench with Ethernet, then:

ssh cameron@lora-bridge.local # Update and install base tools sudo apt update && sudo apt upgrade -y sudo apt install -y git curl vim htop build-essential python3-pip python3-rpi.gpio

4.2 Install Mosquitto (MQTT broker)

sudo apt install -y mosquitto mosquitto-clients sudo systemctl enable mosquitto sudo systemctl start mosquitto

Lock it down with a username and password:

sudo mosquitto_passwd -c /etc/mosquitto/passwd lora # enter a password when prompted sudo tee /etc/mosquitto/conf.d/auth.conf > /dev/null <<'EOF' listener 1883 allow_anonymous false password_file /etc/mosquitto/passwd EOF sudo systemctl restart mosquitto

Test that auth works:

mosquitto_sub -h localhost -t '#' -u lora -P '<password>' -v # In another terminal: mosquitto_pub -h localhost -t test -m hello -u lora -P '<password>'
⚠ Don't leave it anonymous
If allow_anonymous is left true, anyone on the LAN can publish fake duress events. Always enforce auth on MQTT brokers, even on a "trusted" network.

4.3 Install Node-RED

bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) # Accept defaults. Enable at boot: sudo systemctl enable nodered.service sudo systemctl start nodered.service

Verify it's running by browsing to http://lora-bridge.local:1880 in your browser.

Install the required palette nodes via Manage Palette → Install:

4.4 Wire up the 8-channel relay board

Typical 5V/12V opto-isolated 8-channel relay board pinout:

Relay ChPi GPIO (BCM)Physical PinMaps to
IN1GPIO 529Laundry 1 Duress
IN2GPIO 631Laundry 2 Duress
IN3GPIO 1333Laundry 3 Duress
IN4GPIO 1935Laundry 4 Duress
IN5GPIO 2637Laundry 5 Duress
IN6GPIO 1636Laundry 6 Duress
IN7GPIO 2038Laundry 7 Duress
IN8GPIO 2140System Trouble / Supervision
⚠ Active-LOW relays
Most cheap Chinese opto relay boards are active LOW — driving GPIO low energises the relay. Node-RED flows need to account for this, and the GPIO should initialise high on boot (relay off). Get this wrong and every zone on the Bosch will trip the instant the Pi powers up.

Each relay has NC / COM / NO terminals. Wire COM + NO to the Bosch zone so that when the relay energises, the zone shorts through whatever EOL config Bosch expects.

4.5 Bosch zone wiring (reuse existing CM705B zones)

The existing CM705B in the head office already has 7 zones connected to the broken P2P relay rig. Disconnect those and re-terminate to the new 8-channel board.

Typical Bosch Solution 6000 single-EOL wiring

ZONE+ ─────┬───── NO (relay) │ 3.74kΩ │ ZONE- ─────┴───── COM (relay)
⚠ Check the EOL value first
Bosch 6000 supports No EOL, Single EOL (3.74kΩ default), or Dual EOL (3.74k seal / 6.8k alarm). Use whatever the existing zones are already programmed as. Don't reprogram the panel if you can avoid it. Change the wiring to match the panel, not the other way around.

Zone programming (only if it must change)

4.6 Head office enclosure layout

┌──────────────────────────────────────────────┐ │ HB6308 Wall Enclosure (300×200×100mm) │ │ │ │ ┌───────┐ ┌────────────────────┐ │ │ │Pi 4 │ │ 8-CH Relay Board │ │ │ │+case │ │ │ │ │ └───┬───┘ └────────┬───────────┘ │ │ │ │ │ │ │ GPIO ribbon │ │ │ └────────────────┘ │ │ │ │ ┌────────────────────┐ │ │ │ 12V 1A PSU │ ┌───────────────┐ │ │ │ + DIN rail │ │ Terminal │ │ │ │ + terminal block │ │ block (zones) │ │ │ └────────────────────┘ └───────────────┘ │ │ │ │ Cable gland ↓ Cable gland ↓ (to Bosch) │ │ (Ethernet from (7x pair + 1 pair) │ │ UG67 PoE) │ └──────────────────────────────────────────────┘

Mount on the wall next to the Bosch panel. Power the Pi and relay board from the 12V rail so they share a common ground with the Bosch zones.


5. Phase 2 — Gateway (UG67)

The UG67 is the outdoor LoRaWAN gateway with ChirpStack network server built in. That means you don't need a separate network server, which simplifies everything.

5.1 Initial gateway bring-up

1
Plug in and connect a laptop

Plug the UG67 into the PoE injector, laptop on the LAN side.

2
Log into the default IP

Default IP is 192.168.1.1/24, login admin/password.

⚠ Change the default password immediately
First thing you do, before plugging it into a shared network. Every internet-facing UG67 with default creds gets owned inside a week.
3
Set hostname, timezone, NTP

System → General: hostname ug67-camp, timezone Brisbane, NTP to pool.ntp.org.

4
Set a static LAN IP

Network → Interface: set a static IP on your site LAN (e.g. 192.168.1.250).

5
Enable the built-in ChirpStack network server

System → Packet Forwarder: enable Built-in Network Server. This is the ChirpStack instance that ships with the UG67.

6
Configure radio for AU915 sub-band 2

Packet Forwarder → Radios: frequency AU915, sub-band 2 (channels 8–15 + 65).

7
Update firmware

System → Upgrade: make sure it's 60.0.0.43 or later.

5.2 ChirpStack built-in network server setup

UG67 ships with ChirpStack baked in. In the ChirpStack UI:

  1. Network Server → General: Enable.
  2. Applications → Add: name duress-system, payload codec Custom Javascript codec functions (we'll paste a decoder in Phase 4).
  3. Profiles → Device Profile → Add:
    • Name: UC501-Duress
    • LoRaWAN MAC Version: 1.0.3
    • Regional Parameters: RP002-1.0.3
    • Class: Class A
    • Max EIRP: 16 dBm
    • ADR: Enabled
  4. Integration → MQTT:
    • Broker: tcp://lora-bridge.local:1883 (the Pi)
    • Username: lora / password as set earlier
    • Topic prefix: application/duress/

5.3 Mounting and antenna

  1. Mount UG67 as high as practical — roof, mast, parapet. Line of sight to the laundries is the goal.
  2. Mount the external high-gain omni antenna on a short pole above the UG67 body, connected via the LMR-240 jumper.
  3. Use an N-type coaxial surge arrestor inline if the antenna is on a mast (grounded to mast ground).
  4. Run Cat6 PoE back to the head office switch and the Pi enclosure.
💡 Gateway placement wins or loses this job
Do a site survey with a spectrum analyser or a UC501 in scanner mode before committing. Spend real time finding the highest point with the best line of sight to all 7 laundries. If the gateway is on the ground with a single-storey building in the way, no amount of software tuning will save you.

6. Phase 3 — Field Nodes (UC501 + Button)

Do all 7 UC501s on the bench, before any enclosure work. Label everything as you go.

6.1 UC501 base configuration (via NFC)

1
Install Milesight ToolBox on your Android phone

Free on Google Play.

2
Power on the UC501

Flick the internal switch and make sure the battery is charged.

3
Connect over NFC

In ToolBox: Device, then tap the back of your phone against the UC501 NFC logo. If it doesn't connect first go, try moving the phone around — NFC coupling is fiddly.

4
Note the Device EUI

Go to the Status page. Confirm firmware version, battery %, and write the Device EUI on a sticker. You'll need it to map buttons to zones.

5
Configure LoRaWAN settings

Settings → LoRaWAN:

  • Work Mode: OTAA
  • Confirmed Mode: On, Retransmissions: 3
  • Class: Class A
  • Spread Factor: SF10 (range/battery balance) or SF7 if close to gateway
  • TX Power: 16 dBm (max for AU915)
  • Channel Mode: Sub-Band 2 (must match the UG67 sub-band)
  • App Key / App EUI: generate or use your own standard keys
  • Uplink Interval: 360 min (6 hours) — idle heartbeat. DI changes are event-triggered on top of this.
6
Configure GPIO inputs

Settings → Interface → GPIO:

  • GPIO_1 (duress button): mode = Digital Input, trigger = falling edge, debounce = 50 ms
  • GPIO_2 (tamper): mode = Digital Input, trigger = rising edge, debounce = 200 ms
7
Save, label, photograph

Tap Save — ToolBox writes over NFC, you'll hear a confirmation beep. Label the UC501 with its Device EUI and Laundry number (1–7). Take a photo for records. Repeat for all 7.

6.2 Field enclosure assembly (per unit)

Prep the enclosure (Jaycar HB6131 or similar)

Mount the components inside

Wiring

E-stop NO contact ─┬─ UC501 GPIO_1 └─ UC501 GND Tamper NC contact ─┬─ UC501 GPIO_2 └─ UC501 GND

Antenna

Final seal

6.3 Wall mounting position (install guide for the site installer)


7. Phase 4 — ChirpStack Device Registration

7.1 Add each UC501 as a device

For each UC501, in the UG67 ChirpStack UI:

  1. Applications → duress-system → Devices → Create:
    • Name: laundry-01 through laundry-07
    • Device EUI: the EUI you wrote on the sticker
    • Device Profile: UC501-Duress
    • Save
  2. On the device page → Keys (OTAA): paste the App Key you set in ToolBox (must match exactly). Save.
  3. Power cycle the UC501. It should JOIN within 30 seconds.
  4. Watch the Device Data tab — you should see a join accept, then uplinks as you press the button.

7.2 Payload codec

UC501 uplinks are TLV-encoded binary. Paste this codec into the device profile or application:

// UC501 LoRaWAN payload decoder (simplified for GPIO-only duress use case) function decodeUplink(input) { var bytes = input.bytes; var data = {}; var i = 0; while (i < bytes.length) { var channel = bytes[i++]; var type = bytes[i++]; // Battery if (channel === 0x01 && type === 0x75) { data.battery = bytes[i]; i += 1; } // GPIO_1 digital input else if (channel === 0x03 && type === 0x00) { data.gpio_1 = bytes[i] === 1 ? "active" : "inactive"; i += 1; } // GPIO_2 digital input (tamper) else if (channel === 0x04 && type === 0x00) { data.gpio_2 = bytes[i] === 1 ? "tamper_open" : "tamper_sealed"; i += 1; } // Skip unknown TLVs else { i += 1; } } return { data: data }; }
⚠ Verify channel/type bytes against the actual uplink
Milesight can change TLV channel/type values between firmware versions. Before you trust the decoder, watch raw MQTT messages and compare the bytes to what this code expects. The UC50x Communication Protocol PDF in the references section is the source of truth.

7.3 Verify the MQTT stream

SSH into the Pi and subscribe:

mosquitto_sub -h localhost -t 'application/duress/#' -u lora -P '<password>' -v

Press the e-stop button — you should see an MQTT message within 2 seconds:

application/duress/device/<EUI>/event/up {"applicationID":"...","devEUI":"...","object":{"battery":100,"gpio_1":"active"},...}

8. Phase 5 — Node-RED Flow

8.1 Device mapping

Create /home/cameron/duress-mapping.json on the Pi:

{ "a84041xxxxxxxxx1": { "name": "Laundry 1", "zone_gpio": 5 }, "a84041xxxxxxxxx2": { "name": "Laundry 2", "zone_gpio": 6 }, "a84041xxxxxxxxx3": { "name": "Laundry 3", "zone_gpio": 13 }, "a84041xxxxxxxxx4": { "name": "Laundry 4", "zone_gpio": 19 }, "a84041xxxxxxxxx5": { "name": "Laundry 5", "zone_gpio": 26 }, "a84041xxxxxxxxx6": { "name": "Laundry 6", "zone_gpio": 16 }, "a84041xxxxxxxxx7": { "name": "Laundry 7", "zone_gpio": 20 } }

Replace the EUIs with your actual UC501 EUIs from the stickers.

8.2 Node-RED flows (high level)

Flow 1 — Duress trigger

[MQTT in: application/duress/+/device/+/event/up] │ ▼ [JSON parse] │ ▼ [Function: lookup device EUI in mapping, extract gpio_1 state] │ ▼ [Switch: is gpio_1 === "active"?] │ yes ▼ [Function: set GPIO pin, msg.topic = mapping[EUI].zone_gpio] │ ▼ [rpi-gpio out: Output, BCM, Active Low, initial high] │ ▼ [Delay 3 seconds] │ ▼ [rpi-gpio out: reset pin high (relay off)] │ ▼ [Debug + Log to file /var/log/duress.log]

Flow 2 — Watchdog (heartbeat supervision)

[Interval trigger every 60s] │ ▼ [Function: check last-seen timestamp for each device in context store] │ ▼ [Switch: any device silent > 13 hours?] │ yes ▼ [rpi-gpio out: GPIO 21 low (Trouble relay energised)] │ ▼ [Log + Push notification: "Duress button X offline"]

Flow 3 — Heartbeat recorder

[MQTT in: application/duress/+/device/+/event/up] │ ▼ [Function: update context store with last-seen timestamp for EUI]

Flow 4 — Gateway liveness watchdog

[Interval 60s] │ ▼ [Exec: ping -c 1 -W 2 192.168.1.250 (UG67 IP)] │ ▼ [Switch: fail count > 5?] │ yes ▼ [rpi-gpio out: GPIO 21 low (Trouble)]

8.3 Reference flow JSON

A complete pre-built flow JSON will live alongside this guide as duress-flow.json. Import into Node-RED via Menu → Import → paste JSON → Deploy.

8.4 Active-low relay configuration

In each rpi-gpio out node in Node-RED:

💡 Test flow before you wire the Bosch
Before hooking the relay outputs into the Bosch zones, run everything with the relay contacts floating and a multimeter across them. Verify each button press closes the correct relay for the correct duration. Only THEN wire into the Bosch and cause real alarms.

9. Testing Protocol

Run through this checklist on your bench before anything goes to site.

9.1 Component tests

9.2 End-to-end tests (per button)

9.3 Range testing

9.4 Stress tests

9.5 Before handover


10. Deployment Notes

⚠ Monitoring station coordination
Before any live test, email the monitoring company with: the site address, the test window, and the zones you'll be triggering. Otherwise your first test dispatches a response unit to a mining camp at 2am.

11. Open Questions & Risks

ℹ UC501 GPIO TLV channel numbers
The included decoder is based on the UC50x protocol doc, but firmware versions differ. Verify against your UC501's actual uplinks by watching raw MQTT and adjust the decoder bytes if needed.
ℹ Sub-band 2 vs Sub-band 8
Confirm your UG67 and UC501 are in the same sub-band. Default is sub-band 2 for AU915, but it's worth double-checking — if they're mismatched the devices will never join, and the failure is silent.
ℹ Tamper DI wiring
Milesight UC501 GPIOs are typically pulled up internally. NC contact to ground should give the correct edge trigger but confirm in ToolBox after first install.
ℹ Power at each laundry
UC501 on battery is good for 2–5 years with a 6-hour heartbeat. If you want mains backup, feed 5–24V DC to the UC501's power input and it will trickle-charge the built-in cell.
⚠ Lightning / surge
In a mining camp environment, consider gas discharge arrestors on the UG67 antenna line and surge protection on the Pi power. Mining camps see real lightning, and losing the whole system to one strike is an expensive lesson.

12. Appendix — Files & References

Files in this project folder

Located at /mnt/shared/research/lorawan-duress/:

Useful references

ResourceURL
Milesight UC50x User Guideresource.milesight.com/milesight/iot/document/uc50x-series-user-guide-en.pdf
Milesight UC50x Communication Protocolresource.milesight.com/milesight/iot/document/uc50x-series-communication-protocol-en.pdf
Milesight UG67 User Guideresource.milesight.com/milesight/iot/document/ug67-user-guide-en.pdf
ChirpStack Node-RED integrationchirpstack.io/docs/guides/node-red-integration.html
Milesight ChirpStack V4 Integrationsupport.milesight-iot.com/support/solutions/articles/73000610017
Bosch Solution 6000 Installation Manualmanualslib.com/manual/1210378/Bosch-Solution-6000.html
LoRa Alliance AU915 regional parameterslora-alliance.org/resource_hub/rp002-1-0-4-regional-parameters/

Supplier contact list

SupplierWebsiteNotes
IoT Store AUiot-store.com.auRetail + trade, Milesight + Dragino in stock, fast AU dispatch
Tekdis AUtekdis.com.auOfficial Milesight distributor AU/NZ, project pricing for volume
Powertecpowertec.com.auAlternative Milesight stockist
Core Electronicscore-electronics.com.auRaspberry Pi + accessories, Australian
Jaycarjaycar.com.auEnclosures, pushbuttons, basic electronics
RS Components AUau.rs-online.comIndustrial pushbuttons, Phoenix Contact terminals
element14 AUau.element14.comSame as RS, different stock/pricing

13. Quick Build Order

Shortest path from zero to working prototype:

  1. Order parts from the BOM: UC501 ×1 first for testing, UG67 ×1, Pi kit, relay board, enclosures, buttons, antennas
  2. While parts are shipping: flash Pi, install Mosquitto + Node-RED on the bench
  3. Configure UG67 on the bench, join it to ChirpStack built-in network server
  4. Join one UC501 via NFC, watch MQTT uplinks arrive
  5. Wire one e-stop button to that UC501, test end-to-end: MQTT → Node-RED → GPIO → multimeter on relay
  6. Wire to a test Bosch panel (or the CM705B expander from the actual job), verify zone fires
  7. Once one works, order the remaining 6 UC501s + enclosures, build in parallel
  8. Full bench test all 7 with the testing protocol in section 9
  9. Deploy to site using the deployment notes in section 10
💡 Realistic timeline
Expected bench build time: 2–3 days for the first working prototype once parts arrive. 1 day to build out the other 6 once the template is dialled in. Then 1 full day onsite for deployment + commissioning. Plan for double that on your first one.

Version History

VersionDateAuthorChanges
1.011 April 2026Cameron PollackInitial HTML release, converted from markdown build guide dated 8 April 2026