123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- #!/usr/bin/env python3
-
- # ----------------------------------------------------------------------------
- # Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # See <http://www.gnu.org/licenses/>.
- # ----------------------------------------------------------------------------
-
- import uasyncio as asyncio
- from scan import ble_scan
- import time
-
- class StateScan:
- def __init__(self, lcd):
- self.lcd = lcd
-
- self.lock = asyncio.Lock()
-
- def enter(self, val = None):
- n = None
- self.results = []
- self.current = None
- self.menuOff = 0
- self.scanner = asyncio.create_task(self.scan())
-
- def exit(self):
- self.scanner.cancel()
-
- if self.lock.locked():
- self.lock.release()
-
- self.lcd.store_brightness()
-
- return self.results[self.current][4]
-
- async def scan(self):
- while True:
- new = await ble_scan(None, None, 0.25)
-
- for n in new:
- name = n.name()
- mac = n.device.addr_hex()
- rssi = n.rssi
- value = [name, mac, rssi, time.time(), n]
-
- async with self.lock:
- found = False
- for i in range(0, len(self.results)):
- if self.results[i][1] == mac:
- found = True
- self.results[i][0] = name
- self.results[i][2] = rssi
- self.results[i][3] = time.time()
- self.results[i][4] = n
- break
-
- if found == False:
- self.results.append(value)
-
- def draw_list(self):
- if len(self.results) <= 0:
- self.lcd.textC("No devices found yet", int(self.lcd.width / 2), int(self.lcd.height / 2), self.lcd.white)
- return
-
- for i, d in enumerate(self.results):
- if i < self.menuOff:
- continue
-
- off = (i - self.menuOff) * 25 + 30
- if off >= (self.lcd.height - 10):
- break
-
- selection = " "
- if self.current == i:
- selection = "->"
- name, mac, rssi, timeout, device = self.results[i]
- age = int(time.time() - timeout)
- s1 = "{}: {}".format(i + 1, name)
- s2 = "{} [{}] {} {}".format(selection, mac, rssi, age)
-
- c1 = self.lcd.white
- if name == "S&B VOLCANO H":
- c1 = self.lcd.green
- if self.current == None:
- self.current = i
- elif name == "STORZ&BICKEL":
- c1 = self.lcd.yellow
- elif self.current == i:
- c1 = self.lcd.red
- c2 = self.lcd.white
- if self.current == i:
- c2 = self.lcd.red
-
- self.lcd.hline(0, off - 3, self.lcd.width, self.lcd.blue)
- self.lcd.text(s1, 0, off + 2, c1)
- self.lcd.text(s2, 0, off + 12, c2)
-
- async def draw(self):
- self.lcd.text("Scanning for Bluetooth devices", 0, 10, self.lcd.red)
-
- keys = self.lcd.buttons()
-
- async with self.lock:
- if keys.once("enter") or keys.once("a"):
- if self.current < len(self.results):
- return 2
- elif keys.once("up"):
- if self.current == None:
- self.current = len(self.results) - 1
- else:
- self.current -= 1
- elif keys.once("down"):
- if self.current == None:
- self.current = 0
- else:
- self.current += 1
- elif keys.once("x"):
- return 10
- elif keys.held("left"):
- v = self.lcd.curr_brightness - 0.05
- if v < 0.05:
- v = 0.05
- self.lcd.brightness(v)
- elif keys.held("right"):
- self.lcd.brightness(self.lcd.curr_brightness + 0.05)
- elif keys.once("y"):
- return 0
-
- if self.current != None:
- while self.current < 0:
- self.current += len(self.results)
- while self.current >= len(self.results):
- self.current -= len(self.results)
- while self.current < self.menuOff:
- self.menuOff -= 1
- while self.current >= (self.menuOff + int((self.lcd.height - 30 - 10) / 25)):
- self.menuOff += 1
-
- # remove entries after timeout
- self.results = [x for x in self.results if (time.time() - x[3]) < 10.0]
-
- # filter out incompatible devices
- self.results = [x for x in self.results if (x[0] != None) and (("S&B" in x[0]) or ("STORZ&BICKEL" == x[0]))]
-
- if self.current != None:
- if self.current >= len(self.results):
- self.current = len(self.results) - 1
-
- self.draw_list()
-
- w = int(self.lcd.width * self.lcd.curr_brightness)
- self.lcd.hline(0, 24, w, self.lcd.white)
-
- return -1
|