Raspberry Pi PDU

It’s that time of the year again!!!

Let’s get the bureaucracy out of the way first:

I, Mircea Anton, will participate in the next Devember. My Devember project will be “PiPDU”. I promise I will program for my Devember for at least an hour, every day of the next December. I will also write a daily weekly public devlog and will make the produced code publicly available on the internet. No matter what, I will keep my promise.

If the name is not suggestive enough, piPDU is a smart PDU, powered by Raspberry Pi and Arduino. I intend to build it and mount it in my Home Lab rack.

This project is basically going to dust off my Arduino/Raspberry skills which I haven’t really been using lately and hopefully get a usable product by the end of it!

Some rough requirements for this project are

  • the pdu itself to function as a plain old power strip if anything goes wrong
  • the pdu should have an API server to control each socket individually
  • the pdu should expose metrics in a prometheus endpoint for each socket
  • the controller should have 16 buttons, one to control each socket
  • the controller should have 16 leds to indicate the on/off status of the sockets
  • the controller should have an LCD display to show stats for the sockets

I want the controller and the PDU itself to be separate entities in a client-server relationship so that i can eventually expand this and maybe make a discord bot or mobile app or whatever else to control the pdu as well.

I did not know initially if devember was going to happen or not, so i started the blog post series on my own website as well. I think I will run these 2 in parallel.
Link to my website here

2 Likes

Git repo: GitHub - mirceanton/piPDU: A Raspberry Pi powered PDU for the Homelab.

Week 1 overview posted on my blog: Devember 2022: Planning is Essential, but Plans are Useless · Mircea Anton

Short summary here:

  1. Monday
  • Cleaned up the frontplate after my dad drilled the holes for the buttons
  • Mounted the buttons
  • Started soldering the wires for the buttons
  1. Tuesday
  • Finished soldering the wires for the LEDs and the LCD
  1. Wednesday
  • Started testing the circuit, apparently they shipped my order wrong, some LEDs were 12v, some were 5v.
  • Lay down, try not to cry, cry a lot
  • Troubleshoot → Get mad → Give up for the day
  1. Thursday
  • Change gears to work on the server
  • Wired the Relay board to the arduino
  • Used a gutted out pc psu to power everuthing up
  • Wrote the code for the arduino to turn on/off relays
  • Wrote the code for the arduino to “simulate” reading from the sensors as i did not connect them yet
  1. Friday
  • Started working on the python code for the pi, set up an api server
  • Made a /pong endpoint to test connectivity
  • Made the /api/v1/sockets/<number> endpoint to toggle relay states
  • Established serial communication via USB between arduino and raspberry
  1. Saturday
  • Worked with dad to draw a circuit diagram for the controller, with 12v LEDs
  • Picked all the parts, placed the order
  1. Sunday
  • Worked some more on the server code, did some refactoring into dedicated files
  • implemented config file parsing
  • implemented GET endpoint to check relay status
  • implemented prometheus metrics exporter for the data from the sensors
1 Like

Week 2 overview posted on my blog: Devember 2022: One step forward, two steps... to the left · Mircea Anton

Monday:

  • today I did not get around to work on Devember, sadly. I had my CKA exam and took the day off to decompress a bit

Tuesday:

  • worked on modding the gutted out PC PSU by adding DC jacks to it
  • removed all of the old buttons from the controller front plate
  • mounted the new buttons on the controller frontplate
  • soldered individual wires to the buttons and LEDs

Wednesday:

  • soldered components to a protoboard, trying to make a custom PCB for the controller

Thursday:

  • worked on the custom pcb a bit more, got frustrated, gave up
  • designed a custom PCB in KiCAD for the controller
  • wrote some code to interact with the LCD

Friday:

  • no work on Devember today either. I had to study for the CKAD exam I have on monday as I was behind

Saturday:

  • set up the controller circuit on a breadboard with the gutted out psu and a pi 4 for development

Sunday:

  • wrote quite a bit of code for the controller
    • created the config class singleton
    • create an LCD singleton to interact with the LCD display
    • implemented some basic scraping of the prometheus endpoint served by the pipdu server

Week 3 up on my blog: Devember 2022: · Mircea Anton

  1. Monday
  • i had my CKAD exam so i did not get around to work today. Just like last week, i decided to take the rest of the day off to decompress
  1. Tuesday
  • today I refactored some of the code for the controller into “arduino-style” functions, basically implementing a setup function and then a loop function that, as you might have guessed, loops indefinitely
  • I set up some functions to initialize the LEDs and the boilerplate for led updates
  • I set up the metrics singleton class to collect and cache metrics from the prometheus endpoint exposed by the server
  • Implemented singleton class to abstract away the button matrix, handling the long and short presses
  1. Wednesday
  • today I was very sick, to the point that i couldn’t really get out of bed to do anything at all
  1. Thursday
  • today i managed to get some coding done.
  • I worked on the controller code and I implemented the actual api calls for the long and short button presses
  • I implemented the LCD states to show both the overall power consumption during idle as well as per-socket power consumption when a button has been pressed
  • I implemented the led_array update function to turn leds on/off based on socket status
  1. Friday
  • today i was unable to get any work done on the pipdu project as life managed to get in the way
  1. Saturday
  • today i managed to get a tiny bit of work done.
  • i desoldered the screw terminals from my previous attempt of a protoboard in order to reuse them for the custom pcb i am working on
  • i tried to do some more troubleshooting by fixing errors reported by kicad on my pcb
  1. Sunday
  • i was pretty behind on my CKS study for my exam tomorrow, so I decided to dedicate this day to studying only
