Monday, January 11, 2021

Web Server for the Garden Logger

I'd like to be able to see how the Garden Logger's doing. Is it still running? What values is it reading now?

I'd like to stick a Raspberry Pi in the bento box with the Arduino, run a web server on the Pi, and have have the Pi serve up web pages showing the logger's status;  and maybe even control which channels are scanned at what speed.

I was going to develop it on a Pi Zero W, using VSCode via SSH. No dice -  VSCode didn't support the Pi Zero's Processor. Same thing with RasPi 2. It does work with a RasPi 3, but I didn't have any to spare, so I wrote the code on my Linux Mint workstation.

I thought it would be great if logger could send a nice JSON package across to the Pi, but it was better to keep things simple on the Arduino and to put those smarts into the web server. So for now, every time the Arduino writes data to the SD card, it also sends a string of data channel names followed by a string of the data from those channels.

The first thing to do is to install the serial and web server libraries. For some reason, I needed to "pip uninstall" the serial library, then "pip install" the pyserial library. I "pip install"ed the Flask library for the web server.

After connecting the Arduino to a USB port, the sever app needs to find the port that the Arduino's attached to. This is the code snippet I used. It's hard coded to use a specific "Seeeduino", so the process is that the list of hardware IDs needs to be printed using the first two lines in the code snippet, then after the right ID is determined, it gets hardcoded into the server app.

for port in list(list_ports.comports()):
print(port.hwid)
if port.hwid.startswith('USB VID:PID=0403:6001'): # change this if using something other than Seeeduino.
print('Arduino on: ' + port.device)
arduinoPort = port.device

I used this tutorial as a starting point for learning Flask

After I got the example working I needed to start a thread running that would wait asynchronously for data from the Arduino, then parse it, and save it into a global variable for the web server.

print('starting data acq')
dataAcq = threading.Thread(target=monLogger)
dataAcq.start()

The next step was to start the web server. Here's where I hit a problem. When I started it in the VSCode IDE, it was bringing up a second instance of the logger monitor thread. I was really stumped until I came across a web posting that said debug must be disabled on the server. I changed that, and the problem was fixed!

print("starting server")
app.run(debug=False, host='0.0.0.0') # debug=False should prevent restart and doubling dataAcq

Now the final step was to get the data into a Jinja2 template for display. With a few more lines of code, I can now monitor the Garden Logger from anywhere on my network!




No comments:

Post a Comment