Make it all work
This commit is contained in:
173
cassini.py
173
cassini.py
@@ -6,21 +6,18 @@
|
||||
# Copyright (C) 2023 Vladimir Vukicevic
|
||||
# License: MIT
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import socket
|
||||
import struct
|
||||
import time
|
||||
import json
|
||||
import asyncio
|
||||
import logging
|
||||
import random
|
||||
import argparse
|
||||
from simple_mqtt_server import SimpleMQTTServer
|
||||
from simple_http_server import SimpleHTTPServer
|
||||
from saturn_printer import SaturnPrinter
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG, # .INFO
|
||||
level=logging.INFO,
|
||||
format="%(asctime)s,%(msecs)d %(levelname)s: %(message)s",
|
||||
datefmt="%H:%M:%S",
|
||||
)
|
||||
@@ -43,28 +40,27 @@ except ImportError:
|
||||
async def create_mqtt_server():
|
||||
mqtt = SimpleMQTTServer('0.0.0.0', 0)
|
||||
await mqtt.start()
|
||||
logging.info(f"MQTT Server created, port {mqtt.port}")
|
||||
mqtt_server_task = asyncio.create_task(mqtt.serve_forever())
|
||||
return mqtt, mqtt.port, mqtt_server_task
|
||||
|
||||
async def create_http_server():
|
||||
http = SimpleHTTPServer('0.0.0.0', 0)
|
||||
await http.start()
|
||||
logging.info(f"HTTP Server created, port {http.port}")
|
||||
http_server_task = asyncio.create_task(http.serve_forever())
|
||||
return http, http.port, http_server_task
|
||||
|
||||
def print_printer_status(printers):
|
||||
def do_status(printers):
|
||||
for i, p in enumerate(printers):
|
||||
attrs = p.desc['Data']['Attributes']
|
||||
status = p.desc['Data']['Status']
|
||||
printInfo = status['PrintInfo']
|
||||
print(f"{i}: {attrs['Name']} ({attrs['MachineName']})")
|
||||
print(f" Status: {printInfo['Status']} Layers: {printInfo['CurrentLayer']}/{printInfo['TotalLayer']}")
|
||||
print_info = status['PrintInfo']
|
||||
file_info = status['FileTransferInfo']
|
||||
print(f"{p.addr[0]}: {attrs['Name']} ({attrs['MachineName']}) Status: {status['CurrentStatus']}")
|
||||
print(f" Print Status: {print_info['Status']} Layers: {print_info['CurrentLayer']}/{print_info['TotalLayer']} File: {print_info['FileName']}")
|
||||
print(f" File Transfer Status: {file_info['Status']}")
|
||||
|
||||
def do_watch(interval):
|
||||
printers = SaturnPrinter.find_printers()
|
||||
status = printers[0].status()
|
||||
def do_watch(printer, interval=5):
|
||||
status = printer.status()
|
||||
with alive_bar(total=status['totalLayers'], manual=True, elapsed=False, title=status['filename']) as bar:
|
||||
while True:
|
||||
printers = SaturnPrinter.find_printers()
|
||||
@@ -76,54 +72,111 @@ def do_watch(interval):
|
||||
break
|
||||
time.sleep(interval)
|
||||
|
||||
async def main():
|
||||
cmd = None
|
||||
printers = SaturnPrinter.find_printers()
|
||||
|
||||
if len(printers) == 0:
|
||||
print("No printers found")
|
||||
return
|
||||
|
||||
if len(printers) > 1:
|
||||
print("More than 1 printer found.")
|
||||
print("Usage --printer argument to specify the ID. [TODO]")
|
||||
return
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
cmd = sys.argv[1]
|
||||
|
||||
if cmd == 'watch':
|
||||
do_watch(int(sys.argv[2]) if len(sys.argv) > 2 else 5)
|
||||
return
|
||||
|
||||
if cmd == 'status':
|
||||
print_printer_status(printers)
|
||||
return
|
||||
|
||||
# Spin up our private servers
|
||||
async def create_servers():
|
||||
mqtt, mqtt_port, mqtt_task = await create_mqtt_server()
|
||||
http, http_port, http_task = await create_http_server()
|
||||
|
||||
printer = printers[0]
|
||||
printer.connect(mqtt, http)
|
||||
return mqtt, http
|
||||
|
||||
await asyncio.sleep(3)
|
||||
printer.send_command(SATURN_CMD_0)
|
||||
await asyncio.sleep(1)
|
||||
printer.send_command(SATURN_CMD_1)
|
||||
await asyncio.sleep(1)
|
||||
printer.send_command(SATURN_CMD_SET_MYSTERY_TIME_PERIOD, { 'TimePeriod': 5 })
|
||||
await asyncio.sleep(1000)
|
||||
async def do_print(printer, filename):
|
||||
mqtt, http = await create_servers()
|
||||
connected = await printer.connect(mqtt, http)
|
||||
if not connected:
|
||||
logging.error("Failed to connect to printer")
|
||||
sys.exit(1)
|
||||
|
||||
#printer_task = asyncio.create_task(printer_setup(mqtt.port))
|
||||
#while True:
|
||||
# if server_task is not None and server_task.done():
|
||||
# print("Server task done")
|
||||
# print(server_task.exception())
|
||||
# server_task = None
|
||||
# if printer_task is not None and printer_task.done():
|
||||
# print("Printer task done")
|
||||
# print(printer_task.exception())
|
||||
# printer_task = None
|
||||
result = await printer.print_file(filename)
|
||||
if result:
|
||||
logging.info("Print started")
|
||||
else:
|
||||
logging.error("Failed to start print")
|
||||
sys.exit(1)
|
||||
|
||||
asyncio.run(main())
|
||||
async def do_upload(printer, filename, start_printing=False):
|
||||
if not os.path.exists(filename):
|
||||
logging.error(f"{filename} does not exist")
|
||||
sys.exit(1)
|
||||
|
||||
mqtt, http = await create_servers()
|
||||
connected = await printer.connect(mqtt, http)
|
||||
if not connected:
|
||||
logging.error("Failed to connect to printer")
|
||||
sys.exit(1)
|
||||
|
||||
#await printer.upload_file(filename, start_printing=start_printing)
|
||||
upload_task = asyncio.create_task(printer.upload_file(filename, start_printing=start_printing))
|
||||
# grab the first one, because we want the file size
|
||||
basename = filename.split('\\')[-1].split('/')[-1]
|
||||
file_size = os.path.getsize(filename)
|
||||
with alive_bar(total=file_size, manual=True, elapsed=False, title=basename) as bar:
|
||||
while True:
|
||||
if printer.file_transfer_future is None:
|
||||
await asyncio.sleep(0.1)
|
||||
continue
|
||||
progress = await printer.file_transfer_future
|
||||
if progress[0] < 0:
|
||||
logging.error("File upload failed!")
|
||||
sys.exit(1)
|
||||
bar(progress[0] / progress[1])
|
||||
if progress[0] >= progress[1]:
|
||||
break
|
||||
await upload_task
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(prog='cassini', description='ELEGOO Saturn printer control utility')
|
||||
parser.add_argument('-p', '--printer', help='ID of printer to target')
|
||||
parser.add_argument('--debug', help='Enable debug logging', action='store_true')
|
||||
|
||||
subparsers = parser.add_subparsers(title="commands", dest="command", required=True)
|
||||
|
||||
parser_status = subparsers.add_parser('status', help='Discover and display status of all printers')
|
||||
|
||||
parser_watch = subparsers.add_parser('watch', help='Continuously update the status of the selected printer')
|
||||
parser_watch.add_argument('--interval', type=int, help='Status update interval (seconds)', default=5)
|
||||
|
||||
parser_upload = subparsers.add_parser('upload', help='Upload a file to the printer')
|
||||
parser_upload.add_argument('--start-printing', help='Start printing after upload is complete', action='store_true')
|
||||
parser_upload.add_argument('filename', help='File to upload')
|
||||
|
||||
parser_print = subparsers.add_parser('print', help='Start printing a file already present on the printer')
|
||||
parser_print.add_argument('filename', help='File to print')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.debug:
|
||||
logging.getLogger().setLevel(logging.DEBUG)
|
||||
|
||||
printers = []
|
||||
printer = None
|
||||
if args.printer:
|
||||
printer = SaturnPrinter.find_printer(args.printer)
|
||||
printers = [printer]
|
||||
if printer is None:
|
||||
logging.error(f"No response from printer {args.printer}")
|
||||
sys.exit(1)
|
||||
else:
|
||||
printers = SaturnPrinter.find_printers()
|
||||
if len(printers) == 0:
|
||||
logging.error("No printers found on network")
|
||||
sys.exit(1)
|
||||
printer = printers[0]
|
||||
|
||||
if args.command == "status":
|
||||
do_status(printers)
|
||||
sys.exit(0)
|
||||
|
||||
if args.command == "watch":
|
||||
do_watch(printer, interval=args.interval)
|
||||
sys.exit(0)
|
||||
|
||||
logging.info(f'Printer: {printer.describe()} ({printer.addr[0]})')
|
||||
if printer.busy:
|
||||
logging.error(f'Printer is busy (status: {printer.current_status})')
|
||||
sys.exit(1)
|
||||
|
||||
if args.command == "upload":
|
||||
asyncio.run(do_upload(printer, args.filename, start_printing=args.start_printing))
|
||||
elif args.command == "print":
|
||||
asyncio.run(do_print(printer, args.filename))
|
||||
|
||||
main()
|
Reference in New Issue
Block a user