Setting Up a Zigbee Sensor Network

The advantage of Zigbee devices is that they are very low power, and they communicate in a wireless mesh network. The sensors are small and can work off a CR2032 coin cell for at least 2 years, maybe more. Depending on the type of sensor, they cost around US$10 and are readily available from various manufacturers, such as Xiaomi, Aqara (pictured below) or IKEA under their TRÅDFRI range of products.

You typically pair these sensors with a Zigbee gateway, which speaks the IEEE 802.15.4 protocol and relays the information (e.g. sensor readings) to either your mobile app or stores it in the cloud (or the gateway itself). But as you can imagine, a Raspberry Pi with the right adapter can do this job and offer more flexibility.

Continue reading

Custom Firmware for the Xiaomi AX3600 Wireless Router

As I have mentioned in the review, the stock firmware on the Xiaomi AX3600 wireless router is extremely limiting. On top of that, the firmware is also locked to install only authorized updates from the manufacturer. If you have been following the blog, you will know that I like the flexibility that ASUSWRT provides for customizing my router.

While there is currently an on-going effort to try and port vanilla OpenWRT for this router, I suspect that might take some time. In this post, I describe how to workaround the lousy firmware and configure the router with the advanced features I need.

Router Disassembly

It is recommended to have UART access handy, in case something bad happens and you need to recover your router, or if you want access to U-Boot, the bootloader. This would require you to crack open your router, so you might only want to do this if necessary. Feel free to skip this section if you are not interested in the hardware, or don’t need low-level access.

router top view, with cover opened

You need to unscrew 5 screws, 4 of which are hidden under the rubber feet, and one under the center sticker label. In the disassembled top view photo here, you can see the screw holes at the corners, as well as a missing chunk in the center of the heatsink for the mating screw post, directly aligned with the AIoT antenna and indicator LEDs.

Continue reading

Xiaomi AIoT Wireless Router AX3600 Review

I recently bought the Xiaomi AIoT AX3600 wireless router to experience WiFi 6 (or 802.11ax). This WiFi 6 router has been touted as having very good hardware specs for under US$100. After checking out a few reviews, it looked like you could achieve close to Gigabit speeds over a wireless link, which was pretty exciting. It reminded me of the time I upgraded my home network to Gigabit and could finally copy large files over the network quickly. I decided to get my hands on one and evaluate it with some speed tests around the house.

the Xiaomi AX3600 wireless router

I don’t have any compatible WiFi 6 devices yet, so I ordered an Intel AX200NGW wireless card to replace the one in my laptop. These cards typically go for US$15 on AliExpress or eBay.

Continue reading

Detailed Wireless Client Stats with collectd

collectd has always been able to grab interface traffic statistics from Linux. But what if we want to collect data about individual WiFi clients that connect to it? How much bandwidth is each of the clients using?

That information is already being recorded by the wireless driver; all we need to do is to query it. Turns out you can do that with the wl utility. This is Broadcom’s proprietary tool to control and query the wireless interfaces.

To do this, first use wl to get associated stations:

wl -i eth2 assoclist

Given a particular MAC address that is associated to the AP, query its info using sta_info:

# wl -i eth2 sta_info d4:a3:00:aa:bb:cc
 STA d4:a3:00:aa:bb:cc:
     aid:2
     rateset [ 6 9 12 18 24 36 48 54 ]
     idle 0 seconds
     in network 16 seconds
     state: AUTHENTICATED ASSOCIATED AUTHORIZED
     flags 0x11e03b: BRCM WME N_CAP VHT_CAP AMPDU AMSDU
     HT caps 0x6f: LDPC 40MHz SGI20 SGI40
     VHT caps 0x43: LDPC SGI80 SU-BFE
     tx data pkts: 663916
     tx data bytes: 68730715
     tx ucast pkts: 155
     tx ucast bytes: 42699
     tx mcast/bcast pkts: 663761
     tx mcast/bcast bytes: 68688016
     tx failures: 0
     rx data pkts: 234
     rx data bytes: 73557
     rx ucast pkts: 192
     rx ucast bytes: 62971
     rx mcast/bcast pkts: 42
     rx mcast/bcast bytes: 10586
     rate of last tx pkt: 866667 kbps
     rate of last rx pkt: 780000 kbps
     rx decrypt succeeds: 195
     rx decrypt failures: 1
     tx data pkts retried: 19
     tx data pkts retry exhausted: 0
     per antenna rssi of last rx data frame: -61 -56 -59 0
     per antenna average rssi of rx data frames: -61 -56 -57 0
     per antenna noise floor: -104 -98 -98 0

The “easy way” is probably to write a shell script, invoked via the Exec plugin that calls wl multiple times (once per interface, and once for each WiFi client) and uses grep or awk to get the information we need. This won’t be performant, of course.

wl itself does have quite a fair bit of overhead. It does some verification of the provided interface name. It checks for the Broadcom driver magic to ensure that the interface is a Broadcom device. It then needs to convert the MAC address from the argument string to binary, and vice-versa. Sure, that’s not really much “these days”, but we can definitely do better.

Instead, let’s short-circuit the process and write a plugin that directly collects the data, without going through wl. This way, we avoid creating several new processes for every query.

Continue reading

Cross-compiling collectd for ASUSWRT

I have been using collectd on my server to monitor traffic (inbound, outbound and to/from the Internet), as well as disk stats because it’s being used as a NAS. So far it has been helpful, observing various graphs to understand patterns, and detecting problems when they happen.

I’m also recording video from a WiFi camera, so I can constantly see traffic that comes into the server. But without visibility on the router itself, I am unable to determine whether the traffic is from the 5 GHz or 2.4 GHz band, or the guest network.

By getting a collectd instance onto the router, we can get those detailed interface statistics separately.

Continue reading