I think I grew more with this assignment than I have in any other 7-week class’ assignment.
By that I mean it was a STRUGGLE.
The premise was simple:
Make home environment controller, a web client device with physical controls. The bare minimum version of this will be a thermostat controller. The server will be provided for you. It should contain a temperature sensor that is reporting to the server. It can contain whatever other environmental sensors you wish (light levels, humidity, noise, etc). It should contain at least one physical input control besides the temperature sensor, to set a temperature setpoint. It can contain sensors and output controls for other lighting, sound, etc, devices on the floor at ITP if you wish, but the server will not support those devices, nor will it control them. It should send data to the server on an hourly basis, minimum. The data spec is TBA, but it will be sent via HTTP/HTTPS request. It should be online by week 5 at class time (9:00 AM EST) and remain online until the end of class time on week 6 (11:30 AM EST). It should connect via the itpsandbox network.
But oh, how devilish it turned out to be…
The First Major Roadblock
I had never done anything on the ITP sandbox network, and incorrectly assumed it was some sort of magic portal that I had to be connected to to do any homework related to it. Since I had many weekend deadlines, I didn’t get connected to it until Monday and hadn’t started any of the physical interface elements either (first mistakes). I had already set up my new Raspberry Pi Zero with the ITP image, but when I finally got my components on the breadboard and everything all wired up, something went wrong. I tried running the demo examples on NodeSensorExamples and some of my own, and I kept getting a combination of errors:
throw err; EACCES: permission denied
for which I attempted to chmod 777 any directories that it referenced or run sudo with everything
TypeError: rotaryEncoder is not a function
Had no idea what this could be, since no one else was getting this issue, and I was using the exact same files and packages as the rest of the class it seemed.
I tried reinstalling the packages over and over
and others related to file paths of node/npm/nvm
I tried completely uninstalling node, npm, nvm, reinstalling under different locations, with different users, and eventually it got so convoluted and I felt like I had tangled up my node file paths in a giant ball of electric yarn, so I decided to just start over and reflash the default image onto the pi. Which of course took an hour to get back to where I was. Then I had the exact same issues. I even tried using Nicolas’ pi to see if I would get the same error. This whole error process took about 5 hours, I’m afraid to say.
After working in the shop until 3am with a handful of other classmates who were very supportive but couldn’t figure out what was wrong either, I decided to cut my losses and just show up to class the next morning very humbled.
I got a lot of great insights hearing how it went for the other students. During class Mark told me there was a gpio user group I might need to add myself to, but in the end that wasn’t it. After class I decided to just run the code the way I knew it needed to be run and it worked on the first try, no errors. So I spent the next couple hours getting everything else to work and I was done…
I learned at office hours later that day that the magic answer to my problems appeared to be the fact that I hadn’t soldered the pins onto the pi the night before, I had just used loose wires and a breadboard. Apparently if any of the pins threw an error, it could have gone down the chain of command and appeared to me on the console as though it were a package error.
Major lesson that I learned: Even if the error you see is a software error, you still have to check the entire chain of command, because it might be a hardware issue manifesting as a software one.
The other major breakthrough that came as a result of this was that I finally understood what it meant for Javascript to be all about asynchronous callbacks. Having mainly only ever intereacted with code in the case of draw/loops like in arduino and p5.js, it took a while for me to wrap my head around how to write the node code. I eventually made sure there was only one function being called, so that everything was nested inside of that and I would only send data to the server once I actually had accurate data to send.
Installation
Since I was mainly focused on getting the server messages up and running every hour, I decided to focus on my physical interface later and put my thermostat in a place that I knew it would be relatively safe (up high). I taped the plug and wrapped the cord around so that it wouldn’t come unplugged if someone messed with the extension cord, and crossed my fingers.
First Reset and Later Issues
The first couple of days went swimmingly; I had good, JSON-formatted data being sent every hour (thanks to the super useful crontab tutorial during class). Then on Friday, I was helping Nicolas get crontab set up on his pi when I tried to ssh in to mine and got some weird errors:
I had a sneaking suspicion that my code wasn’t actually ending the node process after sending the data, which meant that I had several dozen programs running concurrently. To test this, I reset the pi and was able to ssh back in without a problem. I then commented out the rotary encoder functions that I felt might be accidentally triggering on all those programs simultaneously, and then ran the code a couple times to see if ps and top would show “node” as any of the processes. It appeared not to be anywhere, which contrasted with Nicolas’ code that was running 24/7 and using setInterval() to send data every hour (and node showed up under his “top”).
So I thought I had solved that issue, however when I checked back on Monday and tried to ssh in, I was unable to (got the same error messages). So not sure what the issue was, and since Monday is a snow day I’m unable to reset until Tues morning. It appears that it was sending reliably over the weekend until early afternoon on Monday though, so at least I’m not missing too much data.
The only thing left to do is document my physical interface and clean up my server data.