def _set_mv_led(self, pos, freq): """ Set the leds on board according to pos array, used by `show_deltas`. """ if self.connected is True: leds = [[0 for x in range(9)] for y in range(9)] cmd = "L" + clp.hex2(freq) for y in range(8): for x in range(8): if pos[y][x] != 0: if self.orientation == True: leds[7 - x][y] |= pos[y][x] leds[7 - x + 1][y] |= pos[y][x] leds[7 - x][y + 1] |= pos[y][x] leds[7 - x + 1][y + 1] |= pos[y][x] else: leds[x][7 - y] |= pos[y][x] leds[x + 1][7 - y] |= pos[y][x] leds[x][7 - y + 1] |= pos[y][x] leds[x + 1][7 - y + 1] |= pos[y][x] for y in range(9): for x in range(9): cmd = cmd + clp.hex2(leds[y][x]) self.trans.write_mt(cmd) else: self.log.warning("Not connected to Chess Link.")
def set_scan_time_ms(self, scan_ms=41): """ Set the scan time value. Lower scan times make the board less susceptible to random unexpected events and can be used together with `set_debounce()` to prevent random fluke events. :param scan_ms: 30.72(fastest)-522.24(slowest), scan time in ms. A value around 100ms is recommended, board default is 41ms. """ if self.connected is True: cmd = "W01" if scan_ms < 2.048 * 15.0 or scan_ms > 255.0 * 2.048: self.log.error( 'Invalid scan_ms {}, shouldbe between 30.72(fastest, might not work)..522.24(slowest, about 2 scans per sec))' .format(scan_ms)) else: iscans = int(scan_ms / 2.048) if iscans < 15: iscans = 15 if iscans > 255: iscans = 255 cmd += clp.hex2(iscans) self.trans.write_mt(cmd) self.log.debug( "Setting scan_ms intervall to {} -> {}ms ({} scans per sec)" .format(iscans, scan_ms, 1000.0 / scan_ms)) else: self.log.warning("Not connected to Chess Link.")
def get_led_brightness_percent(self): """ Asynchronuosly request the current led brightness setting. The answer will be written to the queue `appqueue` given during initialization. See see `magic-link.md <https://github.com/domschl/python-mchess/blob/master/mchess/magic-board.md>`_. """ if self.connected is True: cmd = "R" + clp.hex2(4) self.trans.write_mt(cmd) else: self.log.warning("Not connected to Chess Link.")
def set_led(self, pos, freq, ontime1, ontime2): """ Static blinking leds according to `position`. :param pos: `position` array, field != 0 indicates a led that should blink. :param freq: blink frequency, see `magic-link.md <https://github.com/domschl/python-mchess/blob/master/mchess/magic-board.md>`_. :param ontime1: 8-bit value, bits indicate cycles led is on. :param ontime2: 8-bit value, bits indicate cycles led is off. """ if self.connected is True: leds = [[0 for x in range(9)] for y in range(9)] cmd = "L"+clp.hex2(freq) for y in range(8): for x in range(8): if pos[y][x] != 0: if self.orientation == True: leds[7-x][y] = pos[y][x] leds[7-x+1][y] = pos[y][x] leds[7-x][y+1] = pos[y][x] leds[7-x+1][y+1] = pos[y][x] else: leds[x][7-y] = pos[y][x] leds[x+1][7-y] = pos[y][x] leds[x][7-y+1] = pos[y][x] leds[x+1][7-y+1] = pos[y][x] for y in range(9): for x in range(9): if leds[y][x] == 0: cmd = cmd + "00" elif leds[y][x] == 1: cmd = cmd + clp.hex2(ontime1) else: cmd = cmd + clp.hex2(ontime2) self.trans.write_mt(cmd) else: self.log.warning( "Not connected to Chess Link.")
def set_led_brightness(self, level=1.0): """ Set the led brighness. :param level: 0.0 - 1.0: 0(darkest) up to 1.0(brightest). """ if self.connected is True: cmd = "W04" if level < 0.0 or level > 1.0: self.log.error(f'Invalid brightness level {level}, "\ "should be between 0(darkest)..1.0(brightest)') else: ilevel = int(level * 15) cmd += clp.hex2(ilevel) self.trans.write_mt(cmd) self.log.debug( f"Setting led brightness to {ilevel} (bri={level})") else: self.log.warning("Not connected to Chess Link.")
def set_debounce(self, count): """ Set the debounce-value. Debouncing helps to prevent random fluke events. Should be tested together with different `set_scan_time_ms()` values. :param count: 0-4, 0: no debounce, 1-4: 1-4 scan times debounce. """ if self.connected is True: cmd = "W02" if count < 0 or count > 4: self.log.error(f'Invalid debounce count {count}, "\ "should be 0: no debounce, 1 .. 4: 1-4 scan times debounce' ) else: # 3: no debounce, 4: 2 scans debounce, -> 7: 4 scans cmd += clp.hex2(count + 3) self.trans.write_mt(cmd) self.log.debug(f"Setting board scan debounce to {count}") else: self.log.warning("Not connected to Chess Link.")
def worker_thread(self, log, address, wrque, que): """ Background thread that handles bluetooth sending and forwards data received via bluetooth to the queue `que`. """ mil = None message_delta_time = 0.1 # least 0.1 sec between outgoing btle messages rx = None tx = None log.debug("bluepy_ble open_mt {}".format(address)) # time.sleep(0.1) try: log.debug("per1") mil = Peripheral(address) log.debug("per2") except Exception as e: log.debug("per3") emsg = 'Failed to create BLE peripheral at {}, {}'.format( address, e) log.error(emsg) self.agent_state(que, 'offline', '{}'.format(e)) self.conn_state = False return rx, tx = self.mil_open(address, mil, que, log) time_last_out = time.time()+0.2 if rx is None or tx is None: bt_error = True self.conn_state = False else: bt_error = False self.conn_state = True while self.worker_thread_active is True: rep_err = False while bt_error is True: time.sleep(1) bt_error = False self.init = False try: mil.connect(address) except Exception as e: if rep_err is False: self.log.warning( "Reconnect failed: {} [Local bluetooth problem?]".format(e)) rep_err = True bt_error = True if bt_error is False: self.log.info( "Bluetooth reconnected to {}".format(address)) rx, tx = self.mil_open(address, mil, que, log) time_last_out = time.time()+0.2 self.init = True if wrque.empty() is False and time.time()-time_last_out > message_delta_time: msg = wrque.get() gpar = 0 for b in msg: gpar = gpar ^ ord(b) msg = msg+clp.hex2(gpar) if self.protocol_debug is True: log.debug("blue_ble write: <{}>".format(msg)) bts = "" for c in msg: bo = chr(clp.add_odd_par(c)) bts += bo btsx = bts.encode('latin1') if self.protocol_debug is True: log.debug("Sending: <{}>".format(btsx)) try: tx.write(btsx, withResponse=True) time_last_out = time.time() except Exception as e: log.error( "bluepy_ble: failed to write {}: {}".format(msg, e)) bt_error = True self.agent_state( que, 'offline', 'Connected to Bluetooth peripheral lost: {}'.format(e)) wrque.task_done() try: rx.read() mil.waitForNotifications(0.05) # time.sleep(0.1) except Exception as e: self.log.warning("Bluetooth error {}".format(e)) bt_error = True self.agent_state( que, 'offline', 'Connected to Bluetooth peripheral lost: {}'.format(e)) continue log.debug('wt-end')