Code: Select all
from bluepy import btle
from bluepy.btle import Scanner, DefaultDelegate
from bluepy.btle import AssignedNumbers
from bluepy.btle import BTLEDisconnectError
from datetime import datetime
from struct import unpack
from log4python.Log4python import log
from oauth2client.service_account import ServiceAccountCredentials
import gspread
import binascii
import threading
import time
import subprocess
###
from board import SCL, SDA
import busio
from PIL import Image, ImageDraw, ImageFont
import adafruit_ssd1306
###
BDLLog = log("BDLLog");
RAWLog = log("RAWLog");
next_row=1
timerFlag=0
# Create the I2C interface.
i2c = busio.I2C(SCL, SDA)
# Create the SSD1306 OLED class.
# The first two parameters are the pixel width and pixel height. Change these
# to the right size for your display!
disp = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c)
# Clear display.
disp.fill(0)
disp.show()
# Create blank image for drawing.
# Make sure to create image with mode '1' for 1-bit color.
width = disp.width
height = disp.height
image = Image.new("1", (width, height))
# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)
# Draw a black filled box to clear the image.
draw.rectangle((0, 0, width, height), outline=0, fill=0)
# Draw some shapes.
# First define some constants to allow easy resizing of shapes.
padding = -2
top = padding
bottom = height - padding
# Move left to right keeping track of the current x position for drawing shapes.
x = 0
# Load default font.
font = ImageFont.load_default()
# Alternatively load a TTF font. Make sure the .ttf font file is in the
# same directory as the python script!
# Some other nice fonts to try: http://www.dafont.com/bitmap.php
#font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf',10)
def write2Google():
global next_row
global voltage
global soc
global current
global timerFlag
next_row=next_row+1
new_row = [datetime.now().strftime("%d/%m/%Y %H:%M:%S"), str("{:6.2f}".format(voltage)), str("{:6.2f}".format(soc)), str("{:8.2f}".format(current))]
BDLLog.debug("Writing into google sheet")
BDLLogsheet.resize(next_row)
BDLLogsheet.append_row(new_row)
mobileAppSheet.update('B2', datetime.now().strftime("%d/%m/%Y %H:%M:%S"))
mobileAppSheet.update('C2', str("{:6.2f}".format(soc)))
mobileAppSheet.update('D2', str("{:6.2f}".format(voltage)))
mobileAppSheet.update('E2', str("{:6.2f}".format(current)))
timerFlag=0
def next_available_row(worksheet):
str_list = list(filter(None, worksheet.col_values(1)))
return str(len(str_list)+1)
class ScanDelegate(DefaultDelegate):
def __init__(self):
DefaultDelegate.__init__(self)
# ... initialise here
class MyDelegate(btle.DefaultDelegate):
def __init__(self):
btle.DefaultDelegate.__init__(self)
# ... initialise here
def handleNotification(self, cHandle, data):
RAWLog.debug(data)
global voltage
global soc
global current
global timerFlag
if len(data) >= 85:
voltage=byte2int(data,25)/1000
soc=byte2short(data,41)*.4
current=byte2short(data,29)/100
voltageMV=round(voltage*100).to_bytes(2, 'little', signed=True)
currentMA=round(current*10).to_bytes(2, 'little', signed=True)
factCap=byte2short(data,43)/10
rateCap=byte2short(data,45)/10
cell1Volt=byte2int(data,47)/1000
cell2Volt=byte2int(data,49)/1000
#print(str("{:6.2f}".format(voltage))+ " : " + str("{:6.2f}".format(soc)) + " : " + str("{:8.2f}".format(current)))
BDLLog.debug( str("{:6.2f}".format(voltage)) \
+ " : " + str("{:6.2f}".format(soc)) \
+ " : " + str("{:8.2f}".format(current)) \
+ " : " + str("{:8.2f}".format(factCap)) \
+ " : " + str("{:8.2f}".format(rateCap)) \
+ " : " + str("{:8.2f}".format(cell1Volt)) \
+ " : " + str("{:8.2f}".format(cell2Volt)) \
+ " : " + str((voltageMV+currentMA).hex()) \
)
if timerFlag == 0:
draw.text((x, top + 0), "SOC : " + str("{:8.2f}".format(soc)) +"%" , font=font, fill=255)
draw.text((x, top + 11),"Vol : " + str("{:8.2f}".format(voltage)) +"V" , font=font, fill=255)
draw.text((x, top + 22),"Cur : " + str("{:8.2f}".format(current)) + "A", font=font, fill=255)
#draw.text((x, top + 0), str("{:6.2f}".format(soc)) +"% : " + str("{:6.2f}".format(voltage)) +"V" , font=font, fill=255)
#draw.text((x, top + 17),str("{:8.2f}".format(current)) + "A" , font=font, fill=255)
# Display image.
disp.image(image)
disp.show()
t = threading.Timer(60.0,write2Google)
timerFlag=1
t.start()
def byte2int(bArr, i):
return (bArr[i + 2] << 24) | (bArr[i + 1] & 255) | ((bArr[i] << 8) & 65280) | ((bArr[i + 3] << 24) >> 8)
def byte2short(bArr, i):
retInt=(((bArr[i] << 8) & -256) | (bArr[i+1] & 255)).to_bytes(2,'little')
return(unpack('h'*(len(retInt)//2),retInt)[0])
# Initialisation -------
whileCount=0
BDLLog.debug("Connecting to google sheet")
scope = ['https://spreadsheets.google.com/feeds',
'https://www.googleapis.com/auth/drive']
creds = ServiceAccountCredentials.from_json_keyfile_name('client_secret.json', scope)
client = gspread.authorize(creds)
monYY=datetime.now().strftime('%b%Y')
print("Month Year = "+ monYY.upper())
mobileAppSheet = client.open('BatteryData').worksheet("BDL")
BDLLogsheet = client.open('TIRUCHERAI_BDL_' + monYY.upper()).worksheet("01")
next_row = int(next_available_row(BDLLogsheet))
BDLLog.debug("Next row = " + str(next_row) )
BDLLog.debug("Bluetooth BLE Initializating")
while True:
try:
whileCount=whileCount+1
if whileCount>= 2000:
resp = subprocess.call("sudo hciconfig hci0 down && sudo hciconfig hci0 up", shell=True)
BDLLog.debug("Restared bluetooth " + str(resp))
time.sleep(30)
whileCount=0
BDLLog.debug("Starting to scan, count = " + str(whileCount))
scanner = Scanner().withDelegate(ScanDelegate())
devices = scanner.scan(10.0)
BDLName="JEPL15S02849000"
CHRName="0000ffe1-0000-1000-8000-00805f9b34fb"
BDLMAC="B8:27:EB:4E:49:EB"
#for dev in devices:
#for (adtype, desc, value) in dev.getScanData():
#if value == BDLName:
#BDLMAC=dev.addr
#break
#p = btle.Peripheral(BDLMAC,addrType=btle.ADDR_TYPE_RANDOM)
p = btle.Peripheral(BDLMAC)
p.setMTU(200)
p.setDelegate( MyDelegate())
chList = p.getCharacteristics()
for ch in chList:
if str(ch.uuid) == CHRName:
BDLLog.debug (ch)
BDLLog.debug (ch.valHandle)
break
desc = ch.getDescriptors(AssignedNumbers.client_characteristic_configuration);
print(desc[0].handle)
print(ch.valHandle)
p.writeCharacteristic(desc[0].handle, b"\x01\x00")
#p.writeCharacteristic(desc[0].handle, b"\x01\x00")
BDLLog.debug("Started to listen for MACaddress = " + BDLMAC)
# Main loop --------
while True:
if p.waitForNotifications(1.0):
continue
except BTLEDisconnectError as btlede:
BDLLog.debug("Device disconnected will start scan again")
except:
BDLLog.debug(datetime.now().strftime("%d/%m/%Y %H:%M:%S") + " : Unkown error will start scan again")
#resp = subprocess.call("sudo hciconfig hci0 down && sudo hciconfig hci0 up", shell=True)
#BDLLog.debug("Restared bluetooth " + str(resp))
time.sleep(30)