diff --git a/source/jetsort.py b/source/jetsort.py index 05eae46..40c74df 100644 --- a/source/jetsort.py +++ b/source/jetsort.py @@ -76,6 +76,10 @@ class JetSortSimulator: # Bag limit settings (in cents) self.bag_limit = 50000 # $500.00 + # Workflow state + self.counting_in_progress = False + self.report_ready = False + def _calculate_checksum(self, data: bytes) -> int: """Calculate checksum for packet""" checksum = 0 @@ -85,7 +89,7 @@ class JetSortSimulator: return checksum & 0xFF def _create_packet(self, title: str, data: str) -> bytes: - """Create a packet with STX, checksum, length, title, data, and ETX""" + """Create a packet with STX, checksum, length, CR, LF, title, data, and ETX""" # Build packet content (without STX and ETX) content = f"{title}\r\n{data}".encode("ascii") @@ -93,12 +97,12 @@ class JetSortSimulator: checksum = self._calculate_checksum(content) # Calculate length (high and low bytes) - length = len(content) + 2 # +2 for CR LF after title + length = len(content) + 2 # +2 for CR LF after length bytes len_high = (length >> 8) & 0xFF len_low = length & 0xFF - # Build full packet - packet = bytes([STX, checksum, len_high, len_low]) + content + bytes([ETX]) + # Build full packet: STX + CHECKSUM + LENGTH + CR + LF + content + ETX + packet = bytes([STX, checksum, len_high, len_low, CR, LF]) + content + bytes([ETX]) return packet @@ -376,24 +380,49 @@ class JetSortSimulator: logger.info(f"Sending SUB-BATCH report ({len(packet)} bytes)") return packet - def send_automatic_report(self): - """Send automatic SUB-BATCH report (immediate mode)""" - if not self.polled_mode and self.serial_conn: - logger.info("Sending automatic SUB-BATCH report") + def handle_s_batch_button(self): + """Handle S-BATCH button press - starts counting""" + logger.info("=" * 60) + logger.info("S-BATCH button pressed - Starting counting...") + logger.info("=" * 60) - # Simulate new batch - self._simulate_counting() + # Simulate counting + self._simulate_counting() - # Generate and send report - report_data = self._generate_sub_batch_report() - packet = self._create_packet(REPORT_SUB_BATCH, report_data) + # Update state + self.counting_in_progress = True + self.report_ready = True - self.serial_conn.write(packet) - logger.debug(f"TX: {' '.join(f'{b:02X}' for b in packet[:50])}...") + logger.info("Counting complete. Press ENTER again (END button) to send report.") - # Reset batch counters after sending - self.coin_values = [0] * self.num_coin_lines - self.bill_values = [0] * self.num_bill_lines + def handle_end_button(self): + """Handle END button press - sends the report""" + if not self.report_ready: + logger.warning("No report ready to send. Press ENTER to start counting first.") + return + + logger.info("=" * 60) + logger.info("END button pressed - Sending SUB-BATCH report") + logger.info("=" * 60) + + # Generate and send report + report_data = self._generate_sub_batch_report() + packet = self._create_packet(REPORT_SUB_BATCH, report_data) + + self.serial_conn.write(packet) + logger.debug(f"TX: {' '.join(f'{b:02X}' for b in packet[:50])}...") + logger.info("Report sent successfully") + + # Reset batch counters after sending + self.coin_values = [0] * self.num_coin_lines + self.bill_values = [0] * self.num_bill_lines + + # Reset state + self.counting_in_progress = False + self.report_ready = False + + logger.info("") + logger.info("Ready for next batch. Press ENTER (S-BATCH button) to start counting.") def run(self): """Main simulator loop""" @@ -401,7 +430,14 @@ class JetSortSimulator: f"Starting JetSort simulator on {self.port} at {self.baudrate} baud" ) logger.info("Protocol: JetSort Communication Package") - logger.info("Press ENTER to send a cash counting report") + logger.info("") + logger.info("=" * 60) + logger.info("WORKFLOW:") + logger.info("1. Press ENTER → S-BATCH button (starts counting)") + logger.info("2. Press ENTER → END button (sends report)") + logger.info("=" * 60) + logger.info("") + logger.info("Ready for first batch. Press ENTER (S-BATCH button) to start counting.") try: self.serial_conn = serial.Serial( @@ -414,31 +450,37 @@ class JetSortSimulator: ) logger.info("Serial port opened successfully") - help_text_shown = False + logger.info("") while True: - if not help_text_shown: - print("\nPress ENTER to send a cash counting report...") - help_text_shown = True - # Check for keyboard input (non-blocking) if sys.platform != "win32": # Unix/Linux - use select ready, _, _ = select.select([sys.stdin], [], [], 0) if ready: sys.stdin.readline() # Consume the input - logger.info("Key pressed - sending cash counting report") - self.send_automatic_report() - help_text_shown = False + + # Handle button press based on current state + if not self.report_ready: + # First press: S-BATCH button + self.handle_s_batch_button() + else: + # Second press: END button + self.handle_end_button() else: # Windows - use msvcrt import msvcrt if msvcrt.kbhit(): msvcrt.getch() # Consume the input - logger.info("Key pressed - sending cash counting report") - self.send_automatic_report() - help_text_shown = False + + # Handle button press based on current state + if not self.report_ready: + # First press: S-BATCH button + self.handle_s_batch_button() + else: + # Second press: END button + self.handle_end_button() # Check for incoming data from serial port if self.serial_conn.in_waiting > 0: