Connected Devices
A chip in a kitchen measures 21.4 degrees. A phone in another country shows 21.4 degrees. Between those two facts sit ten separate things that each have to work, and any one of them can quietly fail and leave the phone showing a number from yesterday. This course follows one reading the whole way, stage by stage, and lets you break every stage and watch the reading not arrive. Then it sends a command back down the same path, works out what it costs a coin cell, and pulls the power out half way through a firmware update.
Every figure on these pages is worked out by one simulator that runs when you move a control. It has a device, a broker, a subscriber, and a radio link between the device and the broker. That link can drop a packet, hold it up, duplicate a delivery, or stop carrying anything at all. Beside it sits an energy model with a real coin cell in it: the flat round battery from inside a watch. When a page says a choice costs four times the battery life, something on that page has divided one computed number by another to get the four.
Embedded Systems comes before this one. It builds the chip, the pins, the sensor and the reading, and this course starts the moment that reading exists and asks where it goes next. Computer Networks and Reliable Data Transfer own addresses, routing and the business of getting bytes across a link that loses them. Both are referred to and neither is repeated. If you have not read them, nothing here will stop working: every term is introduced where it is used.
The steps
Small, on a battery, on a radio, with one job
Count the computers in a house. The one on the desk is easy. Then there is the doorbell camera, the thermostat on the wall, the fitness band on a wrist, and the plant sensor in a pot by the window. Each of those has a chip inside it running a program, so they are all computers. They are just computers that do not look like one.
Four things separate them from the computer on the desk. They are small: the chip costs about a pound and has less memory than a single photograph. They run on a battery, or on a supply not much bigger than one, so everything they do has to be paid for in charge. They have a radio instead of cables, usually wifi; everything they say goes through the air in short bursts. And each one has exactly one job: nobody sits at it, nobody types into it, and it is expected to do that job alone, for years.
Two words before the first stage, because everything after this uses both. Data crosses a network in a packet: a short run of bytes carrying its own delivery address, like a postcard. A big message is cut into several packets, and any one of them can go missing on its own. And the program inside a device is called its firmware, kept in a memory that holds its contents when the power goes, so it knows its job tomorrow.
What is a packet, exactly?
A run of bytes, usually a few dozen to about 1500, wrapped with the address it is going to and the address it came from. The network reads the wrapper and never the contents, the way a postal worker reads an envelope and not the letter.
Packets matter here because each one travels alone: one can be lost while its neighbours arrive, one can be delayed, and one can even be delivered twice. Every strange behaviour in this course comes from those three facts. Computer Networks builds packets properly; this course only needs the envelope picture.
Is a thermostat really a computer, and not just a switch?
A switch closes when a person moves it. A thermostat reads a sensor, compares the number with a target, decides, and moves the switch itself. Reading, comparing and deciding is a program running, and the thing running it is a computer.
The test is whether the behaviour can be changed without changing the parts. A thermostat can be given a new schedule, a new target, even a whole new program. A bare switch cannot. That flexibility is the whole reason to put a chip in, and it is also what a firmware update, much later in this course, is allowed to replace.
Why give a device only one job?
Because the battery decides. A chip doing many jobs has to stay awake to see what turns up, and staying awake is the one thing a small battery cannot pay for. A device with one job knows exactly when it has nothing to do, and sleeps.
One job also means one honest answer to the question is it working? A desk computer that is misbehaving has a person in front of it to notice, and a plant sensor has nobody. The fewer things it can be doing, the easier it is for the far end to notice that it is doing nothing. A lot of this course is about noticing exactly that.
This course follows one such device, a temperature sensor in a kitchen. The lab below opens five machines up so you can see what the four differences look like as parts.
Ten stages between a sensor and a screen
Start with the thing you already have. A sensor on a chip has produced a number, 21.4 degrees, and it is sitting in a variable. Getting that number onto a distant screen is often described as one step, and people write it in a plan as a single line: send it to the cloud. It is not one step: it is ten, and every one of them fails in the field, usually on a Sunday.
Here they are in order. Read the sensor. Join the wifi network. Be given an address. Turn the name of the far machine into an address. Open a connection to it. Check it is who it claims to be. Log in. Publish the reading. Have the far machine work out who wants it. Have the screen draw it.
Each one has its own failure and its own repair. This course is one step per stage, plus a few more for the things that only show up once the basics work. The lab below is the map, and you will come back to it.
What is a millisecond, and why do these numbers matter?
A millisecond is a thousandth of a second, written ms, and a blink of an eye is about 150 of them. The numbers in the lab are how long each stage takes on a small wireless board of the kind you would put in a kitchen sensor. They are not evenly sized: the smallest is 2 ms and the largest is 1200.
They matter because a device on a battery pays for time. While any of this is happening the radio is switched on, and a radio that is on draws roughly fifteen thousand times as much current as one that is asleep. Step 11 turns these milliseconds into months of battery life.
Is this the same thing as loading a web page?
The middle of it is, more or less. A browser also resolves a name, opens a connection and checks a certificate. The two ends are different. A browser starts on a machine that is already on a network, so the first three stages happened while you were making tea. And it wants an answer back at once, so a human can read it.
A sensor has to do the joining itself, every time it wakes up, with nobody there to type a password if it goes wrong. And it does not want an answer. It wants to say one short thing and go back to sleep for fifteen minutes. Those two differences produce nearly every design decision in this course.
Why does this list have a broker in it and not just the phone?
Because the phone cannot be reached and neither can the device. Both of them sit behind a box that gives them an address usable only inside one building or one mobile network. Neither box lets a stranger start a conversation from outside. Step 4 lets you try it and watch it fail.
The way round it is that both sides dial out to a third machine that does have a reachable address, and that machine passes messages between them. That machine is called a broker, and Steps 5 to 7 are about what it does once it exists.
The other thing worth reading off the map is where the time goes. The stages are not the same size, and the biggest of them is not the one people expect.
Get a device onto a wifi network, and break each part of it in turn
Joining a wifi network sounds like one action because that is how a phone presents it. Underneath it is three separate agreements with three different parties, and they fail in three different ways.
First, association. The device finds the access point by name, proves it knows the password, and is allowed to send frames onto the network. It now has a neighbour it can talk to and nothing else. Second, DHCP, which stands for dynamic host configuration protocol and means asking the network to lend you an address. The device shouts a request, something answers with an address, how long it may keep it, and which machine to send everything not on this network to. Third, DNS, the domain name system: turning a name a human typed into an address a machine can aim at.
Only after all three does the device have what a program needs: permission to speak, a return address, and somewhere to aim.
What is an address, exactly?
A number that identifies one machine on a network, written for humans as four smaller numbers with dots between them, such as 192.168.1.42. Anything sent to that number arrives at that machine and nowhere else. Computer Networks builds addresses properly, including why they have structure and how a router uses that structure to decide which way to send a packet.
What matters here is that a device does not own one. It borrows one, for a stated period called a lease, and it has to ask again before the lease runs out. A device that sleeps through the end of its lease wakes up with an address that may now belong to a laptop.
Why does association take three hundred milliseconds when the network is right there?
Because it is a conversation, not a message: the device scans the channels for the network it wants, which means listening on each in turn. It then exchanges several frames to prove it knows the password without ever sending the password, which takes four messages of arithmetic on both sides. Only then is it allowed to send anything of its own.
Some of that can be cached. A device that remembers which channel its network was on last time skips most of the scan. Real low-power products do exactly this, and it is the difference between 300 ms and about 90 ms.
What happens if the DNS server is unreachable but the device has looked the name up before?
It uses the answer it kept. Every answer from the name system arrives with a time to live: how many seconds it may be believed before it must be asked again. Inside that period the device does not ask anybody, so a name server that has fallen over is invisible.
The second lab lets you run exactly that case. It is worth knowing because it produces one of the nastiest field faults there is. A fleet keeps working perfectly for an hour after something important has broken, and then all of it fails at once when the last cached answer expires.
Nothing outside the house can reach the device
The device now has an address: 192.168.1.42. So the phone should be able to send it a message. It cannot, and the reason is worth understanding properly, because it is the argument for everything in Part 2.
192.168.1.42 is a private address. There is one in nearly every building in the world, and they do not identify anything outside the building they are in. The house has exactly one address that works from outside and the router owns it. When something inside sends a packet out, the router rewrites the sender to be itself, writes down what it did, and un-rewrites the reply on the way back. That rewriting is network address translation, or NAT and the note it writes down is a row in a table.
Two things follow, and both are in the lab. A packet arriving from outside with no matching row is dropped, because the router does not know which of the fifteen machines in the house it is for. And a row is deleted after a period of silence, so a conversation that goes quiet stops working without anybody doing anything.
Why not just give every device an address that works from outside?
The older numbering scheme, called IPv4, has about four billion addresses in it. That sounded generous in 1981 and ran out around 2011. There are more connected devices than that. The newer scheme, IPv6, has enough for every grain of sand, and where it is deployed a device really can have an address of its own.
It has not fixed this, for two reasons. Deployment is patchy, so a product that relied on it would not work in a lot of houses. And having a reachable address is not the same as being reachable. The firewall in the router, the part whose job is refusing uninvited connections, still refuses them by default, and almost everybody wants it to. The broker is the answer under either scheme.
Could the device just tell the phone what its address is?
It can, and it does not help. The public address belongs to the house, not to the device, so the phone would still be knocking on a door with no row in the table behind it. And that address changes: many providers hand out a different one after a reboot or every few days.
There is a family of techniques that make direct connections work anyway. Both sides dial out to a helper at the same moment, so that two rows appear in two tables at once. Video calls use it. It is intricate, it fails on some networks, and it needs the helper anyway, which is why almost no sensor product does it.
How long does a row really last?
It depends who owns the box, and the range is enormous. The standard asks for at least two hours and fourteen minutes for an established connection. Plenty of home routers honour that. Mobile networks, where one public address may be shared by thousands of subscribers, are far less generous, and five minutes is common.
The lab uses five minutes because that is the number a product has to survive. Step 11 shows what it costs: the device must send something, anything, more often than the shortest table timeout in the path, or the way back to it closes.
So neither end can be dialled. The way out is that both ends dial out, to the same third machine, which does have an address anybody can reach and never goes to sleep. That machine is the broker. The device holds a connection to it; the phone holds a connection to it; the broker passes messages between the two. Neither end ever knows the other's address.
Publish to a topic, and subscribe to one
The device has a connection to a broker. Now it needs a way to say what a message is about, because the broker has thousands of connections and no idea which of them wants this reading.
The answer is a topic: a label the sender attaches to a message, written as words with
slashes between them, like a path. This device publishes to
home/kitchen/temperature. Anybody who wants kitchen temperatures tells the broker so, and
the broker keeps the list. Telling it is called subscribing; sending a message with a topic on
it is publishing. The whole protocol these two words come from is MQTT, which is what
most connected products actually speak.
The important part is what nobody says: the device does not know who is subscribed, or whether anybody is. The phone does not know which device sent what it is reading, and neither has the other's address. The topic is the entire agreement between them.
How is this different from asking for the reading?
Asking means one side has to know how to reach the other, has to be awake at the moment the other one asks, and has to answer. Every one of those is a problem for a sensor on a battery behind a router. Publishing means the sensor says its piece when it wants to and goes back to sleep, and whoever cares finds out when they next look.
The technical name for the difference is coupling. Asking couples the two ends: they have to agree on an address, be awake together and stay compatible. Publishing couples both of them to a name instead, which is a much cheaper thing to keep stable.
What makes a good topic?
General to specific, left to right, so that a wildcard part way along means something useful.
home/kitchen/temperature lets somebody subscribe to one room. Writing it the other
way round, temperature/kitchen/home, would let somebody subscribe to all temperatures
everywhere, which nobody wants.
Two things to avoid. Do not put anything in a topic that changes when nothing has really
changed, such as a firmware version, because every subscriber then has to be updated. And do not
put a value in the topic, as in home/kitchen/temperature/21.4, because a subscriber
would have to subscribe to every possible reading to see any of them.
What if two devices publish to the same topic?
Both messages go to every subscriber, in the order the broker received them, and nothing marks which came from where. The broker does not police topics. This is usually a mistake in the naming, fixed by putting the device's serial number into the topic and letting subscribers use a wildcard when they want the lot.
Occasionally it is deliberate, and useful: several door sensors publishing to one
home/doors/opened topic gives a subscriber a single stream of door events without
caring how many doors there are.
home/kitchen/temperature and publish again. Then add
home/+/temperature as a second subscriber and watch one message go to two places.Two characters make subscriptions useful across many devices. A + stands for exactly
one level and matches anything in that position. A # stands for everything from that
point down, and has to be the last thing in the filter.
home/+ and, before pressing anything, decide whether it matches
home/kitchen/temperature. Then press Check my prediction. Most people get
this one wrong the first time.+ is exactly one level and not one or more.
home/+ matches home/kitchen and does not match
home/kitchen/temperature, because the second has a level the filter has nothing to
put against it. If you want everything under a point, that is #, and nothing
else.home/kitchen/temperature,
home/hall/temperature and home/kitchen/humidity. You want every reading
from the kitchen and nothing else. Which subscription does it?home/kitchen/#, and the reasoning is worth keeping. The hash
matches every level below the point it sits at, so both kitchen topics arrive and the hall does
not. The first option reads as though it means kitchen, and it means every room's temperature.
The second is the trap from the lab: a plus is exactly one level, so it matches nothing three
levels deep. Getting the topic shape right early is cheap; changing it after ten thousand devices
are in kitchens is not.Quality of service 0, 1 and 2
The radio hop between the device and the broker loses packets. Not often, but it loses them, and the device has no way of knowing which ones. What to do about that is a choice, and MQTT makes you make it, one message at a time, by writing a number between 0 and 2 on each one. That number is the quality of service, usually shortened to QoS.
At 0, the device sends the message and forgets it, so if the packet is lost the reading is gone and nobody ever knows. At 1, the broker sends back an acknowledgement, and if it does not arrive the device sends the message again. At 2, there is a four-message exchange that lets the broker recognise a resend and refuse to pass it on twice.
The three are usually described as at most once, at least once, and exactly once. Those phrases are accurate and they hide the interesting bit, which is what level 1 costs you. The lab runs sixty readings at each level over the same lossy link and counts what came out.
Why does an acknowledgement being lost cause a duplicate?
Because the device cannot tell the two failures apart. If it sends a reading and hears nothing, that could mean the reading never arrived, or that it arrived and the acknowledgement was the packet that got lost. From where the device sits, those look identical.
It has to choose, and the only safe choice is to send again, because losing a reading forever is worse than sending one twice. So it resends, the broker receives a message it has already handed on and has kept no record of, and hands it on again. The duplicate is not a bug in anything. It is the price of a promise made over a link that loses packets, and Reliable Data Transfer is the whole course about that promise.
How does level 2 avoid the duplicate?
By making the broker remember. When it receives a message at level 2 it writes down the message number before doing anything else, and answers with a received. If the same number turns up again it recognises it, answers again and does not hand the message on a second time. Only when the device says release does the broker forget the number.
That is four messages for one reading instead of two, and it means the broker has to store something for every message in flight from every device. Level 2 is not a better version of level 1: it is a different trade, and the lab counts both sides of it.
Which level should a real product use?
Level 0 for anything that will be replaced by a better version shortly. A temperature every fifteen minutes is the perfect case: losing one costs nothing, because another is coming, and the graph has a small gap in it.
Level 1 for anything where losing the message matters and a repeat can be recognised, which is most things. Level 2 for the small set where a repeat cannot be recognised and would do damage: a meter reading that gets added to a total, a command that spends money. In practice level 2 is rare, because designing the message so a repeat is harmless is usually cheaper than paying for level 2 on every message forever. Step 12 is that design.
Retained messages and the last will
Two problems are left over from Step 5, and the broker has one switch for each of them.
The first: a subscriber that arrives after a message has been sent gets nothing, and has to wait for the next one. On a sensor that reports every fifteen minutes, opening the app can mean a blank screen for a quarter of an hour. The switch is retain. A message published with it set is kept by the broker as the last known value for that topic, and handed to every new subscriber the instant they subscribe. Exactly one message per topic is kept, and a new one replaces it.
The second: nothing tells anybody when a device stops. Publishing is one-way, so a device that has gone flat looks exactly like a device with nothing to say. The switch is the last will: a message the device hands the broker when it connects, with instructions to publish it if the connection ends without a proper goodbye. The device writes its own obituary in advance.
How does the broker know the device has gone?
By a timer, agreed when the device connects: the device promises to say something at least every so many seconds, and that period is the keepalive. If it has nothing to publish it sends a two-byte ping instead. The broker waits one and a half keepalives, and if nothing has arrived it treats the connection as dead.
So the will is not instant. With a sixty second keepalive the broker declares the device gone ninety seconds after its last word. That delay is a direct consequence of the number you chose, and Step 11 is where choosing it gets expensive.
What is a proper goodbye?
A disconnect message. One byte of intent that says: I am finishing on purpose, throw the will away. A device that is going to sleep, or being switched off by its owner, sends it and no obituary is published.
Every other ending skips it. A flat battery, a snapped wire, a crash, a router reboot, a phone walking out of range. All of those leave the will in place, and that is precisely the set of events you want to be told about. The lab lets you end the device both ways and see the difference.
Can the will and retain be combined?
Yes, and together they make one of the few tidy patterns in this subject. Publish
online to home/kitchen/status with retain set on connecting, and set the
will to publish offline to the same topic, also retained. Now that topic always holds
the truth, and any subscriber that appears at any time is told at once.
The pattern has a limit worth knowing. It reports whether the broker is hearing from the device, which is not quite the same as whether the device is working. A device whose sensor has failed but whose radio is fine will happily report itself online forever.
offline. The freezer is unplugged along with the sensor. How long until the alarm
fires, if the keepalive is 60 seconds?Put a different key in every unit
The broker will not accept just anybody, so the device needs a secret to prove it is allowed on. Getting that secret into the device is called provisioning, and on a bench with one device it is no problem: you type it into the source code and build.
That answer stops working at about two devices and gets steadily worse. The secret is now in the firmware image, and the image is on your website as a download. Anybody with a cheap clip and ten minutes can read the flash memory off a chip and find it. One secret in ten thousand units means one person, once, owns the whole fleet.
There are two better answers. Program a different secret into each unit on the production line. Or ship each unit with a one- time claim code, which it swaps for a secret of its own the first time it is switched on. The lab prices all three.
What is a key, in this sense?
A long run of random bits that the device knows and the broker knows, and that nobody else can guess. It might be presented as a password, or as a private key with a certificate around it. What matters here is not the format but the count: how many devices does one of these let you pretend to be.
Random is doing real work in that sentence. A key derived from something predictable, such as a serial number run through a fixed calculation, is one key wearing ten thousand hats. Reading one device tells you the recipe for all of them.
Is reading the flash off a chip really that easy?
On a lot of hardware, yes. Many chips leave the debug port enabled by default, and the tool to talk to it costs a few pounds. Where the debug port is locked, the flash is often a separate eight-legged chip on the board, and a clip that grips those legs is also a few pounds.
Parts with encrypted flash and a permanently disabled debug port exist and are worth using, but they change the cost of the attack rather than removing it. The rule that survives is the one the lab is about: never let the compromise of one device be the compromise of the fleet.
Why does a claim code work if it also ships in the device?
Because it is worth almost nothing, and only once. It is not a key but a token that says: the unit holding me has not yet been claimed. On first power-up the device presents it, receives a real key of its own, and the token is marked as spent. From then on it opens nothing.
The exposure it leaves is real and it is small. Somebody who reads a code out of a boxed unit before the customer switches it on could claim that one unit. Nobody can claim the fleet, nothing is exposed after first use, and cancelling one code costs a line in a database.
The claim exchange is worth stepping through, because it is the only part of this that is not obvious. Everything that can go wrong with it goes wrong in the first ten seconds of a device's life.
Check a certificate, and watch each check fail
The device has a key now. Before it sends that key anywhere, it has to know who it is sending it to. The mechanism for that is TLS, transport layer security, the same thing that puts a padlock on a browser.
TLS does two separate jobs and they are worth keeping apart, because only one of them is the hard one. The easy job is making the conversation unreadable to anybody listening. The hard job is deciding whether the machine at the other end is the one you meant. Encryption with the wrong party is a private conversation with a thief.
The second job is done with a certificate: a statement of who a machine is, signed by an authority the device was built already trusting. Four checks have to pass, each able to fail on its own, and the lab lets you fail every one of them.
What does signed mean here?
A signature is a number worked out from the document and from a secret that only the signer has. Anybody can check it against a public number, and nobody can produce it without the secret. Change one character of the document and the check fails.
So a certificate says: this name belongs to whoever holds this key, and here is my signature to prove I looked into it. The device carries a short list of signers it was built trusting, called root certificates. The chain from the certificate it was handed has to reach one of them.
Why does a device with no clock fail this?
Because two of the checks are about dates. A certificate is valid between two moments, and the device compares them with what it thinks the time is. A small board with no battery-backed clock wakes up believing it is the first of January 1970. That is before every certificate on earth was issued, so every one of them looks not yet valid.
The order of operations therefore matters. The device has to learn the time before it can check a certificate. The usual way to learn the time is over the network, which it has not been allowed onto yet. The standard answers are a cheap clock chip with its own coin cell, or an unauthenticated time taken from the network. The second is purely a starting point, never trusted for anything else.
What is the missing middle certificate about?
Authorities do not sign server certificates with their root key, because that key is kept offline in a safe. They sign an intermediate certificate with it, and the intermediate signs the servers. So a device has to follow a chain of two or three links to reach something it trusts.
The server is supposed to send the intermediate along with its own certificate. Some are misconfigured and send only their own. Browsers hide this by fetching the missing link themselves or by having seen it before. A small device does neither, so it fails against a server that appears to work perfectly in every browser anybody tries, which makes it a memorable afternoon.
Which brings us to the switch that is always there and always tempting: turning the checking off because the device will not connect and the demo is tomorrow.
Listen to your own traffic from the road outside
Wifi is radio: anybody within range receives every frame, whether or not it was for them, and a cheap adapter can capture nearby traffic. Assume somebody can listen, then test what the capture reveals and what an unauthorised sender can do with it.
Without TLS, they get everything: the topic, the reading, the username and the password, in readable characters. The password is the interesting one, because it does not just reveal this device's data. It lets the listener publish as this device, and after Step 8 you know whether that means one device or all of them.
With TLS, all of that goes dark. What does not go dark is worth knowing, and the second lab is about it. Plenty of products treat encryption as the end of the conversation, and it is not.
Is the wifi password not already encrypting this?
It encrypts the hop between the device and the access point, and only that hop. It is real protection against somebody in the road with no password, and it stops at the router. Everything beyond, across the provider's network and the wider internet, is carried in whatever the application chose.
It also does less than it looks like inside the house. On the older shared-password schemes, anybody who knows the wifi password, which is everybody who has ever been given the wifi password, can decrypt their neighbours' traffic on that network. A guest at a party is inside the fence.
What can a listener still see once it is encrypted?
Who you are talking to, and when, and roughly how much. The broker's address and port are on the outside of every packet, because the network needs them to deliver it. The name the device asked for is sent in the clear at the start of the handshake so that a server holding many names knows which certificate to present. And every message's size and timing is visible.
That last one sounds harmless. The second lab shows that it is not, and that the fix costs almost nothing, which is why it is worth doing.
Does this matter for a temperature?
The temperature, no. The pattern, yes. A house's readings say when somebody cooks, when the heating comes on, and when nobody has been home for four days. Researchers have identified which programme people are watching from the traffic of a smart television, and which appliance was switched on from the shape of a power meter's traffic.
The general rule is that data about a home is data about the people in it, and it is worth more to somebody unpleasant than the readings themselves ever are. That is the argument for padding, and for not sending anything you did not need to send.
The keepalive interval decides how long the cell lasts
Every choice so far has a price, and on a battery-powered device the price is paid in the same currency: how long the radio is switched on. A small board draws about 5 microamps asleep and about 75 milliamps with the radio up, which is fifteen thousand times as much. Nothing else on the board matters next to that ratio.
So the sum is simple. Work out how much charge each kind of wake-up costs, multiply by how often it happens, add the sleep current, and divide the capacity of the cell by the answer. A CR2032 coin cell holds about 180 milliamp-hours of usable charge. Everything in this step comes out of that division.
The surprise is which term dominates: it is not the reading, and it is certainly not the size of the reading. It is the keepalive ping, because the ping is the same wake-up as a publish and you have asked for one every sixty seconds.
What is a milliamp-hour?
A measure of how much electrical charge a battery holds, in a form built for this exact sum. A cell of 180 milliamp-hours can supply 1 milliamp for 180 hours, or 180 milliamps for one hour, or 0.03 milliamps for 6000 hours. Divide the capacity by the average current and you get the time.
Average is doing the work. A device is not drawing a steady current: it is asleep at 0.005 milliamps almost all the time and awake at 75 for a fraction of a second. Spread those bursts out over the whole period and you get an average you can divide with, which is what the lab does.
Why does a two-byte ping cost as much as a whole reading?
Because the bytes are not what you pay for. Two hundred bytes at the speed the air carries them takes about a quarter of a millisecond. Waking the radio up takes 22 milliseconds and waiting for a reply takes about 90, and both of those happen whether you are sending two bytes or two hundred.
This is worth internalising, because it inverts the instinct. Making messages smaller buys almost nothing. Making them less frequent buys everything. The lab has a slider for the payload, the content bytes of a message. Drag it from 20 to 500 and watch the answer stay the same to the nearest day.
Can a coin cell really supply 75 milliamps?
Not on its own. A CR2032 has a fair amount of internal resistance, and pulling tens of milliamps out of one drops its voltage far enough to reset the chip. That is why a device on a coin cell can reboot in a loop while a meter says the cell is nearly full. The 180 milliamp-hours in the model is already the honest figure rather than the number on the packet, for that reason.
The standard fix is a large capacitor across the cell. The cell trickles charge into it slowly, the capacitor supplies the burst, and the cell never sees the peak. The sums in this lab hold once that capacitor is there; without it, a design that looks fine on paper resets every time it tries to transmit.
There is a second way to live, and it looks obviously better until it is measured. Disconnect after every reading and sleep properly, paying a full connection each time instead of a keepalive.
Send a command down, and survive it arriving twice
Everything so far has gone one way. Now the phone wants to turn the heating up, which means a message travelling in the other direction. The machinery is the same machinery: the phone publishes to a topic and the device is subscribed to it. Nothing new is needed, which is the point of having built it this way.
What is new is that the message changes something. A reading that arrives twice puts a duplicate point on a graph. A command that arrives twice turns the heating up twice, and Step 6 established that at level 1 a duplicate is a certainty on a poor link.
The fix is not a better protocol; it is a better message. A command is idempotent when applying it twice leaves the same result as applying it once. Set the target to 21 is idempotent; turn it up by 1.5 is not, and no amount of care in the network makes it so.
Where else does this word turn up?
Everywhere something might be retried, which is everywhere. Pressing a lift button twice does not summon two lifts, because the button is idempotent. A cash machine that dispenses on a repeated request is not, which is why the retry logic in payments is written by people who are paid a lot.
The web has it built into the vocabulary: fetching a page can be repeated safely and submitting a form cannot, which is why a browser warns you before resending one. Same idea, same reason: somewhere underneath, something might send the message again.
What if the command really is a change rather than a value?
Then put a number on it and have the device remember. Every command carries an identifier, and the device keeps a short list of the ones it has already carried out. A command whose identifier is on the list is acknowledged and ignored. That converts any command into a safe one.
It is not free. The list has to survive a reboot, or a device that restarts mid-conversation loses its memory and does the thing again. And it has to be bounded, or it grows forever. Both are solvable, and both are more work than sending a target instead of a nudge, which is why the first thing to try is always the message design.
Should the device report what it did?
Yes, on a separate topic, and the report should be the new state rather than a confirmation.
Publishing target is now 21 with retain set means the phone's screen is correct
whenever it looks, the command loop is closed and a duplicate report is as harmless as a
duplicate command.
The pattern is worth naming because it is the one that scales. The phone publishes what it wants, the device publishes what is true, and both are values rather than instructions. Nobody has to keep count of anything, and every message in both directions can be repeated without consequence.
toggle, sent at level 1. On a poor link
the owner sometimes finds the door shut when they asked for it open. What is the smallest change
that ends this?Replace the firmware without bricking the device
Ten thousand devices are in kitchens and one of them has a bug. Sending somebody to each house is not a plan, so the program has to be replaceable over the network. That is an over-the-air update, and it is the highest-stakes thing a connected product ever does, because the failure mode is not a missing reading. It is a device that will not start.
The naive version writes the new program straight over the old one, a chunk at a time. It works almost always; when it does not, because the power went or the wifi dropped part way through, only one copy of the program exists. It is the first part of the new one followed by the tail of the old one. That is not a program. The device is bricked: as useful as a brick, and needing a wire and a screwdriver to revive.
The fix is to have two program slots and never write to the one you are running from. Write the new program into the other slot, check it, and only then change the single pointer that says which slot to start from. An interruption at any point leaves the running slot untouched. This is the A/B arrangement, and it is what every product that survives contact with customers does.
What is flash memory, and why does writing it take so long?
The memory that holds the program when the power is off. It differs from ordinary working memory in two ways that matter here. It keeps its contents without power, which is why the program is there when the device switches on. And it cannot be changed a byte at a time: a region is erased in a block, typically four kilobytes at once, before anything can be written into it.
The erase is the slow part, tens of milliseconds a block, and during it that block holds nothing at all. So there is a real window, repeated for every block, where the old contents have gone and the new ones have not arrived. That window is where an interrupted update does its damage.
How does the device know the new program is any good?
Two checks, at two different moments. Before switching over, a checksum: a number worked out from every byte of the image and compared with the number the server said it should be. That catches a truncated or corrupted download. It does not catch a program that downloaded perfectly and crashes on start.
For that there is a second check after switching over. The bootloader starts the new program with a flag saying this is a trial, and the new program has to mark itself as working within its first minute. If it does not, the next start goes back to the old slot. The lab lets you build an update that passes the first check and fails the second.
What stops somebody else sending an update?
A signature, the same idea as the certificate in Step 9. The image is signed with a key the manufacturer keeps, the device holds the matching public key, and the bootloader refuses to start anything whose signature does not check out. Without that, an update mechanism is a way for anybody who can reach the device to run their own code on it forever.
The awkward part is what happens to the signing key. It has to be available often enough to sign releases and protected well enough that it cannot be stolen, and if it is stolen, every device already built trusts it. Products that take this seriously keep the key in dedicated hardware and allow more than one key so that one can be retired.
The spare copy is not free. Two slots means the program has to fit into the flash twice over, and on a chip with 4 megabytes that decides how big your program is allowed to be.
Your own device, with nothing marked
Everything from the whole course is exposed here in one panel and nothing is checked. The quality of service, the loss on the radio hop, the keepalive, whether the certificate is verified, how often the device reports, and the layout of its flash. The readouts underneath are the same computations every earlier lab used.
One suggestion for using it, because a sandbox with no plan is only controls: pick a product first and then find settings that suit it. A freezer alarm has to notice a failure inside two minutes and can be mains powered. A soil sensor in a field has to last a season and nobody minds if a reading is a quarter of an hour late. Those two want opposite answers to nearly every control here.
Then try to build something indefensible: find the settings that give the longest battery life, and check whether the broker can still reach the device. Find the settings that detect a failure fastest and read what they cost. Both extremes are reachable and neither is a product.
What is in front of me?
The same simulator as every other lab. A device publishing readings over a link that drops packets at whatever rate you set. A broker applying the rules of whichever quality of service you chose, and a subscriber counting what arrived. The energy panel divides the capacity of the cell you picked by the average current your settings imply.
The reachability line compares your keepalive with the five minute table timeout from Step 4. The update panel runs the same two-slot arithmetic as Step 13 against the flash budget your program size implies.
Which settings would a real thermostat use?
Mains powered, so battery is not a constraint. Keepalive around 60 seconds, because it has to be reachable from a phone at any moment and the router's table must be kept open. Level 1 for readings and level 1 for commands, with the commands worded as targets so duplicates do not matter. Retain set on both the current temperature and the current target.
A battery-powered window sensor is the opposite in almost every respect. It sleeps, wakes only when the window moves, sends at level 1 and disconnects. It cannot be reached at all between events, and nobody needs to reach it, because there is nothing to command.
What is missing from this model?
Several things, and it is worth knowing which. The link loses packets independently, while real radio loses them in bursts when a microwave oven runs. The broker never falls over and never runs out of storage. It never rejects a connection because ten thousand devices reconnected at once after a power cut, which is a real and vicious failure. Time is exact and a real device's clock drifts.
The energy model assumes the radio comes up in a fixed 22 milliseconds. A real one takes longer when the signal is poor, so a device in a bad spot uses more power for the same work. And there is one device here. A field of five hundred sharing one access point is a different subject. It is the one that decides whether a product works in a block of flats.
MQTT checkpoint
- Name the ten stages between a sensor and a screen, and say what each one fails to do.
- Separate association, being given an address, and turning a name into an address, and say which of the three a status light has actually proved.
- Explain why a device behind a home router cannot be dialled, and why a broker is the answer rather than a workaround.
- Design a topic that a subscriber can usefully wildcard, and predict what a filter matches.
- Choose a quality of service on purpose, knowing that level 1 produces duplicates by design and that level 2 charges twice the packets to avoid them.
- Use retain so a new subscriber sees a value at once, and a last will so somebody hears when a device stops.
- Say why one key in every unit is one compromise away from the whole fleet, and price the two alternatives.
- Read a certificate failure and say which of the four checks failed and whether it is an attack or an ordinary mistake.
- Say what an eavesdropper still learns after encryption, and defeat a size-based attack with padding.
- Work out the battery life of a design from its keepalive, its reporting interval and the cell, and know which of those three actually matters.
- Word a command so that receiving it twice is harmless, and say when an identifier is needed instead.
- Explain why an interrupted update bricks a one-slot device and not a two-slot one, and what the spare slot costs in flash.
Courses used so far
- Embedded Systems. The chip underneath all of this: the pins, the sensor, the timers and the sleep modes that the battery arithmetic in Step 11 is spending.
- Computer Networks. What an address really is, how a packet is routed between networks, and the name system that Step 3 leaned on.
- Reliable Data Transfer. The acknowledgements, timers and retries behind quality of service, done properly, including how long a sender should wait before deciding a packet is lost.
- Real-Time Systems. What happens when the reading has a deadline and being right late is the same as being wrong.
Choose a protocol from the traffic, not its popularity
MQTT suits the thermometer in this course because many devices send short reports to a broker and several applications may want the same report. That does not make MQTT the answer to every connected product. Start with who opens the conversation, how often bytes move, whether the node sleeps, and what must happen after a lost packet.
HTTP is often simplest when a client asks a service for one resource. WebSocket keeps a two-way stream open for a busy browser. CoAP gives small constrained nodes a request-and-resource model over datagrams, single packets sent without opening a connection, with confirmable messages when an acknowledgement is needed. A gateway can translate between protocols, but then it owns buffering, identity and error translation.
How should an engineer compare them?
Measure a complete exchange, not just the payload. Include headers, handshakes, retransmissions, radio wake time, RAM used by the library and time spent connected. Then test the actual failures: lost replies, duplicate requests, a sleeping peer and a service restart. The protocol name alone does not give those numbers, and a protocol that looks free on the bench can double the radio's waking time in the field.
MQTT 5 is the current OASIS standard used here. CoAP is specified in IETF RFC 7252. Their standards define wire behaviour; a product still needs a policy for authentication, authorization and data retention.
An address is not permission
IPv6 gives a network enough addresses to avoid the address-sharing trick from Step 4. It does not mean that every device should accept a conversation from anywhere. A stateful firewall can allow replies to a connection the device opened while rejecting an unsolicited packet from outside.
Small radios often reach IP through a gateway or border router. A Thread border router forwards IPv6 packets between a low-power mesh, a network whose devices relay for each other, and the rest of the local network. An industrial gateway may also translate protocols or store readings during an outage. In either case, routing answers “where?”; certificates and access rules answer “who?” and “may do what?”
Is the gateway a trusted part?
Only if the design makes it one. End-to-end encryption can keep a forwarding gateway from reading application data. A translating gateway must usually read and rewrite messages, so compromise has more consequences. Record that boundary in the threat model, update the gateway, and decide what happens when it is unavailable. A gateway that stores readings during an outage is also where readings are lost when it fails, so its storage needs the same care as the device's own queue.
A reading needs a contract
The number 21.4 is incomplete. Is it Celsius or Fahrenheit? When was it observed? Which
sensor produced it? A message schema names fields, types, units and required values. It also sets a
rule for change, because old devices and new services will run together for years.
A safe addition is usually optional: a new sender adds battery_v, and an old reader ignores
that unknown field. Renaming temperature_c to temperature removes a required field
and breaks that reader. Keep the old field during a migration, version the contract, and test old
readers against new payloads before release.
What else belongs beside the schema?
Define numerical range, precision, missing-value meaning, clock basis and a stable device identity. Give each event a sequence number if duplicates or gaps matter. Store example messages as contract tests. JSON is readable but not automatically well defined; a binary format is compact but not automatically compatible. The contract supplies the discipline. A field that changes meaning is worse than a field that disappears, because every old reader keeps accepting the record and quietly computes the wrong thing with it.
temperature_c. What is the safest first v2 change?The network will go away
A field device must decide what to do before its connection fails. Store-and-forward keeps readings in a bounded flash queue and uploads them when the link returns. The record size, report rate and reserved flash determine the longest outage it can cover. When the queue fills, the product needs an explicit loss rule: drop oldest, drop newest, or replace detail with a summary.
Commands need reconciliation too. A useful device twin, the service's own record of the device, separates desired state from reported state. The service may desire 19 °C while the offline thermostat still reports 21 °C. On reconnect, compare versions and timestamps, reject stale commands, and show the disagreement instead of pretending the command already happened.
Will repeated flash writes wear it out?
Yes, so use a log or ring buffer that spreads writes across pages. Batch metadata updates and test recovery after power loss during both append and erase. A queue that was never tested against a power cut in mid-write tends to fail on the first winter evening the lights flicker, with the oldest readings as the casualties. The crash-safe storage methods in Embedded Systems apply directly.
Clocks drift, jump and disagree
A crystal clock rated at 20 parts per million (ppm) can gain or lose about 1.7 seconds per day. Network time corrects the wall clock, but the correction and packet delay have uncertainty. Store that uncertainty when event order matters. Do not invent millisecond precision because the timestamp has three decimal places.
Use a monotonic clock for durations and timeouts because it only moves forward. Use wall time for a calendar date, and expect it to jump after synchronization. A per-device sequence number proves the order of that device's reports even when its wall clock is wrong. Ordering events from different devices needs synchronized clocks, or a system that reasons about partial order.
How do two devices agree closely enough?
A time service estimates clock offset using timestamped exchanges. Variable network delay limits that estimate, so synchronization has an error bound rather than perfect truth. Systems that need tighter timing may add hardware timestamping or a local precision-time network. Always measure the bound under load and after a device has been disconnected. A device that has just woken from a long sleep is the worst case, because its clock has drifted the whole time and its first messages carry the stalest timestamps.
A valid certificate does not grant every action
Authentication proves which device holds a key. Authorization limits that identity afterward. Device A may publish only under devices/A/telemetry, its own stream of readings, and
subscribe only to devices/A/config. It must not read B's commands or publish through a wildcard. Broker access
rules should express those limits directly.
A stolen but valid key is still dangerous, so bound message rate, payload size, retained storage and connection attempts. Revoke the affected identity without replacing every fleet key. Log denied actions and unusual reconnect bursts, but avoid putting secrets or private payloads in the log.
Build a small threat model
List assets, entry points, trust boundaries and plausible attackers. Then name a control and a test for each important threat. Unique keys limit fleet compromise, and an access control list (ACL) blocks cross-device topics. Rate limits bound broker work, signed updates block modified firmware, and rollback and recovery handle a bad but correctly signed release. The rate limit deserves the same attention as the topic rules, because a compromised device that may only publish its own telemetry can still bury the broker in it.
Operate ten thousand devices without guessing
A fleet needs evidence at three levels. Per-device signals include boot reason, firmware version, last contact, queue depth and battery estimate. Fleet measures include connection success, command latency, update success and the fraction currently healthy. A service-level objective turns one of those into a promise, such as “99% of alarm reports reach storage within 30 seconds each week.”
Change a fleet in cohorts, one chosen group at a time. Start with lab devices, then staff devices, then a small canary, a first group that meets trouble before the rest, chosen across hardware revisions and network types. Compare its failure, battery and reconnect measures with a control group. Stop automatically when a release gate fails. A percentage alone is not enough if the first 1% contains only the newest hardware.
What should an alert say?
State the affected cohort, time window, measured symptom and runbook. “Connection success fell from 99.8% to 93.1% for hardware B after firmware 7.2” is actionable. “IoT errors increased” is not. Keep metric labels bounded; a separate label for every device can overload the monitoring system. The runbook line matters because the person woken at three in the morning is rarely the person who wrote the release, and the alert is their only briefing.
Matter and Thread solve different layers
Matter defines a shared application model for compatible smart-home devices: how they are securely commissioned, represented and commanded over IP. Thread is a low-power IPv6 mesh network that can carry those packets. Matter can also use other IP transports, and Thread can carry applications that are not Matter. Keeping the layers separate makes faults easier to locate.
As of 2026, the current maintenance release is Matter 1.5.1 and current Thread resources list 1.4.1. Version numbers do not guarantee that two products implement the same device type or optional feature. Check certification, supported clusters (Matter's groups of related commands), border-router availability and behaviour when the Internet is down. Local IP operation and vendor cloud history are separate capabilities.
Where does commissioning fit?
Commissioning moves a new device from factory identity into a particular home or fabric, gives it operational credentials and assigns access. Test first setup, adding a second administrator, removing an administrator, factory reset and transfer to a new owner. A successful radio join is only one part of that lifecycle. The ownership transfer is the test most products fail first, because the factory reset has to remove every credential the old household ever granted.
Read the current specifications and release notes at the Connectivity Standards Alliance and Thread Group.
Plan the whole life of collected data
A sensor can reveal more than its field name suggests. Temperature changes may show when a room is occupied; power readings can reveal appliance use. Before collection, write the purpose and minimum fields. Then define who may see them, where they travel, how long exact records remain, and how an owner can export or delete them.
Minimization is an engineering control. Compute a daily total on the device when the service needs a trend rather than every minute. Remove precise location when region is enough. Use short retention for raw data and keep a coarser aggregate if the product needs long-term comparison. Test deletion across queues, replicas and backups instead of deleting one database row and declaring success.
Can anonymous data still identify a home?
Removing a name may not be enough. A stable device identifier, precise location or distinctive activity pattern can link records back to a person or place. Test likely combinations, rotate identifiers where continuity is unnecessary, and keep the re- identification key separate when a product needs one for a stated purpose. A backup is the copy most deletion schedules forget, and a person who asked to be erased is entitled to be erased from the copies as well.
A learned model stays behind ordinary safety rules
A small model can detect an unusual vibration on the device, reducing radio traffic and response time. A cloud model can compare a fleet and predict maintenance. Decide between them from latency, energy, privacy, update size and what happens offline. Measure the model on data from the actual sensors, mounting positions and operating conditions.
Model output is uncertain. Convert it into a typed proposal, then pass it through the same identity, range, freshness, rate and state checks as any other command. A model may suggest a temperature within a safe band. It must not bypass the command path to unlock a door or disable an alarm. Log the model version, input summary, decision and fallback so an incident can be reconstructed.
What changes when an AI agent uses tools?
Treat the agent as an untrusted client. Give it narrow tools with typed arguments and least-privilege credentials. Require confirmation for high-consequence actions, make repeated calls idempotent, cap rate and cost, and keep a deterministic safe state when the model is unavailable. The fallback deserves as much testing as the model, because the day the model is unavailable is usually the day something else is already going wrong. Text from a sensor, document or web page is data, not an instruction allowed to change those rules.
TinyML covers fitting and measuring small models. The release gate here adds system evidence: representative data, false-alarm cost, memory and energy budget, signed model update, canary monitoring, rollback and a non-ML fallback.
What you can do now
- Trace a reading and a command through radio, IP, broker, service and app, and isolate the failed layer.
- Choose MQTT, HTTP, CoAP or WebSocket from measured traffic and device constraints.
- Design versioned records with units, timestamps, sequence numbers and compatibility tests.
- Size offline storage, reconcile desired and reported state, and bound clock uncertainty.
- Separate identity from permission, then limit topic, message rate, payload size and update authority.
- Define fleet measures, representative canaries, stop conditions, rollback and recovery evidence.
- Separate Matter's application model from Thread's IPv6 mesh, and test commissioning through ownership transfer.
- Turn privacy and learned-model safety into concrete data, command and release requirements.
Continue the engineering path
- Real-Time Systems adds deadlines, scheduling, bounded blocking and overload behaviour.
- Computer Networks develops addressing, routing, queues, firewalls and packet evidence.
- Reliable Data Transfer derives acknowledgement, timeout and congestion behaviour.
- TinyML builds and evaluates learned models that fit on constrained devices.