114 lines
3.6 KiB
Python
114 lines
3.6 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
__author__ = 'thomas'
|
|
|
|
import serial
|
|
import os
|
|
import argparse
|
|
##from datetime import datetime
|
|
|
|
verbosity=False
|
|
|
|
def log(param):
|
|
if verbosity:
|
|
print param
|
|
|
|
class BS21:
|
|
def __init__(self, dev='/dev/tty.BS21-21-000000-0-A-SPPDev', pin='1234'):
|
|
self.dev = dev
|
|
self.pin = pin
|
|
self.resp=None
|
|
|
|
def openSerialPort(self):
|
|
"""
|
|
open the serial port for the bluetooth SDP/RFCOMM connection
|
|
"""
|
|
try:
|
|
s = serial.Serial(
|
|
port=self.dev,
|
|
baudrate=115200,
|
|
parity=serial.PARITY_NONE,
|
|
stopbits=serial.STOPBITS_ONE,
|
|
bytesize=serial.EIGHTBITS,
|
|
timeout=10)
|
|
#s.open() ## is alerady open? Ouch!
|
|
except serial.SerialException as e:
|
|
print "ERROR: "+e.message
|
|
s = None
|
|
log("... failed to open the serial port!")
|
|
return s
|
|
|
|
def command(self, cmd):
|
|
bs21 = self.openSerialPort()
|
|
if bs21==None:
|
|
log("something wrong, quitting")
|
|
print "ERROR"
|
|
exit()
|
|
log("connection established, write command "+cmd+"...")
|
|
bs21.write(cmd+"#"+ self.pin + "\r\n")
|
|
log("command transmitted, now waiting for response...")
|
|
resp = self.getResponse(bs21)
|
|
dollar=(resp[0][0]=='$')
|
|
if not dollar:
|
|
log("unexpected response: "+self.resp)
|
|
print "ERROR"
|
|
elif resp[0]=='$OK':
|
|
pass
|
|
elif resp[0][1:3]=='BS':
|
|
(hw, ver, unknown, hh, mm, ss) = resp[0].split(' ')
|
|
(str_bs, str_21, serialId, state, str_A) = hw.split('-')
|
|
print "Model "+str_bs[1:3]+"-"+str_21+" Serial ID="+serialId
|
|
print " Revision "+ver
|
|
if state == '1':
|
|
print " Power switch = ON"
|
|
elif state == '0':
|
|
print " Power switch = OFF"
|
|
else:
|
|
print " Power switch = UNKNOWN ("+state+")"
|
|
print " Time: "+hh+":"+mm+":"+ss
|
|
bs21.close()
|
|
|
|
def getResponse(self, bs21):
|
|
self.resp=bs21.readline().strip()
|
|
log("... got response: '"+self.resp+"'")
|
|
return self.resp.split('|')
|
|
|
|
|
|
if __name__=="__main__":
|
|
parser = argparse.ArgumentParser(
|
|
description='control Renkforce BS21 via Bluetooth',
|
|
epilog='''
|
|
Valid commands are either raw BS21 protocol like RELX, REL0, REL1, INFO, CLEAR00 (all uppercase)
|
|
or complex commands (all lowercase):
|
|
timer
|
|
...
|
|
optional: store bluetooth device in environment variable $BS21_DEV and the PIN in $BS21_PIN
|
|
''')
|
|
parser.add_argument('-v', '--verbose', help='increase verbosity', action="store_true")
|
|
parser.add_argument('-d', '--device', type=str, help='path to the device file for bluetooth connection')
|
|
parser.add_argument('-p', '--pin', type=str, help='the PIN to access BS21')
|
|
parser.add_argument('command', type=str, nargs='+', help='command (+args) to execute')
|
|
args = parser.parse_args()
|
|
if args.pin:
|
|
PIN=args.pin
|
|
else:
|
|
PIN=os.environ.get('BS21_PIN')
|
|
if not PIN:
|
|
PIN=raw_input("Enter the PIN: ").strip()
|
|
if args.device:
|
|
#TODO: check for existence
|
|
DEV=args.device
|
|
else:
|
|
DEV=os.environ.get('BS21_DEV')
|
|
if not DEV:
|
|
#TODO: search for resonable device /dev/tty.BS....
|
|
DEV="/dev/tty.BS-21-00NNNN-0-A-SPPDev"
|
|
if args.verbose:
|
|
verbosity=True
|
|
print "calling BS21 with device=%s and PIN=%s" % (DEV, PIN)
|
|
sw=BS21(DEV, PIN)
|
|
sw.command(' '.join(args.command))
|
|
|
|
|