parent
856a226b6f
commit
f9c0cbfd0e
|
@ -2,29 +2,61 @@
|
||||||
|
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
import pygatt
|
import pygatt
|
||||||
|
from .base import BaseLink, LinkTimeoutException, LinkOpenException
|
||||||
from binascii import hexlify
|
from binascii import hexlify
|
||||||
|
|
||||||
|
SCAN_TIMEOUT = 3
|
||||||
|
|
||||||
|
|
||||||
|
import queue
|
||||||
|
|
||||||
|
class Fifo():
|
||||||
|
def __init__(self):
|
||||||
|
self.q = queue.Queue()
|
||||||
|
|
||||||
|
def write(self, data): # put bytes
|
||||||
|
for b in data:
|
||||||
|
self.q.put(b)
|
||||||
|
|
||||||
|
def read(self, size=1, timeout=None): # but read string
|
||||||
|
res = ""
|
||||||
|
for i in xrange(size):
|
||||||
|
res += chr(self.q.get(True, timeout))
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
SCAN_TIMEOUT = 3
|
#_cccd_uuid = "00002902-0000-1000-8000-00805f9b34fb"
|
||||||
|
_rx_char_uuid = "6e400002-b5a3-f393-e0a9-e50e24dcca9e"
|
||||||
|
_tx_char_uuid = "6e400003-b5a3-f393-e0a9-e50e24dcca9e"
|
||||||
|
|
||||||
class BLELink():
|
class BLELink(BaseLink):
|
||||||
def __init__(self, dump=False):
|
def __init__(self, *args, **kwargs):
|
||||||
self.dev = None
|
super(BLELink, self).__init__(*args, **kwargs)
|
||||||
self.dump = dump
|
self._adapter = None
|
||||||
|
self._dev = None
|
||||||
|
self._wr_handle = None
|
||||||
|
self._rx_fifo = Fifo()
|
||||||
|
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
self.adapter = pygatt.BGAPIBackend()
|
self._adapter = pygatt.BGAPIBackend()
|
||||||
self.adapter.start()
|
self._adapter.start()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
def __exit__(self, exc_type, exc_value, traceback):
|
def __exit__(self, exc_type, exc_value, traceback):
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
|
|
||||||
|
def _make_rx_cb(self): # this is a closure :)
|
||||||
|
def rx_cb(handle, value):
|
||||||
|
self._rx_fifo.write(value)
|
||||||
|
return rx_cb
|
||||||
|
|
||||||
|
|
||||||
def scan(self):
|
def scan(self):
|
||||||
res = []
|
res = []
|
||||||
devices = self.adapter.scan(timeout=SCAN_TIMEOUT)
|
devices = self._adapter.scan(timeout=SCAN_TIMEOUT)
|
||||||
for dev in devices:
|
for dev in devices:
|
||||||
if dev["name"].startswith(u"MISc"):
|
if dev["name"].startswith(u"MISc"):
|
||||||
res.append((dev["name"], dev["address"]))
|
res.append((dev["name"], dev["address"]))
|
||||||
|
@ -32,18 +64,27 @@ class BLELink():
|
||||||
|
|
||||||
|
|
||||||
def open(self, port):
|
def open(self, port):
|
||||||
self.dev = self.adapter.connect(port, address_type=pygatt.BLEAddressType.random)
|
try:
|
||||||
|
self._dev = self._adapter.connect(port, address_type=pygatt.BLEAddressType.random)
|
||||||
|
self._dev.subscribe(_tx_char_uuid, callback=self._make_rx_cb())
|
||||||
|
self._wr_handle = self._dev.get_handle(_rx_char_uuid)
|
||||||
|
except pygatt.exceptions.NotConnectedError:
|
||||||
|
raise LinkOpenException
|
||||||
|
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
if self.dev:
|
if self._dev:
|
||||||
self.dev.disconnect()
|
self._dev.disconnect()
|
||||||
self.dev = None
|
self._dev = None
|
||||||
self.adapter.stop()
|
if self._adapter:
|
||||||
|
self._adapter.stop()
|
||||||
|
|
||||||
|
|
||||||
def read(self, size):
|
def read(self, size):
|
||||||
data = self.dev.read(size)
|
try:
|
||||||
|
data = self._rx_fifo.read(size, timeout=self.timeout)
|
||||||
|
except queue.Empty:
|
||||||
|
raise LinkTimeoutException
|
||||||
if self.dump:
|
if self.dump:
|
||||||
print "<", hexlify(data).upper()
|
print "<", hexlify(data).upper()
|
||||||
return data
|
return data
|
||||||
|
@ -52,7 +93,7 @@ class BLELink():
|
||||||
def write(self, data):
|
def write(self, data):
|
||||||
if self.dump:
|
if self.dump:
|
||||||
print ">", hexlify(data).upper()
|
print ">", hexlify(data).upper()
|
||||||
return self.dev.write(data)
|
self._dev.char_write_handle(self._wr_handle, bytearray(data))
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["BLELink"]
|
__all__ = ["BLELink"]
|
||||||
|
|
|
@ -7,7 +7,7 @@ from binascii import hexlify
|
||||||
from .base import BaseLink, LinkTimeoutException, LinkOpenException
|
from .base import BaseLink, LinkTimeoutException, LinkOpenException
|
||||||
|
|
||||||
|
|
||||||
class SerialLink():
|
class SerialLink(BaseLink):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(SerialLink, self).__init__(*args, **kwargs)
|
super(SerialLink, self).__init__(*args, **kwargs)
|
||||||
self.com = None
|
self.com = None
|
||||||
|
|
|
@ -5,28 +5,34 @@ from .packet import BasePacket
|
||||||
|
|
||||||
|
|
||||||
class XiaomiTransport(BT):
|
class XiaomiTransport(BT):
|
||||||
HEAD2ESC = 0x20
|
MASTER2ESC = 0x20
|
||||||
ESC2HEAD = 0x23
|
ESC2MASTER = 0x23
|
||||||
HEAD2BMS = 0x22
|
|
||||||
BMS2HEAD = 0x25
|
|
||||||
DEV01 = 0x01
|
|
||||||
|
|
||||||
_SaDa2Addr = { BT.HOST : { BT.DEV01 : DEV01, BT.ESC : HEAD2ESC, BT.BMS : HEAD2BMS },
|
MASTER2BLE = 0x21
|
||||||
BT.ESC : { BT.HOST : ESC2HEAD, BT.BMS : HEAD2BMS, BT.DEV01 : DEV01 },
|
BLE2MASTER = 0x24
|
||||||
BT.BMS : { BT.HOST : BMS2HEAD, BT.ESC : BMS2HEAD, BT.DEV01 : DEV01 },
|
|
||||||
|
MASTER2BMS = 0x22
|
||||||
|
BMS2MASTER = 0x25
|
||||||
|
|
||||||
|
DEV01 = 0x01
|
||||||
|
DEVFF = 0xFF
|
||||||
|
|
||||||
|
_SaDa2Addr = { BT.HOST : { BT.DEV01 : DEV01, BT.ESC : MASTER2ESC, BT.BLE : MASTER2BLE, BT.BMS : MASTER2BMS },
|
||||||
|
BT.ESC : { BT.HOST : ESC2MASTER, BT.BLE : MASTER2BLE, BT.BMS : MASTER2BMS, BT.DEV01 : DEV01 },
|
||||||
|
BT.BMS : { BT.HOST : BMS2MASTER, BT.ESC : BMS2MASTER, BT.DEV01 : DEV01 },
|
||||||
BT.DEV01 : {BT.HOST : DEV01, BT.ESC : DEV01, BT.BMS : DEV01 } }
|
BT.DEV01 : {BT.HOST : DEV01, BT.ESC : DEV01, BT.BMS : DEV01 } }
|
||||||
|
|
||||||
# TBC
|
# TBC
|
||||||
_BleAddr2SaDa = { HEAD2ESC : (BT.HOST, BT.ESC),
|
_BleAddr2SaDa = { MASTER2ESC : (BT.HOST, BT.ESC),
|
||||||
ESC2HEAD : (BT.ESC, BT.HOST),
|
ESC2MASTER : (BT.ESC, BT.HOST),
|
||||||
HEAD2BMS : (BT.HOST, BT.BMS),
|
MASTER2BMS : (BT.HOST, BT.BMS),
|
||||||
BMS2HEAD : (BT.BMS, BT.HOST),
|
BMS2MASTER : (BT.BMS, BT.HOST),
|
||||||
DEV01 : (BT.DEV01, BT.HOST) }
|
DEV01 : (BT.DEV01, BT.HOST) }
|
||||||
|
|
||||||
_BmsAddr2SaDa = { HEAD2ESC : (BT.BMS, BT.ESC),
|
_BmsAddr2SaDa = { MASTER2ESC : (BT.BMS, BT.ESC),
|
||||||
ESC2HEAD : (BT.ESC, BT.BMS),
|
ESC2MASTER : (BT.ESC, BT.BMS),
|
||||||
HEAD2BMS : (BT.ESC, BT.BMS),
|
MASTER2BMS : (BT.ESC, BT.BMS),
|
||||||
BMS2HEAD : (BT.BMS, BT.ESC),
|
BMS2MASTER : (BT.BMS, BT.ESC),
|
||||||
DEV01 : (BT.DEV01, BT.BMS) }
|
DEV01 : (BT.DEV01, BT.BMS) }
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
from py9b.link.base import LinkOpenException, LinkTimeoutException
|
||||||
|
from py9b.link.tcp import TCPLink
|
||||||
|
from py9b.link.ble import BLELink
|
||||||
|
from py9b.transport.base import BaseTransport as BT
|
||||||
|
from py9b.transport.packet import BasePacket as PKT
|
||||||
|
from py9b.transport.xiaomi import XiaomiTransport
|
||||||
|
|
||||||
|
READ_CHUNK_SIZE = 0x40
|
||||||
|
|
||||||
|
#link = SerialLink()
|
||||||
|
#link = TCPLink()
|
||||||
|
link = BLELink()
|
||||||
|
|
||||||
|
with link:
|
||||||
|
print "Scanning..."
|
||||||
|
ports = link.scan()
|
||||||
|
print ports
|
||||||
|
|
||||||
|
tran = XiaomiTransport(link)
|
||||||
|
|
||||||
|
#link.open(("192.168.1.45", 6000))
|
||||||
|
link.open(ports[0][1])
|
||||||
|
print "Connected"
|
||||||
|
|
||||||
|
req = PKT(src=BT.HOST, dst=BT.ESC, cmd=0x01, reg=0, data=chr(READ_CHUNK_SIZE))
|
||||||
|
|
||||||
|
hfo = open("EscRegs.bin", "wb")
|
||||||
|
for i in xrange(0, 0x200, READ_CHUNK_SIZE):
|
||||||
|
print ".",
|
||||||
|
req.reg = i>>1
|
||||||
|
for retry in xrange(3):
|
||||||
|
tran.send(req)
|
||||||
|
try:
|
||||||
|
rsp = tran.recv()
|
||||||
|
except LinkTimeoutException:
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
hfo.write(rsp.data)
|
||||||
|
|
||||||
|
hfo.close()
|
||||||
|
link.close()
|
Loading…
Reference in New Issue