1 Like

Finally, week 4 devlog is up on my blog: Week 4 - Ho-Ho-Holidays are here · Mircea Anton

This week has been quite chill.

  1. Monday: I had my CKS so I did not work on Devember
  2. Tuesday: Fixed all the errors on the PCB in KiCAD and added mounting holes
  3. Wednesday: Did some more planning to outline some of the main features I have left to implement
  4. Thursday: Busy with some assignments for my masters degree, no Devember work
  5. Friday: A lot of coding done on the server component:
  • added a sockets.yaml configuration file to be able to name the sockets and add a custom initial state (on/off)
  • added dedicated /on, /off endpoints instead of a basic toggle
  • added the /info endpoint
  • refactored the API server into dedicated files and a proper directory structure via Flask Blueprints
  1. Saturday::
  • refactored the entire codebase :smiley:
  • added docstrings and tidied up the code
  • Implemented the Led and LedArray utility classes to handle the logic for using the LEDs as status indicators for the sockets
  1. Sunday:
  • Merry Christmas!
1 Like

Very cool.

Can’t immediately tell from the blog or the repo, what hardware are you using for the current/power measurements and are you using any external pin controller/pin muxer. (looked from my phone while on the go and couldn’t find a pdf or something I could open easily).

I was imagining how something like this might use esphome on esp32 with a bunch of mcp23017 daisy chained on i2c, or maybe even a pca9685 if you want to pwm the LEDs on the buttons.

How does current/power sensing work?

Hello, @risk ! Thanks for your interest in the project!

Yeah, I did not spend too much effort on documentation yet. I hope to do that in the coming weeks this month, as I flush things out more.

So the way things are set up right now is that I have 16 ACS 715 Hall Current Sensors wired in alongside the 16 relay board in order to measure the current.

image

These sensors, alongside the relays themselves are then controlled by an Arduino Mega. The Arduino then in turn communicates via i2c with the Pi zero to complete the circuit. Basically, the Arduino interacts with the hardware itself and the Raspberry simply hosts the API server and communicates with the Arduino.

Now, it would have probably been a better design to get some I2C GPIO expanders and I2C ADCs and use those instead of the Arduino Mega, but I had that lying around so I tried to use as much of the parts I already had as I could.

For the buttons and LEDs, I am using a Pi zero again. It has just enough pins so that I can individually address the LEDs and use the buttons as an 8x2 matrix. The LCD in the controller is communicating over an I2C bus.

Week 5 of my devember project (technically week 6 but i took a week off for the holidays) is live now!

Way more in-depth blog post: New Year, Same Devember · Mircea Anton


TL;DR:

Mon

  • (tried to) print and etch the PCB v1 for the controller but it turned out bad
  • updated the controller PCB to version v1.1 to use 2mm tracks and larger viases to maybe have better results when etching

Tue

  • Created a circuit schematic for the server PCB to get an idea of the components and connections required;
  • Considered getting an I2C ADC for the Pi but I soon dropped the idea, mainly due to cost considerations, since I already had the Arduino Mega and even so, getting enough analog channels would be more expensive via ADC boards than by using an Arduino as an ADC

Wed

  • worked with dad to create a PCB for the pipdu server to connect all the current sensors by manually drawing with a paint marker
  • brainstormed and came with a layout for the components inside the server case
  • updated the PCB for the controller to v2 to use GPIO expanders for a much much simpler design

Thu

  • etched the server PCB and drilled some of the holes
  • cut the hole for the power socket in the controller case

Fri

N/A, had to take care of some university assignments

Sat

  • printed the controller PCB v2
  • etched the controller PCB v2 → turned out great, actually!
  • drilled the hole for the rj45 module in the back panel of the controller case
  • drilled the server PCB pin-holes

Sun

  • worked with dad on the server case:
    • cut the new front panel from a 3mm sheet of metal
    • cut the case into pieces
    • drilled the holes for the power plugs and mounting screws

Devlog for week 6 is also up on my blog: Oops, I did it again · Mircea Anton

A bit late for this update, as well, but I am slowly catching back up.
Spoiler alert: week 7 has more interesting things coming up!


TL;DR:

This week I was very busy with uni work and other projects so only 2 tasks got done:

  • decided on the design/layout for cutting open and re-building the 5U box for the PDU => implemented said design
  • some initial wiring on the power sockets in the PDU

