University project · Team of 2
Smart Hotel - IoT Platform
Sensors installed in rooms sending readings to a web application that displays them on a dashboard that updates by itself.
Context
The first project of my degree. I was responsible for the web application and my teammate for the Arduino side — but we both ended up learning both. Built with what we knew at the time: PHP, HTML, CSS and JavaScript, with no framework and no database.
The problem
Hardware writing on one side, a browser reading on the other, and nothing in between that we knew how to use. We had not covered databases yet. The sensor readings had to go somewhere, and that somewhere turned out to be a text file — not as an architectural choice, but because it was the tool we had.
My part
The entire web application: the PHP API that receives the readings, the layer that stores and reads them from files, the monitoring dashboard and the authentication. My teammate took the Arduino and the sensors. In practice we both ended up understanding both sides, because nearly every problem appeared on the boundary between them.
Technical decisions
Storing in files, and owning it
With no database, every reading goes to a file. A database solves concurrent writes, consistency and lookup for you; with files, those problems become yours. It was not an engineering choice — it was what we knew how to do. I would rather say it that way than call it architecture, because the difference between the two is exactly what I did not understand at the time.
Updating the dashboard without reloading the page
The dashboard requests new data periodically and updates only what changed. On a monitoring screen left open for hours, reloading the whole page wastes bandwidth and loses visual context — whoever is watching loses their place.
Treating the hardware as an untrusted source
The data came from a device on the network, and what arrives over a network can arrive malformed, deliberately or by accident. We validated file paths against directory traversal and sanitised everything written or displayed. A sensor is not an attacker, but the code has no way of telling the difference.
What went wrong
There were plenty of problems, and most of them were not on either side — they were in the seam between them.
Readings that arrived malformed. Files left in an odd state when the sensor wrote at the same moment the dashboard read. Data that disappeared leaving no trace of what had happened. And since we had no error logging, every problem started with a question we could not answer: is this the Arduino, the network, or the PHP?
We spent more time working out which side the problem was on than fixing it. In the end we got it organised and delivered it working.
The lesson stuck: in a system built by two people in two halves, the part that fails is almost never one of the halves. It is the seam — and nobody owns it unless somebody decides to.
Outcome
Delivered and working, with the sensors feeding the dashboard in real time.
What I'd do differently
Two things. I would use a database: I now know that what we were solving by hand — concurrent writes, consistency, not losing readings — is precisely the problem a database exists to solve, and solving it badly is far more work than using one.
And I would log errors from day one. It would not have prevented the problems, but it would have turned hours of guessing into minutes of reading.