<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.geekworm.com/index.php?action=history&amp;feed=atom&amp;title=CommentStreams%3AA82bc30eddc86f48b1de40b45cd01686</id>
	<title>CommentStreams:A82bc30eddc86f48b1de40b45cd01686 - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.geekworm.com/index.php?action=history&amp;feed=atom&amp;title=CommentStreams%3AA82bc30eddc86f48b1de40b45cd01686"/>
	<link rel="alternate" type="text/html" href="https://wiki.geekworm.com/index.php?title=CommentStreams:A82bc30eddc86f48b1de40b45cd01686&amp;action=history"/>
	<updated>2026-07-27T15:23:44Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://wiki.geekworm.com/index.php?title=CommentStreams:A82bc30eddc86f48b1de40b45cd01686&amp;diff=33076&amp;oldid=prev</id>
		<title>37.19.221.52: Migrated reply #2953</title>
		<link rel="alternate" type="text/html" href="https://wiki.geekworm.com/index.php?title=CommentStreams:A82bc30eddc86f48b1de40b45cd01686&amp;diff=33076&amp;oldid=prev"/>
		<updated>2022-12-26T00:54:08Z</updated>

		<summary type="html">&lt;p&gt;Migrated reply #2953&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Sorry, the code did not paste nicely when copied directly from Linux.  I&amp;#039;ll try again with a copy from windows.&lt;br /&gt;
&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
import RPi.GPIO as GPIO&lt;br /&gt;
import time&lt;br /&gt;
import os&lt;br /&gt;
import datetime&lt;br /&gt;
import struct&lt;br /&gt;
import smbus&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
####################################&lt;br /&gt;
# Start Config&lt;br /&gt;
####################################&lt;br /&gt;
&lt;br /&gt;
SHUTDOWN_TRIGGER = &amp;quot;All&amp;quot;            # (AC Power,Capacity,Voltage,All) - determines what settings will trigger a shutdown.&lt;br /&gt;
AC_LOSS_WAIT_MINUTES = 15           # Number of minutes after power loss before shutdown is issued&lt;br /&gt;
CAPACITY_THRESHOLD = 50             # Shutdown will occur when capacity drops below the stated percentage&lt;br /&gt;
CAPACITY_STATUS_LOW = 20            # Low capacity warning below this level&lt;br /&gt;
VOLTAGE_THRESHOLD = 3.70            # Shutdown will occur when voltage drops below the stated percentage&lt;br /&gt;
VOLTAGE_STATUS_LOW = 3.50           # Low valtage warning below this level&lt;br /&gt;
TEST_MODE = &amp;quot;N&amp;quot;                     # (Y,N) - Will show extra output and will not perform shutdown when TEST_MODE = &amp;quot;Y&amp;quot;, normal opperation TEST_MODE = &amp;quot;N&amp;quot;&lt;br /&gt;
BUZZER_ON = &amp;quot;N&amp;quot;                     # (Y,N) - BUZZER_ON = &amp;quot;Y&amp;quot; and buzzer will beep when power is initially lost and right before shutdown&lt;br /&gt;
BUZZER_SECONDS = 0.5                # Number of seconds the buzzer will sound&lt;br /&gt;
&lt;br /&gt;
####################################&lt;br /&gt;
# End Config&lt;br /&gt;
####################################&lt;br /&gt;
&lt;br /&gt;
WAIT_SECONDS = AC_LOSS_WAIT_MINUTES * 6&lt;br /&gt;
WAIT_STR = str(AC_LOSS_WAIT_MINUTES)&lt;br /&gt;
&lt;br /&gt;
GPIO_PORT = 26&lt;br /&gt;
I2C_ADDR = 0x36&lt;br /&gt;
&lt;br /&gt;
GPIO.setmode(GPIO.BCM)&lt;br /&gt;
GPIO.setup(GPIO_PORT, GPIO.OUT)&lt;br /&gt;
&lt;br /&gt;
PLD_PIN = 6&lt;br /&gt;
BUZZER_PIN = 20&lt;br /&gt;
GPIO.setwarnings(False)&lt;br /&gt;
GPIO.setmode(GPIO.BCM)&lt;br /&gt;
GPIO.setup(PLD_PIN, GPIO.IN)&lt;br /&gt;
GPIO.setup(BUZZER_PIN, GPIO.OUT)&lt;br /&gt;
GPIO.output(BUZZER_PIN, 0)&lt;br /&gt;
POWER_LOST_SEC = 0&lt;br /&gt;
&lt;br /&gt;
def soundBuzzer(BUZZER_ON,BUZZER_SECONDS,BUZZER_PIN):&lt;br /&gt;
    if ( BUZZER_ON == &amp;quot;Y&amp;quot; ):&lt;br /&gt;
        GPIO.output(BUZZER_PIN, 1)&lt;br /&gt;
        time.sleep(BUZZER_SECONDS)&lt;br /&gt;
        GPIO.output(BUZZER_PIN, 0)&lt;br /&gt;