Not a whole lot but hey… progress is progress…

PS.: week 7 update coming soon, i am in the works writing it

Devlog for week 7 up on the blog: Back on track! · Mircea Anton

Slowly starting to get back on track, but it is getting awfully close to the deadline and I am not done yet :worried:


TL;DR:

  • FINALLY FINISHED THE BUILD FOR THE CONTROLLER:
    • soldered all the components to the controller PCB
    • mounted everything inside the case
    • did some cable management
    • updated the code to handle the I2C expanders
  • designed and built the mounting system for the components inside the server case

And here goes the last week of devember 2022!

Detailed post with updates for this week, as always, up on my blog: We almost made it! · Mircea Anton


TL;DR:

Monday

  • did some troubleshooting on the controller PCB as there were some imperfect connections
  • closed up the controller case and started testing and adjusting the code

Tuesday

  • finished fixing all of the imperfect connections
  • replaced one of the buttons that was broken, apparently
  • fixed the code to handle the buttons and LEDs via the I2C expanders

Wednesday

  • soldered the components to the server PCB

Friday

  • assembled the server circuitry and did the low-voltage wiring

Sunday

  • added a power switch to the server case
  • added the 5V PSU and wired mains power to it
  • mounted the contraption to the server case
  • mounted a bunch of terminal strips and wired them to the relays NC and the sensors (power → sensor → relay → socket)
  • designed a mounting system for the pi as well, on top of the arduino
  • added a terminal block to split up the 5V and GND from the PSU to power multiple components
  • ran the 5V power to the server PCB, relay board, arduino and Pi
  • wired the I2C from the pi to the arduino

As a final update, I unfortunately did not manage to accomplish all I set out to on time, as I still have to do the final assembly for the server case. That being said, I did make a lot of progress on this project and I am happy with it nonetheless.

I would like to thank the L1T community and team for setting up this challenge and would like to take this time to share my achievements for my Devember 2022:

  • Got my CKA certification in the 1st week of December
  • Got the CKAD certifications in the 2nd week of December
  • Got the CKS certifications in the 3rd week of December
  • Completed the PiPDU Controller (HW + SW)
  • Got ~85% done with the PiPDU Server (HW and SW)
  • Accomplished my goal of posting more on my personal blog and honestly I also improved it a lot. I started with no blog posts and I am currently at like 13. I improved the look and feel of my site since this challenge has started and I got it to a point I am quite happy with it.

To be fully honest, I could have probably finished this if i was more careful and didn’t spread myself too thin by setting too many goals, but I am always saying that it is better to aim for the stars and miss, as you will have gotten much further compared to aiming low and making it!

Overall, I am calling this Devember challenge a win! I hope you’ll tag along as I continue to work on this PiPDU project as I already have bigger plans for the v2, even if v1 is not really done yet :sweat_smile: Expect another post on my blog sometime in the next couple weeks about that!

To wrap things up, I want to outline what has been accomplished and what is left to do for this devember challenge, based on the initial plan:

Done:

  • Controller HW:

    • Designed custom PCB
    • Printed custom PCB at home
    • Modded a 2U case to fit all of the components
    • Assembled and wired all of the components into the case
  • Controller SW:

    • basic python client for the PiPDU server
    • LCD to display stats about the PDU (total power consumption, total Amps)
    • single button press to toggle the LCD from showing general pdu info to specific socket info
    • long button press to toggle the state of a relay (as well as the configured hooks)
    • LEDs to indicate the status of each relay
  • Server HW:

    • built a custom PCB for the current sensors
    • HEAVILY modded a 5U case that was meant for batteries in order to fit the components inside it. And I mean HEAVILY. We literally cut every panel off the case, replaced the front panel, redesigned the case closing system and cut a crap-ton of holes into it. I think it would have been easier to just make a new one but ohwell
    • Assembled and wired the components into the case (sans wiring the sockets into the relays yet)
  • Server SW:

    • set up a basic Flask API to handle the state of the relays by sending requests to the /api/v1/socket/<id>/{on/off} as well as socket status on /api/v1/socket/<id>/status
    • set up a Prometheus monitoring endpoint to expose the values collected by the sensors for each relay to easily integrate into Grafana
    • added functionality to trigger pre/post power on/off hooks. For example, sending a shutdown command to a Pi before turning off the socket or sending a notification to a discord channel after a socket has been turned on
    • YAML config for setting up names for the sockets and configuring the hooks

To Do:

  • Controller HW: N/A
  • Controller SW: some final testing once the server is also up and running
  • Server HW:
    • wire all of the power sockets into the terminal strips
    • final assembly
  • Server SW:
    • final testing once everything is assembled
    • “calibration” for the current sensors
  • Documentation: all of it, LOL

Frankly, depending on how long they take to rate the projects and pick a winner, I think I might be able to finish this, as there is very little left to do! :laughing:

1 Like