Smartifying the Electric Generator

Pavel Zagalsky
6 min readDec 26, 2017

Hi! My name is Pavel. I work at Red Hat as Automation developer. I live in a small village in Galilee, Israel called Clil.

Clil Village

Clil is beautiful, but for its inhabitants it comes with a set of challenges. One of those challenges is the basic fact that the village is off the Israeli electricity grid. Luckily, Israel is blessed with many sunny days so Solar energy is a natural solution to this problem. However, on some days, the sun doesn’t shine or the usage is too high. That’s when our generator becomes handy and fills the gaps in our electricity needs. My extended family’s business is tourism, we have a few wooden cabins and not long ago also had a restaurant. Consequently, the generator must work properly and is a pretty massive beast. The control units of the generator, the solar panels and the batteries occupy this whole room outside the house:

In order to turn on and off the Generator I had to go to that room outside my house and trigger it manually with a dedicated button that closes a 5v loop with the Generator outside

My goal was simple. I wanted to put a stop to those endless visits to the control room. I wanted to be able to control the generator from everywhere, anytime. I wanted to be free!

I had 2 possible hardware solutions to go with here. Arduino and Raspberry Pi, both are valid solutions. Arduino being the cheaper one but (in my opinion) a bit less user friendly due to its using a lower level language (C) that I am not really familiar with. I tried to work a bit with Arduino at first but didn’t really enjoy the process so I switched to Raspberry Pi and went with it until the end.

So, what hardware I used?

  • Raspberry Pi 1
  • Basic 4 channel relay module
  • 5 jumper wires
  • WLAN Network module. Anything should work but probably chose something to suit your operating range
  • SD Card with DietPi

Wiring up

Connecting all the pieces was the easy part. What I actually needed is a relay that closes a loop upon a command. Closing that loop triggers generator’s command to go up. When the loop opens, the Generator goes down.

Raspberry Pi has a bar with several input and output connections and for my needs I needed only 3. The DC 5v and the GND to power the relay and one of the output pins to command. (I chose pin 3 for whatever reason). I chose the 4th input on the 4 channel relay I had, so naturally the 4th output is the one that was sent to the Generator.

Here’s the schematic I skillfully made with Google Docs’ tools:

This is how it looks inside the box:

Software architecture

While planning, I decided that the best way to trigger the generator would be by sending mail messages to a specifically defined email address. I tried to implement a standard Rest API service that would receive triggers to defined endpoints but implementation failed because the Cellular Modem/Router I use to connect to the Internet doesn’t actually allow port forwarding from Internet to internal IPs. I could, of course, hack it and install DD WRT or OpenWRT on it, but I honestly preferred not to.

The language I selected is Python, simply because Python rocks and it’s a great language to implement ideas quickly and reliably. Since I don’t really need high performance or Real Time, Python was absolutely good enough.

So how the logic works? The main script starts to run and polls the email server for new mail messages. If the message includes any of the following words, the logic would respond accordingly:

On, On(time in seconds, for example, On90), Off to start or shut down the generator
Status → To check generator’s current status. (On or Off)
Usage → To check how much generator has been working this month.
Logs → To receive generator’s logs

Generator’s trigger is being done using the GPIO library

All generator’s operations were documented on MongoDB NOSQL database. I contemplated between hosting it locally or remotely and favored hosting remotely because it’s much more reliable and it was extremely important for me to know how much time has the generator been working. At the moment I am hosting the schemas on mlab.com but I am considering switching to GCP or Amazon.

The mail service I chose was Gmail because it allows the non aggressive polling I run on it.

Selected Raspberry Pi distribution

I was looking for a headless and slim distribution and found DietPi which has a minimal footprint and has a very nice CLI driven interface. While I had my share of problems with it, I found it suitable for my use case but I guess other distros would work well too.

The code

The full code is on GitHub and I hope it’s mostly self explanatory but here are some important parts:

Generator’s triggering:
According to the cmd, the Generator would go up or down.
uname function tells the script on which platform the code is running. If it’s indeed DietPi on Raspberry Pi, the generator would be triggered.

def generator_cmd(cmd):
""""Sending the generator command"""
if uname()[1] == 'DietPi':
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(pin, GPIO.OUT)
GPIO.output(pin, GPIO.HIGH)
if cmd == 'on':
GPIO.output(pin, False)
elif cmd == 'off':
GPIO.output(pin, True)
else:
logging_handler('test mode. generator is not going up')

This command polls the mail and extracts the subject that carries the command and the sender that is needed for the white list checking

def poll_mail():
"""Returns a key command that is being received from the mail and the sender"""
msrvr = imaplib.IMAP4_SSL(imap_addr, imap_port)
msrvr.login(receiver_email, receiver_password)
stat, cnt = msrvr.select('Inbox')
for i in cnt:
typ, msg_data = msrvr.fetch(str(i), '(RFC822)')
for response_part in msg_data:
if isinstance(response_part, tuple):
msg = email.message_from_string(response_part[1])
if msg:
from_message = msg['From']
sender = re.findall(r'<(.*?)>', from_message)[0]
try:
key_command = msg['subject'].lower()
logging_handler('{} {}'.format('The request subject is:', key_command))
except:
msg = '{} {}'.format('There\'s a problem with the',
key_command)
logging_handler(msg)
return key_command, sender

Future plans

I am already finishing up the code that shows me diagrams of monthly usage and my next steps include reading the cells’ current voltage and automatic triggering of the generator when they reach defined thresholds. I also want to add a Telegram bot to “talk” to the generator but that’s gonna be a material for the next blog entry! :D

Any questions and comments are more than welcome! The code is fully open source so please feel free to fork/clone and use it and abuse it!

--

--

Pavel Zagalsky

Principal Quality Engineer @ Palo Alto Networks. Love technology, music, cats and my family