cli_bt.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #!/usr/bin/env python3
  2. import threading
  3. import serial
  4. import queue
  5. from xmodem import XMODEM
  6. import io
  7. from bleak import BleakClient
  8. import platform
  9. import asyncio
  10. import wx
  11. mac_addr = (
  12. "80:1F:12:B7:86:93"
  13. if platform.system() != "Darwin"
  14. else "B9EA5233-37EF-4DD6-87A8-2A875E821C46"
  15. )
  16. def notification_handler(sender, data):
  17. print(', '.join('{:02x}'.format(x) for x in data))
  18. async def connect(mac_addr: str):
  19. CHARACTERISTIC_UUID = "49535343-1E4D-4BD9-BA61-23C647249616"
  20. async with BleakClient(mac_addr) as client:
  21. x = await client.is_connected()
  22. print( "Connected: {0}".format(x))
  23. print(client)
  24. await client.write_gatt_char(CHARACTERISTIC_UUID, b'\n')
  25. await client.start_notify(CHARACTERISTIC_UUID, notification_handler)
  26. return client
  27. async def write(client, cmd):
  28. CHARACTERISTIC_UUID = "49535343-1E4D-4BD9-BA61-23C647249616"
  29. print('cmd ' + str(cmd))
  30. print(client)
  31. await client.write_gatt_char(CHARACTERISTIC_UUID, cmd)
  32. class CliThread(threading.Thread):
  33. def __init__(self, parent):
  34. threading.Thread.__init__(self)
  35. self.alive = threading.Event()
  36. self.q = queue.Queue(100)
  37. # self.nodeSerial = serial.Serial(port=port, baudrate=9600)
  38. print('bleaaak')
  39. self.client = asyncio.run(connect(mac_addr))
  40. asyncio.run(write(self.client, b'\n'))
  41. self.alive.set()
  42. def close(self):
  43. self.alive.clear()
  44. self.nodeSerial.close()
  45. def command(self, cmd, response):
  46. asyncio.run(write(self.client, cmd))
  47. self.q.put(response)
  48. #self.nodeSerial.write(cmd)
  49. def getc(self, size, timeout=1):
  50. return self.nodeSerial.read(size) or None
  51. def putc(self,data, timeout=1):
  52. return self.nodeSerial.write(data) # note that this ignores the timeout
  53. def xmodem(self, lines):
  54. self.xmodemlines = lines
  55. self.q.put(None)
  56. self.nodeSerial.write(b'xmodem\n')
  57. def run(self):
  58. """\
  59. Thread that handles the incoming traffic. Does the basic input
  60. transformation (newlines) and generates an SerialRxEvent
  61. """
  62. b = ''
  63. cmd = []
  64. lines = ''
  65. while self.alive.isSet():
  66. #for c in self.nodeSerial.read():
  67. #with await client.read_gatt_char(CHARACTERISTIC_UUID) as c:
  68. c = chr(c)
  69. print(c, end='')
  70. b += c
  71. if b[0:3] == 'ch>':
  72. if (len(cmd) > 0):
  73. callback = self.q.get(block=False)
  74. if callback != None:
  75. wx.CallAfter(callback, lines)
  76. lines = []
  77. if cmd[0] == 'list':
  78. # wx.CallAfter(self.scriptUpdate, lines)
  79. lines = []
  80. if cmd[0] == 'fget':
  81. #wx.CallAfter(self.dataUpdate, lines)
  82. lines = []
  83. if cmd[0] == 'info':
  84. #wx.CallAfter(self.parent.m_staticTextNode.SetLabel, "".join(lines))
  85. lines = []
  86. # if cmd[0] == 'sget':
  87. # wx.CallAfter(self.m_staticTextBattery.SetLabel, "Battery: " + lines[0][6:-2] + " mV")
  88. # lines = []
  89. if cmd[0] == 'finfo':
  90. # wx.CallAfter(self.m_staticTextFlash.SetLabel, "".join(lines))
  91. lines = []
  92. if cmd[0] == 'date':
  93. # wx.CallAfter(self.m_staticTextDatetime.SetLabel, "Datetime: " + lines[0])
  94. lines = []
  95. if cmd[0] == 'sdi12':
  96. # if cmd[1] == '?!':
  97. # wx.CallAfter(self.m_textCtrlSDI12Adress.SetLabel, lines[0].split(' ')[2].replace('\r','').replace('\n',''))
  98. # if cmd[1][1:] == 'I!':
  99. # wx.CallAfter(self.m_textCtrlSDI12Identification.SetValue, lines[0][7:])
  100. # wx.CallAfter(self.m_textCtrlSDI12CommandResult.SetValue, lines[0].split(':')[1][1:])
  101. lines = []
  102. if cmd[0] == 'sget':
  103. #wx.CallAfter(self.m_staticTextValue.SetLabel, lines[0].split(':')[1][1:])
  104. wx.CallAfter(self.m_textCtrlSensorValue.SetValue,
  105. lines[0].split(':')[1][1:] + ' ' +
  106. self.json_data['sensors'][self.m_comboBoxSensor.GetSelection()]['types'][self.m_comboBoxType.GetSelection()]['unit'])
  107. lines = []
  108. if cmd[0] == 'owsearch':
  109. for line in lines:
  110. #wx.CallAfter(self.m_listBox1wire.Append, line.split(' ')[0])
  111. wx.CallAfter(self.m_listBox1wire.Append, line)
  112. # wx.CallAfter(self.m_listCtrl1wire.InsertItem, 0, line.split(' ')[1].replace('\r', '').replace('\n',''))
  113. lines = []
  114. cmd = []
  115. if c == '\n':
  116. if len(cmd) > 0:
  117. lines.append(b)
  118. if b[0:3] == 'ch>':
  119. b = b.replace('\r', '').replace('\n','')
  120. cmd = b.split(' ')[1:]
  121. lines = []
  122. if len(cmd) > 0:
  123. if cmd[0] == 'xmodem':
  124. modem = XMODEM(self.getc, self.putc)
  125. stream = io.BytesIO(bytes(''.join(self.xmodemlines), 'utf-8'))
  126. #stream = io.BytesIO(b"hhh")
  127. #stream = io.StringIO("gfbgjfg")
  128. #stream = open('script_test.bas', 'rb')
  129. modem.send(stream)
  130. b = ''
  131. #b = self.nodeSerial.read(self.nodeSerial.in_waiting or 1)
  132. #if b:
  133. # newline transformation
  134. #if self.settings.newline == NEWLINE_CR:
  135. # b = b.replace(b'\r', b'\n')
  136. #elif self.settings.newline == NEWLINE_LF:
  137. # pass
  138. #elif self.settings.newline == NEWLINE_CRLF:
  139. # b = b.replace(b'\r\n', b'\n')
  140. #event = SerialRxEvent(self.GetId(), b)
  141. #self.GetEventHandler().AddPendingEvent(event)
  142. # self.logComm.write(b);