Header Image - Kilo Charlie 4 Romeo Charlie Romeo

Category Archives

7 Articles

440 Repeater Build

The KC4RCR 440 Repeater!

Front View
Side View

Current status: completed T-MARC frequency coordination for 444.300/449.300 frequency pair with 141.3 Hz CTCSS.

Raspberry Pi repeater controller running AllStar with a Repeater Builder RIM_Lite USB interface with custom cable (9 pin to 25 pin).

Connect with All Star Node #58830 or Echolink Node # 527721 (KC4RCR-R)

Index: 234

Lightning Detector and Email Notifier

I decided to post a draft of this page since I keep referencing it on a few nets. Watch for updates as I continue to update and refine the build and this page. Updated 16 July 2023.

This how-to instruction set will build a local lightning detection notification system which will send an email via Python script running on a Raspberry Pi. This of course, could be adapted to run on other hardware platforms easily.

Here’s my list of items:

* In 2022 Google stopped allowing “less secure apps” to access email. When they removed allowing the user to decide for themself to enable or disable, it rendered the email for many Raspberry Pi users to non-functioning (this would apply in other builds as well). It appears a work around was found, though I have not tried it. You can read about it here: G-Mail and less secure sign-in technology.

First, set up your Raspberry Pi if you have not already. There are many instruction sets on the Internet including this one: https://www.raspberrypi.com/tutorials/how-to-set-up-raspberry-pi/. Also, any Debian-based Operating System should work fine if you can’t source a Raspberry Pi. In my case I am using the Raspberry Pi 4 Model B Rev 1.2 running Raspbian GNU/Linux 10 (buster). I do plan to move this over to an Ubuntu machine one day to free this Pi up for other experiments.

Check and see if you have Python2 installed by running Python -V at the command prompt. You can use newer versions if you wish, but my code snippets in this example were written for the version noted below.

$ python -V
Python 2.7.16

If you do not have Python, it can be installed with:

$ sudo apt update
$ sudo apt-get install python2

