def start_internal(self, color, log=True): """Start the internal clock.""" if not self.internal_running(): if self.mode in (TimeMode.BLITZ, TimeMode.FISCHER): self.active_color = color self.reset_start_time() if log: w_hms, b_hms = self._log_time() logging.info('start internal time w:%s - b:%s [ign]', w_hms, b_hms) logging.info('received clock time w:%s - b:%s [use]', hms_time(self.clock_time[chess.WHITE]), hms_time(self.clock_time[chess.BLACK])) self.internal_time[chess.WHITE] = self.clock_time[chess.WHITE] self.internal_time[chess.BLACK] = self.clock_time[chess.BLACK] # Only start thread if not already started for same color, and the player has not already lost on time if self.internal_time[ color] > 0 and self.active_color is not None and self.run_color != self.active_color: self.timer = threading.Timer( copy.copy(self.internal_time[color]), self._out_of_time, [copy.copy(self.internal_time[color])]) self.timer.start() logging.debug( 'internal timer started - color: %s run: %s active: %s', color, self.run_color, self.active_color) self.run_color = self.active_color
def start_clock(self, side: ClockSide, devs: set): """Start the dgtpi.""" if self.get_name() not in devs: logging.debug('ignored startClock - devs: %s', devs) return True l_hms = hms_time(self.l_time) r_hms = hms_time(self.r_time) logging.debug('(%s) clock sending start time to clock l:%s r:%s', ','.join(devs), l_hms, r_hms) l_run = r_run = 0 if side == ClockSide.LEFT: l_run = 1 if side == ClockSide.RIGHT: r_run = 1 with self.lib_lock: res = self.lib.dgtpicom_set_and_run(l_run, l_hms[0], l_hms[1], l_hms[2], r_run, r_hms[0], r_hms[1], r_hms[2]) if res < 0: logging.warning( 'SetAndRun() returned error %i, running configure', res) self._run_configure() res = self.lib.dgtpicom_set_and_run(l_run, l_hms[0], l_hms[1], l_hms[2], r_run, r_hms[0], r_hms[1], r_hms[2]) if res < 0: logging.warning('finally failed %i', res) return False else: self.side_running = side Timer(0.9, self.out_settime).start( ) # delay abit cause the clock needs time to update its time result return True
def _resume_clock(self, side: ClockSide): if self.dgtboard.l_time >= 3600 * 10 or self.dgtboard.r_time >= 3600 * 10: logging.debug('time values not set - abort function') return False l_run = r_run = 0 if side == ClockSide.LEFT: l_run = 1 if side == ClockSide.RIGHT: r_run = 1 with self.lib_lock: l_hms = hms_time(self.dgtboard.l_time) r_hms = hms_time(self.dgtboard.r_time) res = self.dgtboard.set_and_run(l_run, l_hms[0], l_hms[1], l_hms[2], r_run, r_hms[0], r_hms[1], r_hms[2]) if not res: logging.warning('finally failed %i', res) return False else: self.side_running = side if not self.dgtboard.disable_end: res = self.dgtboard.end_text( ) # this is needed for some(!) clocks self.dgtboard.in_settime = False # @todo should be set on ACK (see: DgtBoard) not here return res
def start_clock(self, side: ClockSide, devs: set): """Start the dgtpi.""" if self.get_name() not in devs: logging.debug('ignored startClock - devs: %s', devs) return True l_hms = hms_time(self.l_time) r_hms = hms_time(self.r_time) logging.debug('(%s) clock sending start time to clock l:%s r:%s', ','.join(devs), l_hms, r_hms) l_run = r_run = 0 if side == ClockSide.LEFT: l_run = 1 if side == ClockSide.RIGHT: r_run = 1 with self.lib_lock: res = self.lib.dgtpicom_set_and_run(l_run, l_hms[0], l_hms[1], l_hms[2], r_run, r_hms[0], r_hms[1], r_hms[2]) if res < 0: logging.warning('SetAndRun() returned error %i', res) self._run_configure() res = self.lib.dgtpicom_set_and_run(l_run, l_hms[0], l_hms[1], l_hms[2], r_run, r_hms[0], r_hms[1], r_hms[2]) if res < 0: logging.warning('finally failed %i', res) return False else: self.side_running = side self.in_settime = False return True
def stop_clock(self, devs: set): """Stop the dgtpi.""" if self.get_name() not in devs: logging.debug('ignored stopClock - devs: %s', devs) return True logging.debug('(%s) clock sending stop time to clock l:%s r:%s', ','.join(devs), hms_time(self.l_time), hms_time(self.r_time)) return self._resume_clock(ClockSide.NONE)
def start_clock(self, side: ClockSide, devs: set): """Start the dgtxl/3k.""" if self.get_name() not in devs: logging.debug('ignored startClock - devs: %s', devs) return True logging.debug('(%s) clock sending start time to clock l:%s r:%s', ','.join(devs), hms_time(self.dgtboard.l_time), hms_time(self.dgtboard.r_time)) return self._resume_clock(side)
def set_clock(self, time_left: int, time_right: int, devs: set): """Start the dgtxl/3k.""" if self.get_name() not in devs: logging.debug('ignored setClock - devs: %s', devs) return True logging.debug('(%s) clock received last time from clock l:%s r:%s', ','.join(devs), hms_time(self.dgtboard.l_time), hms_time(self.dgtboard.r_time)) logging.debug('(%s) clock sending set time to clock l:%s r:%s', ','.join(devs), hms_time(time_left), hms_time(time_right)) self.dgtboard.in_settime = True # it will return to false as soon SetAndRun ack received self.dgtboard.l_time = time_left self.dgtboard.r_time = time_right return True
def set_clock(self, time_left: int, time_right: int, devs: set): """Set the dgtpi.""" if self.get_name() not in devs: logging.debug('ignored setClock - devs: %s', devs) return True l_hms = hms_time(time_left) r_hms = hms_time(time_right) logging.debug('(%s) clock received last time from clock l:%s r:%s', ','.join(devs), hms_time(self.l_time), hms_time(self.r_time)) logging.debug('(%s) clock sending set time to clock l:%s r:%s', ','.join(devs), l_hms, r_hms) self.in_settime = True self.l_time = time_left self.r_time = time_right return True
def _display_time(self, time_left: int, time_right: int): if time_left >= 3600 * 10 or time_right >= 3600 * 10: logging.debug('time values not set - abort function') elif self.clock_show_time: l_hms = hms_time(time_left) r_hms = hms_time(time_right) text_l = '{}:{:02d}.{:02d}'.format(l_hms[0], l_hms[1], l_hms[2]) text_r = '{}:{:02d}.{:02d}'.format(r_hms[0], r_hms[1], r_hms[2]) icon_d = 'fa-caret-right' if self.side_running == ClockSide.RIGHT else 'fa-caret-left' if self.side_running == ClockSide.NONE: icon_d = 'fa-sort' text = text_l + ' <i class="fa ' + icon_d + '"></i> ' + text_r self._create_clock_text() self.shared['clock_text'] = text result = {'event': 'Clock', 'msg': text} EventHandler.write_to_clients(result)
def set_clock(self, time_left: int, time_right: int, devs: set): """Set the dgtpi.""" if self.get_name() not in devs: logging.debug('ignored setClock - devs: %s', devs) return True l_hms = hms_time(time_left) r_hms = hms_time(time_right) logging.debug('(%s) clock received last time from clock l:%s r:%s [ign]', ','.join(devs), hms_time(self.l_time), hms_time(self.r_time)) logging.debug('(%s) clock sending set time to clock l:%s r:%s [use]', ','.join(devs), l_hms, r_hms) self.in_settime = True self.l_time = time_left self.r_time = time_right return True
def start_internal(self, color, log=True): """Start the internal clock.""" if not self.internal_running(): if self.mode in (TimeMode.BLITZ, TimeMode.FISCHER): self.active_color = color self.reset_start_time() if log: w_hms, b_hms = self._log_time() logging.info('start internal time w:%s - b:%s [ign]', w_hms, b_hms) logging.info('received clock time w:%s - b:%s [use]', hms_time(self.clock_time[chess.WHITE]), hms_time(self.clock_time[chess.BLACK])) w_dir, b_dir = self.get_internal_time(flip_board=False) ## molli Avoid strange reset bug to 0 if w_dir != self.clock_time[chess.WHITE] and ( self.clock_time[chess.WHITE] == 0 or self.clock_time[chess.WHITE] == self.fisch_inc): logging.debug('molli: Difference in white clock time!') ##self.internal_time[chess.WHITE] = w_dir self.clock_time[chess.WHITE] = w_dir else: self.internal_time[chess.WHITE] = self.clock_time[chess.WHITE] ## molli Avoid strange reset bug to 0 if b_dir != self.clock_time[chess.BLACK] and ( self.clock_time[chess.BLACK] == 0 or self.clock_time[chess.BLACK] == self.fisch_inc): logging.debug('molli: Difference in black clock time!') ##self.internal_time[chess.BLACK] = b_dir self.clock_time[chess.BLACK] = b_dir else: self.internal_time[chess.BLACK] = self.clock_time[chess.BLACK] # Only start thread if not already started for same color, and the player has not already lost on time if self.internal_time[ color] > 0 and self.active_color is not None and self.run_color != self.active_color: self.timer = threading.Timer( copy.copy(self.internal_time[color]), self._out_of_time, [copy.copy(self.internal_time[color])]) self.timer.start() logging.debug( 'internal timer started - color: %s run: %s active: %s', color, self.run_color, self.active_color) self.run_color = self.active_color
def _runclock(self): if self.side_running == ClockSide.LEFT: time_left = self.l_time - 1 if time_left <= 0: logging.info('negative/zero time left: %s', time_left) self.virtual_timer.stop() time_left = 0 self.l_time = time_left if self.side_running == ClockSide.RIGHT: time_right = self.r_time - 1 if time_right <= 0: logging.info('negative/zero time right: %s', time_right) self.virtual_timer.stop() time_right = 0 self.r_time = time_right logging.info('(web) clock new time received l:%s r:%s', hms_time(self.l_time), hms_time(self.r_time)) DisplayMsg.show( Message.DGT_CLOCK_TIME(time_left=self.l_time, time_right=self.r_time, connect=True, dev='web')) self._display_time(self.l_time, self.r_time)
def _resume_clock(self, side: ClockSide): if self.dgtboard.l_time >= 3600 * 10 or self.dgtboard.r_time >= 3600 * 10: logging.debug('time values not set - abort function') return False l_run = r_run = 0 if side == ClockSide.LEFT: l_run = 1 if side == ClockSide.RIGHT: r_run = 1 with self.lib_lock: l_hms = hms_time(self.dgtboard.l_time) r_hms = hms_time(self.dgtboard.r_time) res = self.dgtboard.set_and_run(l_run, l_hms[0], l_hms[1], l_hms[2], r_run, r_hms[0], r_hms[1], r_hms[2]) if not res: logging.warning('finally failed %i', res) return False else: self.side_running = side if not self.dgtboard.disable_end: res = self.dgtboard.end_text() # this is needed for some(!) clocks self.dgtboard.in_settime = False # @todo should be set on ACK (see: DgtBoard) not here return res
def start_internal(self, color, log=True): """Start the internal clock.""" if not self.internal_running(): if self.mode in (TimeMode.BLITZ, TimeMode.FISCHER): self.active_color = color self.reset_start_time() if log: w_hms, b_hms = self._log_time() logging.info('start internal time w:%s - b:%s [ign]', w_hms, b_hms) logging.info('received clock time w:%s - b:%s [use]', hms_time(self.clock_time[chess.WHITE]), hms_time(self.clock_time[chess.BLACK])) self.internal_time[chess.WHITE] = self.clock_time[chess.WHITE] self.internal_time[chess.BLACK] = self.clock_time[chess.BLACK] # Only start thread if not already started for same color, and the player has not already lost on time if self.internal_time[color] > 0 and self.active_color is not None and self.run_color != self.active_color: self.timer = threading.Timer(copy.copy(self.internal_time[color]), self._out_of_time, [copy.copy(self.internal_time[color])]) self.timer.start() logging.debug('internal timer started - color: %s run: %s active: %s', color, self.run_color, self.active_color) self.run_color = self.active_color
def _runclock(self): if self.side_running == ClockSide.LEFT: time_left = self.l_time - 1 if time_left <= 0: logging.info('negative/zero time left: %s', time_left) self.virtual_timer.stop() time_left = 0 self.l_time = time_left if self.side_running == ClockSide.RIGHT: time_right = self.r_time - 1 if time_right <= 0: logging.info('negative/zero time right: %s', time_right) self.virtual_timer.stop() time_right = 0 self.r_time = time_right logging.info('(web) clock new time received l:%s r:%s', hms_time(self.l_time), hms_time(self.r_time)) DisplayMsg.show(Message.DGT_CLOCK_TIME(time_left=self.l_time, time_right=self.r_time, connect=True, dev='web')) self._display_time(self.l_time, self.r_time)
def _log_time(self): time_w, time_b = self.get_internal_time(flip_board=False) return hms_time(time_w), hms_time(time_b)
def set_clock_times(self, white_time: int, black_time: int): """Set the times send from the clock.""" logging.info('set clock times w:%s b:%s', hms_time(white_time), hms_time(black_time)) self.clock_time[chess.WHITE] = white_time self.clock_time[chess.BLACK] = black_time
def _process_board_message(self, message_id: int, message: tuple, message_length: int): if False: # switch-case pass elif message_id == DgtMsg.DGT_MSG_VERSION: if message_length != 2: logging.warning('illegal length in data') board_version = str(message[0]) + '.' + str(message[1]) logging.debug('(ser) board version %0.2f', float(board_version)) self.write_command([DgtCmd.DGT_SEND_BRD]) # Update the board => get first FEN if self.device.find('rfc') == -1: text_l, text_m, text_s = 'USB e-Board', 'USBboard', 'ok usb' self.channel = 'USB' else: btname5 = self.bt_name[-5:] if 'REVII' in self.bt_name: text_l, text_m, text_s = 'RevII ' + btname5, 'Rev' + btname5, 'b' + btname5 self.is_revelation = True self.write_command([DgtCmd.DGT_RETURN_LONG_SERIALNR]) elif 'DGT_BT' in self.bt_name: text_l, text_m, text_s = 'DGTBT ' + btname5, 'BT ' + btname5, 'b' + btname5 else: text_l, text_m, text_s = 'BT e-Board', 'BT board', 'ok bt' self.channel = 'BT' self.ask_battery_status() self.bconn_text = Dgt.DISPLAY_TEXT(l=text_l, m=text_m, s=text_s, wait=True, beep=False, maxtime=1.1, devs={'i2c', 'web'}) # serial clock lateron DisplayMsg.show(Message.DGT_EBOARD_VERSION(text=self.bconn_text, channel=self.channel)) self.startup_serial_clock() # now ask the serial clock to answer if self.watchdog_timer.is_running(): logging.warning('watchdog timer is already running') else: logging.debug('watchdog timer is started') self.watchdog_timer.start() elif message_id == DgtMsg.DGT_MSG_BWTIME: if message_length != 7: logging.warning('illegal length in data') if ((message[0] & 0x0f) == 0x0a) or ((message[3] & 0x0f) == 0x0a): # Clock ack message # Construct the ack message ack0 = ((message[1]) & 0x7f) | ((message[3] << 3) & 0x80) ack1 = ((message[2]) & 0x7f) | ((message[3] << 2) & 0x80) ack2 = ((message[4]) & 0x7f) | ((message[0] << 3) & 0x80) ack3 = ((message[5]) & 0x7f) | ((message[0] << 2) & 0x80) if ack0 != 0x10: logging.warning('(ser) clock ACK error %s', (ack0, ack1, ack2, ack3)) if self.last_clock_command: logging.debug('(ser) clock resending failed message [%s]', self.last_clock_command) self.write_command(self.last_clock_command) self.last_clock_command = [] # only resend once return else: logging.debug('(ser) clock ACK okay [%s]', DgtAck(ack1)) if self.last_clock_command: cmd = self.last_clock_command[3] # type: DgtClk if cmd.value != ack1 and ack1 < 0x80: logging.warning('(ser) clock ACK [%s] out of sync - last: [%s]', DgtAck(ack1), cmd) # @todo these lines are better as what is done on DgtHw but it doesnt work # if ack1 == DgtAck.DGT_ACK_CLOCK_SETNRUN.value: # logging.info('(ser) clock out of set time now') # self.in_settime = False if ack1 == DgtAck.DGT_ACK_CLOCK_BUTTON.value: # this are the other (ack2-ack3) codes # 05-49 33-52 17-51 09-50 65-53 | button 0-4 (single) # 37-52 21-51 13-50 69-53 | button 0 + 1-4 # 49-51 41-50 97-53 | button 1 + 2-4 # 25-50 81-53 | button 2 + 3-4 # 73-53 | button 3 + 4 if ack3 == 49: logging.info('(ser) clock button 0 pressed - ack2: %i', ack2) DisplayMsg.show(Message.DGT_BUTTON(button=0, dev='ser')) if ack3 == 52: logging.info('(ser) clock button 1 pressed - ack2: %i', ack2) DisplayMsg.show(Message.DGT_BUTTON(button=1, dev='ser')) if ack3 == 51: logging.info('(ser) clock button 2 pressed - ack2: %i', ack2) DisplayMsg.show(Message.DGT_BUTTON(button=2, dev='ser')) if ack3 == 50: logging.info('(ser) clock button 3 pressed - ack2: %i', ack2) DisplayMsg.show(Message.DGT_BUTTON(button=3, dev='ser')) if ack3 == 53: if ack2 == 69: logging.info('(ser) clock button 0+4 pressed - ack2: %i', ack2) DisplayMsg.show(Message.DGT_BUTTON(button=0x11, dev='ser')) else: logging.info('(ser) clock button 4 pressed - ack2: %i', ack2) DisplayMsg.show(Message.DGT_BUTTON(button=4, dev='ser')) if ack1 == DgtAck.DGT_ACK_CLOCK_VERSION.value: self.enable_ser_clock = True main = ack2 >> 4 sub = ack2 & 0x0f logging.debug('(ser) clock version %0.2f', float(str(main) + '.' + str(sub))) if self.bconn_text: self.bconn_text.devs = {'ser'} # Now send the (delayed) message to serial clock dev = 'ser' else: dev = 'err' DisplayMsg.show(Message.DGT_CLOCK_VERSION(main=main, sub=sub, dev=dev, text=self.bconn_text)) elif any(message[:7]): r_hours = message[0] & 0x0f r_mins = (message[1] >> 4) * 10 + (message[1] & 0x0f) r_secs = (message[2] >> 4) * 10 + (message[2] & 0x0f) l_hours = message[3] & 0x0f l_mins = (message[4] >> 4) * 10 + (message[4] & 0x0f) l_secs = (message[5] >> 4) * 10 + (message[5] & 0x0f) r_time = r_hours * 3600 + r_mins * 60 + r_secs l_time = l_hours * 3600 + l_mins * 60 + l_secs errtim = r_hours > 9 or l_hours > 9 or r_mins > 59 or l_mins > 59 or r_secs > 59 or l_secs > 59 if errtim: # complete illegal package received logging.warning('(ser) clock illegal new time received %s', message) elif r_time > self.r_time or l_time > self.l_time: # the new time is higher as the old => ignore logging.warning('(ser) clock strange old time received %s l:%s r:%s', message, hms_time(self.l_time), hms_time(self.r_time)) if self.in_settime: logging.info('(ser) clock still in set mode, ignore received time') errtim = True elif r_time - self.r_time > 3600 or l_time - self.l_time > 3600: logging.info('(ser) clock new time over 1h difference, ignore received time') errtim = True else: logging.info('(ser) clock new time received l:%s r:%s', hms_time(l_time), hms_time(r_time)) status = message[6] & 0x3f connect = not status & 0x20 if connect: right_side_down = -0x40 if status & 0x02 else 0x40 if self.lever_pos != right_side_down: logging.debug('(ser) clock button status: 0x%x old lever: %s', status, self.lever_pos) if self.lever_pos is not None: DisplayMsg.show(Message.DGT_BUTTON(button=right_side_down, dev='ser')) self.lever_pos = right_side_down else: logging.info('(ser) clock not connected, sending old time l:%s r:%s', hms_time(self.l_time), hms_time(self.r_time)) l_time = self.l_time r_time = self.r_time if self.in_settime: logging.info('(ser) clock still in set mode, sending old time l:%s r:%s', hms_time(self.l_time), hms_time(self.r_time)) l_time = self.l_time r_time = self.r_time DisplayMsg.show(Message.DGT_CLOCK_TIME(time_left=l_time, time_right=r_time, connect=connect, dev='ser')) if not self.enable_ser_clock: dev = 'rev' if 'REVII' in self.bt_name else 'ser' if self.watchdog_timer.is_running(): # a running watchdog means: board already found logging.info('(%s) clock restarting setup', dev) self.startup_serial_clock() else: logging.info('(%s) clock sends messages already but (%s) board still not found', dev, dev) if not errtim: self.r_time = r_time self.l_time = l_time else: logging.debug('(ser) clock null message ignored') if self.clock_lock: logging.debug('(ser) clock unlocked after %.3f secs', time.time() - self.clock_lock) self.clock_lock = False elif message_id == DgtMsg.DGT_MSG_BOARD_DUMP: if message_length != 64: logging.warning('illegal length in data') piece_to_char = { 0x01: 'P', 0x02: 'R', 0x03: 'N', 0x04: 'B', 0x05: 'K', 0x06: 'Q', 0x07: 'p', 0x08: 'r', 0x09: 'n', 0x0a: 'b', 0x0b: 'k', 0x0c: 'q', 0x0d: '$', 0x0e: '%', 0x0f: '&', 0x00: '.' } board = '' for character in message: board += piece_to_char[character & 0x0f] logging.debug('\n' + '\n'.join(board[0 + i:8 + i] for i in range(0, len(board), 8))) # Show debug board # Create fen from board fen = '' empty = 0 for square in range(0, 64): if message[square] != 0 and message[square] < 0x0d: # @todo for the moment ignore the special pieces if empty > 0: fen += str(empty) empty = 0 fen += piece_to_char[message[square] & 0x0f] else: empty += 1 if (square + 1) % 8 == 0: if empty > 0: fen += str(empty) empty = 0 if square < 63: fen += '/' # Attention! This fen is NOT flipped logging.debug('raw fen [%s]', fen) DisplayMsg.show(Message.DGT_FEN(fen=fen, raw=True)) elif message_id == DgtMsg.DGT_MSG_FIELD_UPDATE: if message_length != 2: logging.warning('illegal length in data') if self.field_timer_running: self.stop_field_timer() self.start_field_timer() elif message_id == DgtMsg.DGT_MSG_SERIALNR: if message_length != 5: logging.warning('illegal length in data') DisplayMsg.show(Message.DGT_SERIAL_NR(number=''.join([chr(elem) for elem in message]))) elif message_id == DgtMsg.DGT_MSG_LONG_SERIALNR: if message_length != 10: logging.warning('illegal length in data') number = ''.join([chr(elem) for elem in message]) self.enable_revelation_pi = float(number[:4]) >= 3.25 # "3.250010001"=yes "0000000001"=no logging.info('(rev) clock in PiMode: %s - serial: %s', 'yes' if self.enable_revelation_pi else 'no', number) elif message_id == DgtMsg.DGT_MSG_BATTERY_STATUS: if message_length != 9: logging.warning('illegal length in data') DisplayMsg.show(Message.BATTERY(percent=message[0])) else: # Default logging.warning('message not handled [%s]', DgtMsg(message_id))
def _process_board_message(self, message_id: int, message: tuple, message_length: int): if False: # switch-case pass elif message_id == DgtMsg.DGT_MSG_VERSION: if message_length != 2: logging.warning('illegal length in data') board_version = str(message[0]) + '.' + str(message[1]) logging.debug('(ser) board version %0.2f', float(board_version)) self.write_command([DgtCmd.DGT_SEND_BRD ]) # Update the board => get first FEN if self.device.find('rfc') == -1: text_l, text_m, text_s = 'USB e-Board', 'USBboard', 'ok usb' self.channel = 'USB' else: btname5 = self.bt_name[-5:] if 'REVII' in self.bt_name: text_l, text_m, text_s = 'RevII ' + btname5, 'Rev' + btname5, 'b' + btname5 self.is_revelation = True self.write_command([DgtCmd.DGT_RETURN_LONG_SERIALNR]) elif 'DGT_BT' in self.bt_name: text_l, text_m, text_s = 'DGTBT ' + btname5, 'BT ' + btname5, 'b' + btname5 else: text_l, text_m, text_s = 'BT e-Board', 'BT board', 'ok bt' self.channel = 'BT' self.ask_battery_status() self.bconn_text = Dgt.DISPLAY_TEXT(l=text_l, m=text_m, s=text_s, wait=True, beep=False, maxtime=1.1, devs={'i2c', 'web' }) # serial clock lateron DisplayMsg.show( Message.DGT_EBOARD_VERSION(text=self.bconn_text, channel=self.channel)) self.startup_serial_clock() # now ask the serial clock to answer if self.watchdog_timer.is_running(): logging.warning('watchdog timer is already running') else: logging.debug('watchdog timer is started') self.watchdog_timer.start() elif message_id == DgtMsg.DGT_MSG_BWTIME: if message_length != 7: logging.warning('illegal length in data') if ((message[0] & 0x0f) == 0x0a) or ((message[3] & 0x0f) == 0x0a): # Clock ack message # Construct the ack message ack0 = ((message[1]) & 0x7f) | ((message[3] << 3) & 0x80) ack1 = ((message[2]) & 0x7f) | ((message[3] << 2) & 0x80) ack2 = ((message[4]) & 0x7f) | ((message[0] << 3) & 0x80) ack3 = ((message[5]) & 0x7f) | ((message[0] << 2) & 0x80) if ack0 != 0x10: logging.warning('(ser) clock ACK error %s', (ack0, ack1, ack2, ack3)) if self.last_clock_command: logging.debug( '(ser) clock resending failed message [%s]', self.last_clock_command) self.write_command(self.last_clock_command) self.last_clock_command = [] # only resend once return else: logging.debug('(ser) clock ACK okay [%s]', DgtAck(ack1)) if self.last_clock_command: cmd = self.last_clock_command[3] # type: DgtClk if cmd.value != ack1 and ack1 < 0x80: logging.warning( '(ser) clock ACK [%s] out of sync - last: [%s]', DgtAck(ack1), cmd) # @todo these lines are better as what is done on DgtHw but it doesnt work # if ack1 == DgtAck.DGT_ACK_CLOCK_SETNRUN.value: # logging.info('(ser) clock out of set time now') # self.in_settime = False if ack1 == DgtAck.DGT_ACK_CLOCK_BUTTON.value: # this are the other (ack2-ack3) codes # 05-49 33-52 17-51 09-50 65-53 | button 0-4 (single) # 37-52 21-51 13-50 69-53 | button 0 + 1-4 # 49-51 41-50 97-53 | button 1 + 2-4 # 25-50 81-53 | button 2 + 3-4 # 73-53 | button 3 + 4 if ack3 == 49: logging.info('(ser) clock button 0 pressed - ack2: %i', ack2) DisplayMsg.show(Message.DGT_BUTTON(button=0, dev='ser')) if ack3 == 52: logging.info('(ser) clock button 1 pressed - ack2: %i', ack2) DisplayMsg.show(Message.DGT_BUTTON(button=1, dev='ser')) if ack3 == 51: logging.info('(ser) clock button 2 pressed - ack2: %i', ack2) DisplayMsg.show(Message.DGT_BUTTON(button=2, dev='ser')) if ack3 == 50: logging.info('(ser) clock button 3 pressed - ack2: %i', ack2) DisplayMsg.show(Message.DGT_BUTTON(button=3, dev='ser')) if ack3 == 53: if ack2 == 69: logging.info( '(ser) clock button 0+4 pressed - ack2: %i', ack2) DisplayMsg.show( Message.DGT_BUTTON(button=0x11, dev='ser')) else: logging.info( '(ser) clock button 4 pressed - ack2: %i', ack2) DisplayMsg.show( Message.DGT_BUTTON(button=4, dev='ser')) if ack1 == DgtAck.DGT_ACK_CLOCK_VERSION.value: self.enable_ser_clock = True main = ack2 >> 4 sub = ack2 & 0x0f logging.debug('(ser) clock version %0.2f', float(str(main) + '.' + str(sub))) if self.bconn_text: self.bconn_text.devs = { 'ser' } # Now send the (delayed) message to serial clock dev = 'ser' else: dev = 'err' DisplayMsg.show( Message.DGT_CLOCK_VERSION(main=main, sub=sub, dev=dev, text=self.bconn_text)) elif any(message[:7]): r_hours = message[0] & 0x0f r_mins = (message[1] >> 4) * 10 + (message[1] & 0x0f) r_secs = (message[2] >> 4) * 10 + (message[2] & 0x0f) l_hours = message[3] & 0x0f l_mins = (message[4] >> 4) * 10 + (message[4] & 0x0f) l_secs = (message[5] >> 4) * 10 + (message[5] & 0x0f) r_time = r_hours * 3600 + r_mins * 60 + r_secs l_time = l_hours * 3600 + l_mins * 60 + l_secs errtim = r_hours > 9 or l_hours > 9 or r_mins > 59 or l_mins > 59 or r_secs > 59 or l_secs > 59 if errtim: # complete illegal package received logging.warning('(ser) clock illegal new time received %s', message) elif r_time > self.r_time or l_time > self.l_time: # the new time is higher as the old => ignore logging.warning( '(ser) clock strange old time received %s l:%s r:%s', message, hms_time(self.l_time), hms_time(self.r_time)) if self.in_settime: logging.info( '(ser) clock still in set mode, ignore received time' ) errtim = True elif r_time - self.r_time > 3600 or l_time - self.l_time > 3600: logging.info( '(ser) clock new time over 1h difference, ignore received time' ) errtim = True else: logging.info('(ser) clock new time received l:%s r:%s', hms_time(l_time), hms_time(r_time)) status = message[6] & 0x3f connect = not status & 0x20 if connect: right_side_down = -0x40 if status & 0x02 else 0x40 if self.lever_pos != right_side_down: logging.debug( '(ser) clock button status: 0x%x old lever: %s', status, self.lever_pos) if self.lever_pos is not None: DisplayMsg.show( Message.DGT_BUTTON(button=right_side_down, dev='ser')) self.lever_pos = right_side_down else: logging.info( '(ser) clock not connected, sending old time l:%s r:%s', hms_time(self.l_time), hms_time(self.r_time)) l_time = self.l_time r_time = self.r_time if self.in_settime: logging.info( '(ser) clock still in set mode, sending old time l:%s r:%s', hms_time(self.l_time), hms_time(self.r_time)) l_time = self.l_time r_time = self.r_time DisplayMsg.show( Message.DGT_CLOCK_TIME(time_left=l_time, time_right=r_time, connect=connect, dev='ser')) if not self.enable_ser_clock: dev = 'rev' if 'REVII' in self.bt_name else 'ser' if self.watchdog_timer.is_running( ): # a running watchdog means: board already found logging.info('(%s) clock restarting setup', dev) self.startup_serial_clock() else: logging.info( '(%s) clock sends messages already but (%s) board still not found', dev, dev) if not errtim: self.r_time = r_time self.l_time = l_time else: logging.debug('(ser) clock null message ignored') if self.clock_lock: logging.debug('(ser) clock unlocked after %.3f secs', time.time() - self.clock_lock) self.clock_lock = False elif message_id == DgtMsg.DGT_MSG_BOARD_DUMP: if message_length != 64: logging.warning('illegal length in data') piece_to_char = { 0x01: 'P', 0x02: 'R', 0x03: 'N', 0x04: 'B', 0x05: 'K', 0x06: 'Q', 0x07: 'p', 0x08: 'r', 0x09: 'n', 0x0a: 'b', 0x0b: 'k', 0x0c: 'q', 0x0d: '$', 0x0e: '%', 0x0f: '&', 0x00: '.' } board = '' for character in message: board += piece_to_char[character & 0x0f] logging.debug('\n' + '\n'.join( board[0 + i:8 + i] for i in range(0, len(board), 8))) # Show debug board # Create fen from board fen = '' empty = 0 for square in range(0, 64): if message[square] != 0 and message[ square] < 0x0d: # @todo for the moment ignore the special pieces if empty > 0: fen += str(empty) empty = 0 fen += piece_to_char[message[square] & 0x0f] else: empty += 1 if (square + 1) % 8 == 0: if empty > 0: fen += str(empty) empty = 0 if square < 63: fen += '/' # Attention! This fen is NOT flipped logging.debug('raw fen [%s]', fen) DisplayMsg.show(Message.DGT_FEN(fen=fen, raw=True)) elif message_id == DgtMsg.DGT_MSG_FIELD_UPDATE: if message_length != 2: logging.warning('illegal length in data') if self.field_timer_running: self.stop_field_timer() self.start_field_timer() elif message_id == DgtMsg.DGT_MSG_SERIALNR: if message_length != 5: logging.warning('illegal length in data') DisplayMsg.show( Message.DGT_SERIAL_NR( number=''.join([chr(elem) for elem in message]))) elif message_id == DgtMsg.DGT_MSG_LONG_SERIALNR: if message_length != 10: logging.warning('illegal length in data') number = ''.join([chr(elem) for elem in message]) self.enable_revelation_pi = float( number[:4]) >= 3.25 # "3.250010001"=yes "0000000001"=no logging.info('(rev) clock in PiMode: %s - serial: %s', 'yes' if self.enable_revelation_pi else 'no', number) elif message_id == DgtMsg.DGT_MSG_BATTERY_STATUS: if message_length != 9: logging.warning('illegal length in data') DisplayMsg.show(Message.BATTERY(percent=message[0])) else: # Default logging.warning('message not handled [%s]', DgtMsg(message_id))