&lt;br /&gt;
def acPower(PLD_PIN):&lt;br /&gt;
&lt;br /&gt;
    AC_STATUS = &amp;quot;GOOD&amp;quot;&lt;br /&gt;
    i = GPIO.input(PLD_PIN)&lt;br /&gt;
    if ( i == 0 ):&lt;br /&gt;
        AC_STATUS = &amp;quot;GOOD&amp;quot;&lt;br /&gt;
    elif ( i == 1 ):&lt;br /&gt;
        AC_STATUS = &amp;quot;LOST&amp;quot;&lt;br /&gt;
    return AC_STATUS&lt;br /&gt;
&lt;br /&gt;
def readVoltage(bus,VOLTAGE_STATUS_LOW):&lt;br /&gt;
&lt;br /&gt;
    address = I2C_ADDR&lt;br /&gt;
    read = bus.read_word_data(address, 2)&lt;br /&gt;
    swapped = struct.unpack(&amp;quot;&amp;lt;H&amp;quot;, struct.pack(&amp;quot;&amp;gt;H&amp;quot;, read))[0]&lt;br /&gt;
    VOLTAGE = swapped * 1.25 /1000/16&lt;br /&gt;
    VOLTAGE_STATUS = &amp;quot;Good&amp;quot;&lt;br /&gt;
    if ( VOLTAGE &amp;lt;= VOLTAGE_STATUS_LOW ):&lt;br /&gt;
        VOLTAGE_STATUS = &amp;quot;Low&amp;quot;&lt;br /&gt;
    return VOLTAGE,VOLTAGE_STATUS&lt;br /&gt;
&lt;br /&gt;
def readCapacity(bus,CAPACITY_STATUS_LOW):&lt;br /&gt;
&lt;br /&gt;
    address = I2C_ADDR&lt;br /&gt;
    read = bus.read_word_data(address, 4)&lt;br /&gt;
    swapped = struct.unpack(&amp;quot;&amp;lt;H&amp;quot;, struct.pack(&amp;quot;&amp;gt;H&amp;quot;, read))[0]&lt;br /&gt;
    CAPACITY = swapped/256&lt;br /&gt;
    CAPACITY_STATUS = &amp;quot;Good&amp;quot;&lt;br /&gt;
    if ( CAPACITY &amp;gt;= 100 ):&lt;br /&gt;
        CAPACITY_STATUS = &amp;quot;Full&amp;quot;&lt;br /&gt;
    elif ( CAPACITY &amp;lt;= CAPACITY_STATUS_LOW ):&lt;br /&gt;
        CAPACITY_STATUS = &amp;quot;Low&amp;quot;&lt;br /&gt;
    return CAPACITY,CAPACITY_STATUS&lt;br /&gt;
&lt;br /&gt;
def safeShutdown(GPIO_PORT):&lt;br /&gt;
&lt;br /&gt;
    GPIO.output(GPIO_PORT, GPIO.HIGH)&lt;br /&gt;
    os.system(&amp;#039;sudo shutdown -h now&amp;#039;)&lt;br /&gt;
    time.sleep(3)&lt;br /&gt;
    GPIO.output(GPIO_PORT, GPIO.LOW)&lt;br /&gt;
&lt;br /&gt;
bus = smbus.SMBus(1) # 0 = /dev/i2c-0 (port I2C0), 1 = /dev/i2c-1 (port I2C1)&lt;br /&gt;
&lt;br /&gt;
now = datetime.datetime.now()&lt;br /&gt;
date_time = now.strftime(&amp;quot;%m/%d/%Y, %H:%M:%S&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
AC_STATUS = acPower(PLD_PIN)&lt;br /&gt;
VOLTAGE,VOLTAGE_STATUS = readVoltage(bus,VOLTAGE_STATUS_LOW)&lt;br /&gt;
CAPACITY,CAPACITY_STATUS = readCapacity(bus,CAPACITY_STATUS_LOW)&lt;br /&gt;
&lt;br /&gt;
print (&amp;quot;******************************************&amp;quot;)&lt;br /&gt;
print(date_time + &amp;quot; : System Startup&amp;quot;)&lt;br /&gt;
print(date_time + &amp;quot; : AC Power &amp;quot; + AC_STATUS)&lt;br /&gt;
print(date_time + &amp;quot; : Battery Capacity &amp;quot; + CAPACITY_STATUS + &amp;quot; (&amp;quot; + str(round(CAPACITY,2)) + &amp;quot;%)&amp;quot; )&lt;br /&gt;
print(date_time + &amp;quot; : Battery Voltage &amp;quot; + VOLTAGE_STATUS + &amp;quot; (&amp;quot; + str(round(VOLTAGE,2)) + &amp;quot;V)&amp;quot; )&lt;br /&gt;
if ( TEST_MODE == &amp;quot;Y&amp;quot; ):&lt;br /&gt;
    print(date_time + &amp;quot; : Started in Test Mode, No actual shutdown will occur, program will exit after shutdown triggered.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
&lt;br /&gt;
#    print (&amp;quot;******************************************&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    now = datetime.datetime.now()&lt;br /&gt;
    date_time = now.strftime(&amp;quot;%m/%d/%Y, %H:%M:%S&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    AC_STATUS = acPower(PLD_PIN)&lt;br /&gt;
    VOLTAGE,VOLTAGE_STATUS = readVoltage(bus,VOLTAGE_STATUS_LOW)&lt;br /&gt;
    CAPACITY,CAPACITY_STATUS = readCapacity(bus,CAPACITY_STATUS_LOW)&lt;br /&gt;
&lt;br /&gt;
    if ( SHUTDOWN_TRIGGER == &amp;quot;AC Power&amp;quot; or SHUTDOWN_TRIGGER == &amp;quot;All&amp;quot; ):&lt;br /&gt;
        if ( AC_STATUS == &amp;quot;GOOD&amp;quot; ):&lt;br /&gt;
            if ( POWER_LOST_SEC &amp;gt; 0 ):&lt;br /&gt;
                print(date_time + &amp;quot; : AC Power Restored - Shutdown cancelled&amp;quot;)&lt;br /&gt;
                POWER_LOST_SEC = 0&lt;br /&gt;
            else:&lt;br /&gt;
                if ( TEST_MODE == &amp;quot;Y&amp;quot; ):&lt;br /&gt;
                    print(date_time + &amp;quot; : AC Power &amp;quot; + AC_STATUS)&lt;br /&gt;
        elif ( AC_STATUS == &amp;quot;LOST&amp;quot; ):&lt;br /&gt;
            if ( TEST_MODE == &amp;quot;Y&amp;quot; ):&lt;br /&gt;
                print(date_time + &amp;quot; : AC Power &amp;quot; + AC_STATUS)&lt;br /&gt;
            POWER_LOST_SEC += 1&lt;br /&gt;
            if ( POWER_LOST_SEC == 1 ):&lt;br /&gt;
                print(date_time + &amp;quot; : AC Power Lost - Shutdown in &amp;quot; + str(AC_LOSS_WAIT_MINUTES) + &amp;quot;  minutes&amp;quot;)&lt;br /&gt;
                soundBuzzer(BUZZER_ON,BUZZER_SECONDS,BUZZER_PIN)&lt;br /&gt;
            if ( POWER_LOST_SEC &amp;gt;= WAIT_SECONDS ):&lt;br /&gt;
                print(date_time + &amp;quot; : Shutdown in progress due to AC power loss&amp;quot;)&lt;br /&gt;
                soundBuzzer(BUZZER_ON,BUZZER_SECONDS,BUZZER_PIN)&lt;br /&gt;
                if ( TEST_MODE != &amp;quot;Y&amp;quot; ):&lt;br /&gt;
                    safeShutdown(GPIO_PORT)&lt;br /&gt;
                else:&lt;br /&gt;
                    print(date_time + &amp;quot; : Started in Test Mode, No actual shutdown will occur, program will exit.&amp;quot;)&lt;br /&gt;
                    break&lt;br /&gt;
&lt;br /&gt;
    if ( SHUTDOWN_TRIGGER == &amp;quot;Capacity&amp;quot; or SHUTDOWN_TRIGGER == &amp;quot;All&amp;quot; ):&lt;br /&gt;
        if ( CAPACITY &amp;gt; CAPACITY_THRESHOLD ):&lt;br /&gt;
            if ( TEST_MODE == &amp;quot;Y&amp;quot; ):&lt;br /&gt;
                print(date_time + &amp;quot; : Battery Capacity &amp;quot; + CAPACITY_STATUS + &amp;quot; (&amp;quot; + str(round(CAPACITY,2)) + &amp;quot;%)&amp;quot; )&lt;br /&gt;
        elif ( CAPACITY &amp;lt;= CAPACITY_THRESHOLD ):&lt;br /&gt;
            print(date_time + &amp;quot; : Battery Capacity &amp;quot; + CAPACITY_STATUS + &amp;quot; (&amp;quot; + str(round(CAPACITY,2)) + &amp;quot;%)&amp;quot; )&lt;br /&gt;
            print(date_time + &amp;quot; : Shutdown in progress due to battery Capacity below &amp;quot; + str(CAPACITY_THRESHOLD) + &amp;quot;% threshold&amp;quot;)&lt;br /&gt;
            soundBuzzer(BUZZER_ON,BUZZER_SECONDS,BUZZER_PIN)&lt;br /&gt;
            if ( TEST_MODE != &amp;quot;Y&amp;quot; ):&lt;br /&gt;
                safeShutdown(GPIO_PORT)&lt;br /&gt;
            else:&lt;br /&gt;
                print(date_time + &amp;quot; : Started in Test Mode, No actual shutdown will occur, program will exit.&amp;quot;)&lt;br /&gt;
                break&lt;br /&gt;
&lt;br /&gt;
    if ( SHUTDOWN_TRIGGER == &amp;quot;Voltage&amp;quot; or SHUTDOWN_TRIGGER == &amp;quot;All&amp;quot; ):&lt;br /&gt;
        if ( VOLTAGE &amp;gt; VOLTAGE_THRESHOLD ):&lt;br /&gt;
            if ( TEST_MODE == &amp;quot;Y&amp;quot; ):&lt;br /&gt;
                print(date_time + &amp;quot; : Battery Voltage &amp;quot; + VOLTAGE_STATUS + &amp;quot; (&amp;quot; + str(round(VOLTAGE,2)) + &amp;quot;V)&amp;quot; )&lt;br /&gt;
        elif ( VOLTAGE &amp;lt;= VOLTAGE_THRESHOLD ):&lt;br /&gt;
            print(date_time + &amp;quot; : Battery Voltage &amp;quot; + VOLTAGE_STATUS + &amp;quot; (&amp;quot; + str(round(VOLTAGE,2)) + &amp;quot;V)&amp;quot; )&lt;br /&gt;
            print(date_time + &amp;quot; : Shutdown in progress due to battery Voltage below &amp;quot; + str(VOLTAGE_THRESHOLD) + &amp;quot;V threshold&amp;quot;)&lt;br /&gt;
            soundBuzzer(BUZZER_ON,BUZZER_SECONDS,BUZZER_PIN)&lt;br /&gt;
            if ( TEST_MODE != &amp;quot;Y&amp;quot; ):&lt;br /&gt;
                safeShutdown(GPIO_PORT)&lt;br /&gt;
            else:&lt;br /&gt;
                print(date_time + &amp;quot; : Started in Test Mode, No actual shutdown will occur, program will exit.&amp;quot;)&lt;br /&gt;
                break&lt;br /&gt;
&lt;br /&gt;
    time.sleep(10)&lt;br /&gt;
GPIO.cleanup()&amp;lt;!-- migrated from Comments; original IP: 37.19.221.52 --&amp;gt;&lt;/div&gt;</summary>
		<author><name>37.19.221.52</name></author>
	</entry>
</feed>