Fox Red Labs / Builds / Smart home and radio
Show a low-power temperature sensor on your Home Assistant dashboard
A Zigbee temperature sensor that sleeps between polls shows up on your Home Assistant dashboard. Built on the CC1354P10-1, on USB power, not a battery.
HardNo wiringabout 10 min from build to the first reading
Parts and steps
You need
- LP-CC1354P10-1 LaunchPad development kit the board, with a CC1354P10 chip and 256 kB of RAM
- Home Assistant Connect ZBT-2 Buy the Zigbee coordinator Home Assistant talks through; the only one tested
- Zigbee smart plug a mains-powered Zigbee relay near the board. In the test every join went through one, because the ZBT-2 was out of the board's range
- USB data cable (micro-USB to your Mac) powers and programs the board; no battery in the recorded run
- CR2032 coin cell and holder (optional) optional battery power: the board runs from 3.3 V, so a coin cell wired to 3V3 and GND with the USB power jumper removed is the usual option; battery life was not measured
Read this before you load anything.TERMINAL
On this board the debugger connects only in the first seconds after a power-on boot, and once the sleepy image is loaded it cannot get back in. The way back that worked is the loop below (the same one as in step 5's fix line): start it first, then unplug and replug the USB cable. It needs the image from step 3, so build first. Replace
<repository folder>with your clone. Keep that line, or a non-sleeping image and its backup, before you leave this image on a board you share.Replace <repository folder> before you run this.
cd <repository folder> for i in $(seq 1 60); do /Applications/ti/ccs2101/ccs/scripting/python/run.sh cc1354p10/tools/ccs_load_run.py cc1354p10/zigbee-sleepy-sensor/out/frl_sleepy_sensor.out && break; doneYou should see: You have the recovery line to hand before the board is running the sleepy image.
Install the tools once, all free: CCStudio 21.0.1 from TI's CCStudio download page and the SimpleLink CC13xx CC26xx SDK 8.33.00.16 from TI's SDK page (2.6 GB installed; the download size was not recorded).TERMINAL
The paths in the scripts are where TI's installers put them:
/Applications/ti/ccs2101and/Applications/ti/simplelink_cc13xx_cc26xx_sdk_8_33_00_16.You should see: Both folders are under
/Applications/ti.Build the sensor from the repository root.TERMINAL
The script copies TI's
zed_temperaturesensorexample and the three app files it links. It appliessleepy_sensor.patch, which gives a real temperature reading, names Home Assistant can show, working attribute reads, joining without a button, and all 16 channels searched. It imports the project with CCStudio's headless command line and builds it.cc1354p10/zigbee-sleepy-sensor/build.shYou should see: About 21 s later the script prints the FLASH, SRAM and CCFG lines of the linker map and
built:followed by the path ofcc1354p10/zigbee-sleepy-sensor/out/frl_sleepy_sensor.out. The image is 179.4 kB of flash and 45.5 kB of RAM.Open joining first.BROWSER
In Home Assistant go to Settings, Devices & services, Zigbee Home Automation, Add device. Joining stays open for about 4 minutes. If your board is out of the coordinator's range, call the
zha.permitservice from Developer tools, Actions on the router it can reach:duration: 254and that router'sieeeaddress.You should see: Home Assistant is searching for Zigbee devices.
Load the image and start it.TERMINAL
This board needs a CCStudio scripting run to start a freshly loaded program; a plain UniFlash flash does not start it until you unplug and replug the USB cable.
run.shis CCStudio's own scripting Python./Applications/ti/ccs2101/ccs/scripting/python/run.sh cc1354p10/tools/ccs_load_run.py cc1354p10/zigbee-sleepy-sensor/out/frl_sleepy_sensor.outYou should see: After about 15 s the script prints
loaded and runningand the path of the image.Watch the board's own screen at 115200 baud. ls /dev/cu.usbmodem* lists two ports for the probe; the board's serial screen is the one ending in 1.TERMINAL
Replace
<probe serial>with yours, brackets included. To find yours, run/Applications/ti/ccs2101/ccs/ccs_base/common/uscif/xds110/xdsdfu -eif you have CCStudio (it printsSerial Num:), elsesystem_profiler SPUSBDataType | grep -A3 XDS110.Replace <probe serial> before you run this.
screen /dev/cu.usbmodem<probe serial>1 115200You should see:
[State] In the networkon the "ZDO Info" line and[PAN ID] 0x....with your network's channel on the "NWK Info" line. On the clean run that took 6.0 s from boot.Prove the join from Home Assistant's device list rather than the board's screen.BROWSER
Give it a few minutes. Home Assistant asks the sleeping board a set of questions, and about half of its first requests get no answer until the board's next poll.
You should see: About 162 s after boot a device named "Fox Red Labs Temp Sensor" appears. It is an end device with power source "Battery or Unknown", one temperature entity and an identify button. The reading was 22 C on the serial line and Home Assistant showed 71.6 F because Home Assistant is set to Fahrenheit.
Let Home Assistant ask for the value.BROWSER
The reporting interval is set by Home Assistant and not by the board. It set a minimum interval of 30 s, a maximum of 900 s and a reporting change of 0.50 C.
You should see: At a steady temperature the first report arrived 899.9 s after Home Assistant set up reporting. Reads you ask for from Home Assistant came back in 1.6 s (median), because the board polls its parent every 3 s.
Or hand it to a coding assistant
Paste this in a terminal. It hands off to an AI assistant.
git clone --depth 1 --filter=blob:none https://github.com/Fox-Red-Labs/fox-red-labs.git && cd fox-red-labs
./start.sh cc1354p10 battery-sensor-home-assistant --assistant claudegit clone --depth 1 --filter=blob:none https://github.com/Fox-Red-Labs/fox-red-labs.git && cd fox-red-labs
py start.py cc1354p10 battery-sensor-home-assistant --assistant claudeIt runs the steps above and reports what it saw.
Not Claude Code? Copy this prompt instead.
If something goes wrong
| A replug with no loop already running missed the window twice in the test | Nothing from software got the debugger back: not the serial menu's reset, not hundreds of connects, not holding the left button through a reset. |
| They live elsewhere | build.sh reads SDK and CCS_CLI from the environment, and /Applications/ti/ccs2101/ccs/scripting/python/run.sh in step 5 needs the matching path. |
| The build summary says "0 out of 1 projects have errors" even when SysConfig failed | So the script checks that the image exists and stops with "no image built" if not. One warning about NVOCMP_NVPAGES and a note that the headless import swapped the compiler to TI Arm Clang 4.0.4.LTS are normal. To list only your own network's channel instead of all 16, edit zstack.rf.primaryChannels in the patch before building; that avoids the board trying other networks first. |
| The board is out of the coordinator's range and joining is open on the coordinator alone | The board finds no network in 3 minutes. Open joining on the router and keep the board near it for the first join. |
| The debugger will not connect | This is the recovery loop; it tries up to 60 loads and stops at the first one that gets in. Start it, then unplug and replug the USB cable. It got in on the 21st attempt, about 10 s after the replug, in the seconds the chip stays awake at boot. Put the image you want back on the board in place of the sleepy sensor's. |
More troubleshooting
| At step 6 | To log it with timestamps and decode it afterwards, use cui_log.py (capture, then decode) in the same folder. |
| The board joined another open network first | List only your channel as in step 3. The board tries the first network it finds, and each failed try costs 3 s. Four of six association tries on this bench lost the network key. It arrived after the 3 s that TI's stack waits for it, and why it arrived late was not found. |
While Home Assistant is still setting it up, it may list the device as unk_manufacturer unk_model with no value | That is the setup still running, and on TI's unpatched example it never finishes: every attribute read fails with status 0xC1. To start over, remove the device in Home Assistant and wait until it is gone. Use the serial menu's RESET TO FN, which resets to factory new, and load the image again. The board stays silent after that reset until it is loaded again. |
| A reading that looks stale for up to 15 minutes at a steady temperature is the reporting setting | It is not a fault. |
| You re-pair after removing the device | Home Assistant keeps the old entity id sensor.unk_manufacturer_unk_model while the device is named "Fox Red Labs Temp Sensor". Rename the entity if it matters. |
Every fix for this board: the FAQ.
What to build next
Every build. The code for all of them is in the GitHub repository.
Evidence and limitsA sleepy Zigbee sensor joined Home Assistant 6.0 s after boot on the CC1354P10-1; 20 of 20 reads; current draw was not measured. Ran on 1 board. Results, sources, timing and limits.
Expected result: A device named "Fox Red Labs Temp Sensor" shows up in Home Assistant a few minutes after the board boots, with a temperature that reads about 22 C in the test room. It keeps reporting while it sleeps between polls.
What this shows
- TI's temperature-sensor example, patched, joins a Home Assistant (ZHA) network through a ZBT-2 as a sleepy end device: its node descriptor says the receiver is off between polls.
- Home Assistant can read its temperature on demand: 20 of 20 reads returned 22.00 C, median 1.6 s, as a 3 s poll predicts.
What this does not establish, and limits
What this does not establish
- Battery life or sleep current. No battery was used and there was no meter on the bench. The serial menu may also keep the chip out of its deepest sleep; a build without it was not made.
- That the temperature tracks the room. Only 22 C was seen; the chip was not warmed or cooled and no thermometer sat beside it.
- That the join is reliable. The clean 6.0 s join is one run; 4 of 6 earlier association tries lost the network key.
- Anything after the first hour: packet loss, range, and the board's signal strength to its parent were not measured.
Limits to keep in mind
- One clean join; three runs are needed before quoting a median.
- After the debugger lock-out in step 1 the board needs the recovery loop to be reprogrammed.
- On the final build, Home Assistant's whole Zigbee integration went down before the next report was due. Its radio disappeared from the hub's USB, for a reason outside the run. A report on the final build was not seen. The board stayed in the network.
- Checked on an Intel Mac only.
Sources
Versions, sizes and timing
| Image size | 179.4 kB of flash and 45.5 kB of RAM of 256 kB of SRAM; TI's example as shipped is 183,230 and 46,449 (the patch adds 508 and 152). A further 10 kB of flash are reserved for the stack's non-volatile storage | the data (CSV) |
|---|---|---|
| Toolchain | SimpleLink CC13xx CC26xx SDK 8.33.00.16 (Z-Stack, TI-RTOS 7), CCStudio 21.0.1 headless with SysConfig 1.28.1 and TI Arm Clang 4.0.4.LTS, -Oz -g | README notes |
| Build and load time | 21 s build, 15 s load, 6.0 s to join, 162 s until Home Assistant showed the entity | README notes |
| Read latency from Home Assistant | 20 of 20 reads; median 1,574 ms, spread 171 to 2,799 ms; the board polls every 3,000 ms | |
| Reporting set by Home Assistant | minimum 30 s, maximum 900 s, change 0.50 C; first report 899.9 s after setup at a steady 22 C |
Evidence
- Ran on the CC1354P10-1 on 2026-10-07 (one run): joined the house Zigbee network 6.0 s after boot; Home Assistant showed "Fox Red Labs Temp Sensor" with the chip temperature (22 C, shown as 71.6 F) 162 s after boot; 20 of 20 reads from Home Assistant returned 22.00 C. README notes
- The board's own serial screen, decoded, shows "In the network" at about the same time (5.6 s on the board's clock, 6.0 s measured from the reset).
- The 20 reads from Home Assistant: median 1,574 ms, 171 to 2,799 ms.
Other boards
- CC2340R5
- MSPM0G3507, MSPM0L1306, F2800137Not for this chip no radio
What the status words mean
Works ran here and did what it shouldCould work some of it ran; real porting effort is left; hover for whatNot for this chip the chip or its vendor software cannot; hover for why
Result grid
Works ran here and did what it shouldShould work it builds; only naming, packaging or build glue is in the way; hover for whichCould work some of it ran; real porting effort is left; hover for whatNot for this chip the chip or its vendor software cannot; hover for why
Source files
- LP-CC1354P10-1 Zigbee sleepy sensor notes (CC1354P10-1)
Get the code and tell us how it wentThe clone command, the board folder with its AGENTS.md, reports from others, and the three report forms.
Get the code
Clone the repository and open the board's folder below. AGENTS.md is a plain text file of notes for AI coding assistants, and llms.txt at the root indexes the site for one.
git clone https://github.com/Fox-Red-Labs/fox-red-labs.git
- LP-CC1354P10-1: folder
cc1354p10/.- README: the board's lab notebook (what was run, in order)
- Notes for an AI coding assistant working in this repository: notes for an AI assistant; copy it into your own project if you use one
- FAQ: errors and fixes
Code is BSD-3-Clause, writing is CC BY 4.0; third-party folders keep their own licenses.
Built it? Tell us
Built this, or got stuck? Report it on GitHub with a few short answers. Your report shows here in your words, marked as yours. A failure that repeats on the bench gets its fix here.