Now install the rtl_433 code (see official source code instructions here: https://github.com/merbanan/rtl_433/).

 $ sudo apt-get install rtl_433

rtl_433 is a very powerful tool! It can interpret numerous devices so be sure to check out the link above. Did you realize most cars can be tracked via the tire sensors which is now government mandated in many areas? Well now you do and this tool will also read cars as they drive by on the street! It’s all open and unencrypted. I make this point not to encourage snooping but to make folks aware of a pet peeve of mine which are new cars spewing data without knowledge or consent of most owners. Anyway, back to the lightning sensor discussion…

You will also need the msmtp package if you wish to send email notifications. Another package called mailutils is also helpful along with the mail transport agent. Those can be installed by running:

$ sudo apt-get install msmtp
$ sudo apt-get install mailutils
$ sudo apt-get install msmtp-mta

Which can also be combined as:
$ sudo apt-get install msmtp mailutils msmtp-mta

Here is the final setup of the Raspberry Pi with power (white cable), network (orange cable) and RTL-SDR Dongle in one of the USB ports. I also have a small band pass filter on the antenna connection (black cable at bottom with SMA connector). This additional filter isn’t generally needed but since I have a lot of radio activity going on in the area, I figured it couldn’t hurt. It doesn’t have great reviews but I tested it and it was a bit off frequency but not enough to impact my setup. Here is the link: https://www.amazon.com/Interface-Bandpass-Receiver-Dedicated-422-446MHz/dp/B0B1QSBZKR

Acurite 6045M Sensor placed outdoors. This can be found at: https://www.amazon.com/gp/product/B01LNALL6C/

The good thing about using this particular SDR Dongle is that it should be recognized by the Pi’s Operating System without installing anything additional. You can use the command ‘lsusb’ to be sure. Here you see it on the second output line below (Bus 001 Device 003).

$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 0bda:2838 Realtek Semiconductor Corp. RTL2838 DVB-T
Bus 001 Device 002: ID 2109:3431 VIA Labs, Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

If you run rtl_433 with no options, you will start getting a lot of data displayed continuously until you press Ctrl-C in the terminal. Below you will see two different Acurite-6045M devices running (id 85 and id 127). There was no modification to the Acurite devices. This is right out of the box with batteries installed.

Screen capture of rtl_433 running

A couple things of note. Acurite appears to send the data three times. I presume this is their standard to ensure the transmission is received properly. Second, the lightning strike count is a rolling counter which wraps from 255 back to 0. That becomes important in the Python code because you will need to look for a change in the counter, not an absolute number. I also restrict the data collected to only the Acurite protocol needed (thus not filling up my log with tire sensors and many others). The -R option allows that selection. The protocol needed for the Acurite 6045M is “40”, i.e. running as this command only reads the Acurite 6045M and similar sensors and outputs formats (via -F option) json and http (more on that below). The protocol list can be found at https://github.com/merbanan/rtl_433.

/usr/local/bin/rtl_433 -R 40 -F json -F http

Another fun aspect of the rtl_433 package is the ability to format the output as json, csv, http, syslog and a few others. It has an integrated http server which defaults to port 8433 when invoked with rtl_433 -F http. Point your web browser to http://127.0.0.1:8433 or whatever your Raspberry Pi’s IP is (if not local).

Screen capture of http data on port 8433

Now if all you want to do is view the data, you can stop here. The next steps are if you want to set up the Raspberry Pi to notify you via email or text that the lightning count has changed. I was hoping that the “active” tag in the data would be enough, but testing shows it is not. In my tests, the Acurite sensor goes into active mode regularly for unknown reasons. I suspect some is RFI, but I have not done enough testing. Ideally if the RFI field were true, the sensor should not go into active mode, but it’s hard to say what the thinking was in the design of the sensor. Even the author of rtl_433 states there are some transmitted bits in the message that have not been found to correlate to useful data. Check out the acurite.c code for an in-depth analysis.

For email sending, you use msmtp. I have never enjoyed working with msmtp. I find it rather clunky and usually have to fiddle around with it a bit. You must create a config file name msmtprc. For lots more information, try searching for msmtprc configuration. Here’s one example: https://centurio.net/2020/09/21/configure-mail-transport-agent-on-raspbian-with-external-smtp-server/. My example config file is below, redacted of real account login information of course. Make sure you have the /etc/ssl/certs/ca-certificates.crt as well. If you don’t have it properly installed, you might have to research how to get it on your particular system. My hosted email account has port 465 available for sending mail. You will have to modify the settings below based on your email provider.

$ cat /etc/msmtprc
defaults
auth on
tls on
tls_starttls off
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile /var/log/msmtp.log
aliases /etc/aliases
auto_from off
# Account details
account yourusername
host mail.yourserver.com
port 465
from yourusername@yourserver.com
user yourusername@yourserver.com
password S0m3P@$$w0RD
# Default Account
account default : yourusername

You can try a test email using the following (this is one line, be careful with copy paste):

$ echo "Notification System Test" | mail --debug-level=6 -s "Test" -a "From:Notification System sendinguser@domain.com" recievinguser@domain.com

I find the “-a From” header helps get though some spam filters, especially to a cellular phone text gateway. You should see the following output after sending the mail command and get an email for the specified recipient.

mail: sendmail binary: /usr/sbin/sendmail
mail: mu_mailer_send_message(): using From: sendinguser@domain.com
mail: Sending headers…
mail: Sending body…
mail: /usr/sbin/sendmail exited with: 0

Now we move on to the Python code. Let me be clear here! This code will work but it is a quick approach. You can tailor it anyway you want and certainly clean it up to be more efficient. I am still working on the code to add other features and multiple sensors, etc. What that means is this is an earlier version that ran for many months. It does work, just not as clean and neat as it could be. Remember, be careful with copy and paste.

import json
import sys
import datetime
import subprocess

k = 0
start = 0
strike_count_old = 0

outputfile = open(r"/home/pi/lightning.txt", "a")

try:
   for line in iter(sys.stdin.readline, b''):
      k = k + 1
      if k > 9:
          signal_string = json.loads(line)
          if signal_string["model"] == "Acurite-6045M":
               #print signal_string
               strike_count_new = signal_string["strike_count"]
               if strike_count_new != strike_count_old:
                    distance = signal_string["storm_dist"]
                    text = "{} - LIGHTNING STRIKE {} mi away. Historical count is now {}.".format(datetime.datetime.now().strftime("%m/%d/%Y %H:%M:%S"), distance, strike_count_new)
                    if start > 0:
                        outputfile.write(text)
                        outputfile.write("\n")
                        outputfile.flush()
			subprocess.call(['echo "{}" | mail -s "LIGHTNING STRIKE" -a "From:Notification System <sendinguser@domain.com>" receipient@domain.com'.format(text)], shell=True)
                    else:
                        start = 1
                    strike_count_old = strike_count_new
               else:
                    #text = "No strike at time but data is {}.\n".format(signal_string)
                    #outputfile.write(text)
                    #outputfile.flush()
                    pass

except KeyboardInterrupt:
   sys.stdout.flush()
   outputfile.close()
   pass

I’ve left some of the testing lines in there as well which are commented out plus I skip over the first number of lines read to make sure the input gets settled. (I will explain more on the code at a later time). This code reads the json format the rtl_433 will output from “-F json”. I saved this in a file called lightning.py in /home/pi. You will pipe the output from rtl_433 via the -F json command. In my example, I am also running the http server so I can view live data in a web browser. This code will send an email for every strike with the calculated distance (presumed in miles) along with the current rolling strike counter. With this snippet, it only looks for a device named “Acurite-6045M”. It would need more specificity if used with multiple sensors (what I am experimenting with now).

$ rtl_433 -R 40 -F json -F http | /usr/bin/python /home/pi/lightning.py

To run this at startup, you can add an entry in /etc/rc.local (on Raspian). If you are using Ubuntu 20.04+, rc.local is not enabled by default. If you wish to use this approach see https://marsown.com/wordpress/how-to-enable-etc-rc-local-with-systemd-on-ubuntu-20-04/. To use rc.local to start the script on boot, add the rtl_433 line below:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

/usr/local/bin/rtl_433 -R 40 -F json -F http | /usr/bin/python /home/pi/lightning.py

exit 0

One final comment about the code. This will send ALL detected lightning strikes to email. Depending on your area, this could be a lot! I will eventually modify the code to compile the data, but again, this is proof of concept at this point. Besides adding diversity of sensors, my other planned addition is a commanded visual cue when lightning in the area.


To be continued…

Index: 15

Power Outage Notification System

by admin 0 Comments

If you need to be notified of a power outage at your equipment location, this is a quick and cheap way of doing just that. This method will allow you to use a Raspberry Pi, connected to both an Uninterruptible Power Supply (UPS) and a commercial power outlet, to monitor and send email/text alerts with power changes.

Assumptions:

  • You have a Raspberry Pi already set up which is networked
  • You have an SMTP service installed and setup on the Pi like sSMTP
  • You have the ability to execute Python (or can install it if your distro does not have it)

Parts:

  • Raspberry Pi (any model, even Zeros as long as you can network)
  • Relay (this is the one I used)
  • A UPS power source to run the Pi
  • A non-UPS power source to monitor
  • Jumpers
  • Soldering Iron and Solder

Here is the relay I used. It takes 5v from a standard USB so it is quite universal but it does require one quick modification to simplify the power need. Remember the USB power goes to a commercial power outlet not serviced by a UPS system.

5V Relay

The modification is this: you probably don’t want to plug in a USB power and input power to control the relay. Just using one is fine and the USB power can act as both. If the unit is powered by the USB, you can trigger the relay by pushing the “Button Trigger”. Well, just keep it on if there is power and it will disconnect when there is no power. Simple. How do you keep the button pressed? Jumper it always on.

Jumper on button trigger

You can remove the button if you like, but I just jumper-ed over it (yellow wire). Power at USB now always turns on the relay (at the Normally Open terminal).

The relay has three screw terminals. Common (COMM), Normally Open (NO), and Normally Closed (NC). Technically you can write the code anyway you want to as long as the logic is the same or inverse. I wrote it such that COMM is 3.3V and the NO terminal went to GPIO 26 (BCM). That is, if input BCM 26 is HIGH (3.3V) there is power. If input BCM 26 is 0V, there is no power.

Here is the Pi header wiring diagram from Raspberry Pi Pinout:

RPi Pinout Diagram

Connect the COMM wire (RED) to any 3.3V pin (in the pic here I used physical pin number 17) and the NO terminal wire (YELLOW) to BCM GPIO 26 (physical pin number 37). You can vary this depending on your code, if you prefer. For clarification the other pins used at the top are for a room temperature and humidity sensor and not part of this project.

Pi Wired to Relay

Below is the code. Because it may be hard to read on WordPress, here is a link to the file. Remember to change it from .txt to .py to run.

import RPi.GPIO as GPIO    # import GPIO library
import subprocess          # needed for subprocess call
from time import sleep     # this lets us have a time delay

GPIO.setmode(GPIO.BCM)     # set up BCM GPIO numbering
GPIO.setup(26, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) # set up pin 26 for input detection of 3.3V

init = 1  # set inital state for boot message

try:
    while True:            # this will carry on until you hit CTRL+C
        if GPIO.input(26): # if port 26 == 1 (there is power)
            if init == 1:  # we must have cold booted on purpose or from a failure on UPS dead battery extended outage
                email = 'echo "REBOOT from extended power failure or device reset. Power is ON." | mail email1@email.com, email2@email.com'
                subprocess.call(email, shell=True) # send email command
            else:
                email = 'echo "Power restored at site. Commercial power is ON." | mail email1@email.com, email2@email.com'
                subprocess.call(email, shell=True) # send email command
            while GPIO.input(26): # do nothing if the power state stays on
                sleep(0.1)
        else: # there is no power detected at pin 26
            init = 0 # why bother checking every time it happens only once
            email = 'echo "Power failure at site. Commercial power is OFF." | mail email1@email.com, email2@email.com'
            subprocess.call(email, shell=True) # send email command
            while GPIO.input(26) == 0: # do nothing if the power state stays off
                sleep(0.1)

finally:                   # this block will run no matter how the try block exits
    GPIO.cleanup()         # clean up on exit

A couple notes on the code. You can add as many email addresses as you want separated by commas. The sleep is very short, you can adjust if too much CPU is used. Don’t use “shell=True” in a subprocess.call if you don’t control what is going into it. If you use that based on user input, they could execute. Here, there is no user input requested.

Also, DO NOT use the 5v pins. The header cannot tolerate that much voltage and you will burn it out. Only use 3.3V.

You probably want this to start automatically each time the RPi is booted. You can add a line in /etc/rc.local to do this (modified for your file location):

/usr/bin/python /home/pi/Code/PowerCheck.py

That should be it. Happy monitoring.

Index: 5
PHP Code Snippets Powered By : XYZScripts.com