mop-skills/skills/memobird/scripts/memobird_print.py

123 lines
3.6 KiB
Python
Executable File

#!/usr/bin/env python3
import sys
import os
import requests
import json
import base64
from io import BytesIO
from random import randint
from PIL import Image as PILImg, ImageOps
import argparse
# Default IP for Moritz's Memobird
DEFAULT_HOST = "192.168.10.165"
def to_byte_array(img):
imgByteArr = BytesIO()
img.save(imgByteArr, format='bmp')
return imgByteArr.getvalue()
class MemobirdSender:
def __init__(self, host=DEFAULT_HOST, port='80'):
self.host = host
self.port = port
self.uri = f"http://{self.host}:{self.port}/sys/printer"
def send(self, text_list, print_id=None):
print_id = print_id or randint(1, 10**6)
payload = {
'command': 3,
'content': {
'textList': text_list
},
'encryptFlag': 0,
'hasHead': 0,
'hasSignature': 0,
'hasTail': 0,
'isFromDirectPrint': False,
'msgType': 1,
'pkgCount': 1,
'pkgNo': 1,
'printID': print_id,
'priority': 0,
'result': 0,
'scripType': 3
}
try:
resp = requests.post(self.uri, json=payload, timeout=10)
resp.raise_for_status()
return resp.status_code
except Exception as e:
print(f"Error sending to Memobird: {e}")
sys.exit(1)
def create_text_element(text, big=False, bold=False, underline=False):
if not text.endswith('\n'):
text += '\n'
return {
'encodeType': 0,
'printType': 1,
'basetext': base64.b64encode(text.encode("GBK")).decode(),
'fontSize': 1 + big,
'bold': 1 * bold,
'underline': 1 * underline
}
def create_image_element(path):
img = PILImg.open(path)
img = img.convert(mode='L')
img = ImageOps.flip(img)
img = img.convert(mode='1')
return {
'encodeType': 0,
'printType': 5,
'basetext': base64.b64encode(to_byte_array(img)).decode()
}
def create_line_element(linetype='THICK'):
codes = {'THICK': 41, 'THIN': 42, 'DASH': 43}
return {
'encodeType': 0,
'printType': 4,
'iconID': codes.get(linetype, 41)
}
def main():
parser = argparse.ArgumentParser(description="Print to Memobird")
parser.add_argument("--text", help="Text to print")
parser.add_argument("--image", help="Path to image to print")
parser.add_argument("--ip", default=DEFAULT_HOST, help=f"Memobird IP (default: {DEFAULT_HOST})")
parser.add_argument("--big", action="store_true", help="Use big font")
parser.add_argument("--bold", action="store_true", help="Use bold font")
parser.add_argument("--underline", action="store_true", help="Use underline")
parser.add_argument("--line", choices=['THICK', 'THIN', 'DASH'], help="Print a separator line")
args = parser.parse_args()
if not args.text and not args.image and not args.line:
parser.print_help()
sys.exit(1)
sender = MemobirdSender(host=args.ip)
elements = []
if args.line:
elements.append(create_line_element(args.line))
if args.text:
elements.append(create_text_element(args.text, big=args.big, bold=args.bold, underline=args.underline))
if args.image:
if os.path.exists(args.image):
elements.append(create_image_element(args.image))
else:
print(f"Error: Image not found: {args.image}")
sys.exit(1)
status = sender.send(elements)
print(f"Success! Printer returned {status}")
if __name__ == "__main__":
main()