import requests from PIL import Image, ImageDraw, ImageFont, ImageOps import qrcode import serial import io import time CHUNK_SIZE = 1024 # Define the chunk size (in bytes) for sending data DELAY_BETWEEN_CHUNK = 1 # Delay between chunks in milliseconds # Download image from URL and resize to 320x480 def download_image(url): response = requests.get(url) response.raise_for_status() image = Image.open(io.BytesIO(response.content)) image = image.resize((320, 480)) # Resize to 320x480 if image.mode != 'RGB': image = image.convert('RGB') return image # Send image to device over serial port in chunks def write_to_serial_image(ser, data): if ser: try: print("Sending image in chunks to device...") # Prepare the first command with filename and data length first_command = f"StartSendingFile {time.time()}.jpeg {len(data)}\n" ser.write(first_command.encode()) print(f"Sent command: {first_command}") # Wait for the device to respond (this could be adjusted based on the device's protocol) time.sleep(2) # Increase delay before reading device response response = ser.readline().decode().strip() # Read the next line and decode it print(f"Device response: {response}") # If the device is ready to receive data, send the image in chunks if "Command received. Preparing to receive file..." in response: print("Device is preparing to receive file...") for i in range(0, len(data), CHUNK_SIZE): chunk = data[i:i+CHUNK_SIZE] ser.write(chunk) print(f"Sent chunk of size {len(chunk)} bytes") time.sleep(DELAY_BETWEEN_CHUNK / 1000) # Convert milliseconds to seconds print("Image transfer complete.") # After sending, wait for the device's acknowledgment of the transfer response = ser.readline().decode().strip() # Read the next line and decode it print(f"Device response after transfer: {response}") # Check device readiness after transfer time.sleep(1) # Add a delay to ensure the device has processed the file # Check if the device is ready for the next file ready_response = ser.readline().decode().strip() print(f"Device readiness check: {ready_response}") if "Image Displayed Successfully" in ready_response: print("Device is ready for the next file.") else: print("Device is still not ready.") else: print("Device did not acknowledge readiness.") except Exception as e: print(f"Error while sending data: {e}") # Send image data over serial def send_serial_data(serial_port, data): try: with serial.Serial( port=serial_port, baudrate=156500, bytesize=serial.EIGHTBITS, stopbits=serial.STOPBITS_ONE, parity=serial.PARITY_NONE, timeout=5 # Increased timeout to allow more time for device to respond ) as ser: write_to_serial_image(ser, data) except Exception as e: print(f"Serial communication error: {e}") def main(): serial_port = input("Enter serial port (e.g. COM3 or /dev/ttyUSB0): ") while True: print("\nOptions:") print("1. Welcome Screen") print("2. Draw QR Screen") print("3. Success Screen") print("4. Pending Screen") print("5. Fail Screen") print("6. Fail with Reason") print("7. Cancle Screen") print("8. Exit") choice = input("Enter your choice: ") if choice == '1': # Welcome Screen try: img = download_image("http://download.rechargegrid.in/download/general/image/jpeg/_home.jpg") # Convert to bytes and send img_byte_arr = io.BytesIO() img.save(img_byte_arr, format='JPEG') send_serial_data(serial_port, img_byte_arr.getvalue()) print("Welcome screen sent.") except Exception as e: print(f"Error: {e}") elif choice == '2': # QR Screen upi_url = input("Enter UPI URL: ") upi_id = input("Enter UPI ID: ") amount = input("Enter Amount: ") try: # Download background bg = download_image("http://download.rechargegrid.in/download/general/image/jpeg/_background.jpg") # Generate QR code qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=8, border=1, ) qr.add_data(upi_url) qr.make(fit=True) qr_img = qr.make_image(fill_color="black", back_color="white").convert('RGB') qr_img = qr_img.resize((260, 260)) # Paste QR onto background at (30,170) bg.paste(qr_img, (30, 150)) # Draw amount text draw = ImageDraw.Draw(bg) try: font = ImageFont.truetype("arialbd.ttf", 30) # Adjusted font size to 30 except IOError: font = ImageFont.load_default() text = f"₹ {amount}" text_bbox = draw.textbbox((0, 0), text, font=font) text_width = text_bbox[2] - text_bbox[0] x = (320 - text_width) // 2 # Center the text horizontally y = 130 - text_bbox[3] - 3 # Position above the QR code with 10px margin draw.text((x, y), text, fill="black", font=font) # Set text color to black # UPI ID text below QR try: small_font = ImageFont.truetype("arial.ttf", 20) # Define small font except IOError: small_font = ImageFont.load_default() text = f"UPI ID: {upi_id}" upi_text_bbox = draw.textbbox((0, 0), upi_id, font=small_font) upi_text_width = upi_text_bbox[2] - upi_text_bbox[0] upi_x = (250 - upi_text_width) // 2 # Center the UPI ID upi_y = 430 # Position below the QR code draw.text((upi_x, upi_y), text, fill="black", font=small_font) # Convert to bytes and send img_byte_arr = io.BytesIO() bg.save(img_byte_arr, format='JPEG') send_serial_data(serial_port, img_byte_arr.getvalue()) print("QR screen sent.") except Exception as e: print(f"Error: {e}") elif choice == '3': # Success Screen amount = input("Enter Amount: ") try: img = download_image("http://download.rechargegrid.in/download/general/image/jpeg/_success.jpg") draw = ImageDraw.Draw(img) # Load font try: font_large = ImageFont.truetype("arialbd.ttf", 34) # Large font for the main message except IOError: font_large = ImageFont.load_default() # Main payment successful message payment_text = f"₹ {amount}" payment_bbox = draw.textbbox((0, 0), payment_text, font=font_large) payment_width = payment_bbox[2] - payment_bbox[0] x_payment = (320 - payment_width) // 2 y_payment = 250 # Set a fixed position near the top of the image draw.text((x_payment, y_payment), payment_text, fill="black", font=font_large) # Convert the image to bytes and send it via serial img_byte_arr = io.BytesIO() img.save(img_byte_arr, format='JPEG') send_serial_data(serial_port, img_byte_arr.getvalue()) print("Success screen sent.") except Exception as e: print(f"Error: {e}") elif choice == '4': # Amazon Success with Reward amount = input("Enter Amount: ") try: img = download_image("http://download.rechargegrid.in/download/general/image/jpeg/_pending.jpg") draw = ImageDraw.Draw(img) try: font_large = ImageFont.truetype("arialbd.ttf", 34) # Arial Bold, size 24 except IOError: font_large = ImageFont.load_default() text = f"₹ {amount}" text_bbox = draw.textbbox((0, 0), text, font=font_large) text_width = text_bbox[2] - text_bbox[0] x = (320 - text_width) // 2 # Horizontally center the text y = 250 # Position the text near the top of the image draw.text((x, y), text, fill="black", font=font_large) # Convert to bytes and send img_byte_arr = io.BytesIO() img.save(img_byte_arr, format='JPEG') send_serial_data(serial_port, img_byte_arr.getvalue()) print("Amazon Success with Reward screen sent.") except Exception as e: print(f"Error: {e}") elif choice == '5': # Amazon Fail without Reason try: img = download_image("http://download.rechargegrid.in/download/general/image/jpeg/_fail.jpg") img_byte_arr = io.BytesIO() img.save(img_byte_arr, format='JPEG') send_serial_data(serial_port, img_byte_arr.getvalue()) print("Fail without Reason screen sent.") except Exception as e: print(f"Error: {e}") elif choice == '6': # Amazon Fail with Reason reason = input("Enter Reason for Failure: ") try: img = download_image("http://download.rechargegrid.in/download/general/image/jpeg/_fail.jpg") draw = ImageDraw.Draw(img) try: font = ImageFont.truetype("arialbd.ttf", 24) except IOError: font = ImageFont.load_default() # Build the base text text = f"Reason: {reason}" # We'll wrap the text so it doesn't exceed ~300px in width max_width = 300 lines = [] words = text.split() if words: current_line = words.pop(0) for w in words: test_line = current_line + " " + w # textlength(...) returns pixel width of the string if draw.textlength(test_line, font=font) <= max_width: current_line = test_line else: # We start a new line lines.append(current_line) current_line = w lines.append(current_line) wrapped_text = "\n".join(lines) # Measure the bounding box of the wrapped text so we can center it text_bbox = draw.multiline_textbbox((0, 0), wrapped_text, font=font) text_width = text_bbox[2] - text_bbox[0] text_height = text_bbox[3] - text_bbox[1] # Center the text horizontally in a 320-wide area # And vertically in (say) 570 for your layout x = (320 - text_width) // 2 y = (570 - text_height) // 2 # Draw the wrapped, centered text draw.multiline_text((x, y), wrapped_text, fill="black", font=font, align="center") # Convert final image to bytes and send via serial img_byte_arr = io.BytesIO() img.save(img_byte_arr, format='JPEG') send_serial_data(serial_port, img_byte_arr.getvalue()) print("Fail with Reason screen sent.") except Exception as e: print(f"Error: {e}") elif choice == '7': # Amazon Fail without Reason try: # Same logic as Welcome Screen, different background img = download_image("http://download.rechargegrid.in/download/general/image/jpeg/_cancelled.jpg") img_byte_arr = io.BytesIO() img.save(img_byte_arr, format='JPEG') data = img_byte_arr.getvalue() send_serial_data(serial_port, data) print("Cancle without Reason screen sent.") except Exception as e: print(f"Error: {e}") elif choice == '8': print("Exiting...") break else: print("Invalid choice. Please try again.") if __name__== "__main__": main()