-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathbattery_status.py
116 lines (96 loc) · 3.06 KB
/
battery_status.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env python
import os
import time
import mraa
import math
import sys
import subprocess
os.chdir('/home/root/gpio')
print time.strftime('%X') + " START"
snooze = 10
charge = -101
subprocess.call('echo 0 > /home/root/debian/home/buendia/battery_shutdown.txt', shell=True)
## INITIALISE VARIABLES
MAX17043_ADDRESS = 0x36
VCELL_REGISTER = 0x02
SOC_REGISTER = 0x04
MODE_REGISTER = 0x06
VERSION_REGISTER = 0x08
CONFIG_REGISTER = 0x0C
COMMAND_REGISTER = 0xFE
I2C_PORT = 1
x = mraa.I2c(I2C_PORT)
x.address(MAX17043_ADDRESS)
red = mraa.Gpio(35) # 'GP131'
red.dir(mraa.DIR_OUT)
# I2C FUNCTIONS
def cellVoltage():
msb = x.readReg(VCELL_REGISTER)
lsb = x.readReg(VCELL_REGISTER+1)
value = msb << 4 | lsb >> 4
return (value * .00125)
def stateOfCharge():
return (x.readReg(SOC_REGISTER) + (x.readReg(SOC_REGISTER+1) / 256))
def reset_i2c():
x.writeWordReg(COMMAND_REGISTER, 0x0054)
time.sleep(.3) #spec states 125ms
def quickStart():
x.writeWordReg(COMMAND_REGISTER, 0x4000)
time.sleep(.5) #spec states 500ms
def get_battery_status():
reset_i2c()
quickStart()
charge = stateOfCharge()
return charge
# flash LED for individual periods and total duration
# includes safeguards for when variablised 'period' exceeds limits and would crash script
def flash_led(led, duration, period):
period = min(duration, max(.1, float(period)))/2
iterations = int(math.floor((float(duration) / period) + .5)/2)
for i in range(iterations):
led.write(1)
time.sleep(period)
led.write(0)
time.sleep(period)
# test LED
flash_led(red, 3, .1)
time.sleep(1)
k = 0
# Main loop
while True:
charge_new = get_battery_status()
try:
charge_new = int(charge_new)
except:
print "Error: failed to convert 'charge' to int " + str(len(charge_new)) + ', string=' + charge_new
# smoothed charge reading
if charge == -101:
charge = float(charge_new) # initialise on 1st loop
else:
charge = charge * 0.88 + float(charge_new) * 0.12 # ~ avg 12 readings (optimised params)
# output to files
subprocess.call('echo ' + str(int(charge+.5)) + ' > battery_charge.txt', shell=True)
subprocess.call('cp battery_charge.txt /home/root/debian/home/buendia/battery_charge.txt', shell=True)
if k == 0:
try:
subprocess.call('cat battery_charge.txt >> sd/logs/battery_charge_log.txt', shell=True)
except:
print 'Cannot write to sd/logs/battery_charge_log.txt'
k = (k + 1) % 60 # i.e. every 10 mins
if charge <= 5 and not charge < 1: # exception for e.g. disconnected fuel gauge wire
print "Emergency shutdown: battery=" + str(charge) + "%"
subprocess.call('echo 1 > /home/root/debian/home/buendia/battery_shutdown.txt', shell=True)
time.sleep(30) # time for server to alert tablets
subprocess.call('poweroff', shell=True)
time.sleep(10)
# light/flash RED LED when battery low
# if charge > 50:
# red.write(0)
# time.sleep(snooze)
# elif charge > 25:
# red.write(1)
# time.sleep(snooze)
# else:
# flash_led(red, snooze, float(charge)/30)
# any output to file now
sys.stdout.flush()