实现下位机版本检测升级功能以及优化断电续打
# Conflicts: # config/moonraker.conf resolved by f5461563b8a7a5a25470a8763b8513779dbff253 version # scripts/sync_dependencies.py resolved by f5461563b8a7a5a25470a8763b8513779dbff253 version
This commit is contained in:
parent
8633a9e349
commit
08648da7a4
@ -23,6 +23,8 @@ cors_domains:
|
|||||||
|
|
||||||
[octoprint_compat]
|
[octoprint_compat]
|
||||||
|
|
||||||
|
[firmware_manager]
|
||||||
|
|
||||||
[history]
|
[history]
|
||||||
|
|
||||||
[power Printer]
|
[power Printer]
|
||||||
@ -58,42 +60,35 @@ pin: ^!gpiochip4/gpio19
|
|||||||
debounce_period: .01
|
debounce_period: .01
|
||||||
minimum_event_time: 0
|
minimum_event_time: 0
|
||||||
on_press:
|
on_press:
|
||||||
{% set server_info = call_method("server.info") %}
|
{% do call_method("printer.gcode.script", script="TURN_OFF_HEATERS") %}
|
||||||
{% set server_info_data = server_info | tojson | fromjson %}
|
{% do call_method("printer.gcode.script", script="GET_TASKLINE") %}
|
||||||
{% if server_info_data['klippy_state'] == "ready" %}
|
{% set query_objs = {"print_stats": ["state"], "toolhead": ["extruder"], "virtual_sdcard": ["file_path", "file_position", "file_line"]} %}
|
||||||
{% set query_objs = {"print_stats": ["state"], "toolhead": ["extruder"], "gcode_move": ["gcode_position"], "virtual_sdcard": ["file_path"]} %}
|
|
||||||
{% set status = call_method("printer.objects.query", objects=query_objs) %}
|
{% set status = call_method("printer.objects.query", objects=query_objs) %}
|
||||||
{% do call_method("printer.emergency_stop") %}
|
{% do call_method("printer.emergency_stop") %}
|
||||||
{% set data = status | tojson | fromjson %}
|
{% set data = status | tojson | fromjson %}
|
||||||
{% set print_state = data['status']['print_stats']['state'] %}
|
{% set print_state = data['status']['print_stats']['state'] %}
|
||||||
# Judging the printer status
|
# Judging the printer status
|
||||||
{% if print_state | string == 'printing' or print_state | string == 'paused' %}
|
{% if print_state | string == 'printing' or print_state | string == 'paused' %}
|
||||||
{% set x_position = data['status']['gcode_move']['gcode_position'][0] | round(4) %}
|
|
||||||
{% set y_position = data['status']['gcode_move']['gcode_position'][1] | round(4) %}
|
|
||||||
{% set z_position = data['status']['gcode_move']['gcode_position'][2] | round(4) %}
|
|
||||||
{% set hotend = data['status']['toolhead']['extruder'] %}
|
{% set hotend = data['status']['toolhead']['extruder'] %}
|
||||||
|
{% set position = data['status']['virtual_sdcard']['file_position'] %}
|
||||||
|
{% set line = data['status']['virtual_sdcard']['file_line'] %}
|
||||||
{% set filepath = data['status']['virtual_sdcard']['file_path'] %}
|
{% set filepath = data['status']['virtual_sdcard']['file_path'] %}
|
||||||
{% set filename = filepath.split('/')[-1] %}
|
# save file position and line
|
||||||
# save position
|
{% do call_method("printer.gcode.script", script="SAVE_VARIABLE VARIABLE=power_resume_position VALUE=" + position | string) %}
|
||||||
{% if print_state | string == 'printing' %}
|
{% do call_method("printer.gcode.script", script="SAVE_VARIABLE VARIABLE=power_resume_line VALUE=" + line | string) %}
|
||||||
{% do call_method("printer.gcode.script", script="SAVE_VARIABLE VARIABLE=power_resume_x VALUE=" + x_position | string) %}
|
{% set script = "SAVE_VARIABLE VARIABLE=power_loss_paused VALUE=" ~ ("False" if print_state | string == 'printing' else "True") %}
|
||||||
{% do call_method("printer.gcode.script", script="SAVE_VARIABLE VARIABLE=power_resume_y VALUE=" + y_position | string) %}
|
{% if print_state | string in ['printing', 'paused'] %}
|
||||||
{% do call_method("printer.gcode.script", script="SAVE_VARIABLE VARIABLE=power_resume_z VALUE=" + z_position | string) %}
|
{% do call_method("printer.gcode.script", script=script) %}
|
||||||
{% do call_method("printer.gcode.script", script="SAVE_VARIABLE VARIABLE=power_loss_paused VALUE=False") %}
|
{% endif %}
|
||||||
{% elif print_state | string == 'paused' %}
|
|
||||||
{% do call_method("printer.gcode.script", script="SAVE_VARIABLE VARIABLE=power_loss_paused VALUE=True") %}
|
|
||||||
{% endif%}
|
|
||||||
# save extruder
|
# save extruder
|
||||||
{% do call_method("printer.gcode.script", script="SAVE_VARIABLE VARIABLE=power_resume_extruder VALUE=\"'" + hotend | string + "'\"") %}
|
{% do call_method("printer.gcode.script", script="SAVE_VARIABLE VARIABLE=power_resume_extruder VALUE=\"'" + hotend | string + "'\"") %}
|
||||||
# save file
|
# save file
|
||||||
{% do call_method("printer.gcode.script", script="SAVE_VARIABLE VARIABLE=filepath VALUE=\"'" + filepath | string + "'\"") %}
|
{% do call_method("printer.gcode.script", script="SAVE_VARIABLE VARIABLE=filepath VALUE=\"'" + filepath | string + "'\"") %}
|
||||||
{% do call_method("printer.gcode.script", script="SAVE_VARIABLE VARIABLE=last_file VALUE=\"'" + filename | string + "'\"") %}
|
save interrupt
|
||||||
# save interrupt
|
|
||||||
{% do call_method("printer.gcode.script", script="SAVE_VARIABLE VARIABLE=was_interrupted VALUE=True") %}
|
{% do call_method("printer.gcode.script", script="SAVE_VARIABLE VARIABLE=was_interrupted VALUE=True") %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% do call_method("printer.gcode.script", script="SAVE_VARIABLE VARIABLE=was_interrupted VALUE=False") %}
|
{% do call_method("printer.gcode.script", script="SAVE_VARIABLE VARIABLE=was_interrupted VALUE=False") %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
|
||||||
# shutdown
|
# shutdown
|
||||||
{% do call_method("machine.shutdown") %}
|
{% do call_method("machine.shutdown") %}
|
||||||
|
|
||||||
|
206
moonraker/components/firmware_manager.py
Normal file
206
moonraker/components/firmware_manager.py
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import asyncio
|
||||||
|
from .flash_tool import FlashTool
|
||||||
|
from ..confighelper import ConfigHelper
|
||||||
|
from ..common import KlippyState
|
||||||
|
from .klippy_apis import KlippyAPI
|
||||||
|
|
||||||
|
from typing import (
|
||||||
|
TYPE_CHECKING,
|
||||||
|
Any,
|
||||||
|
Dict,
|
||||||
|
)
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .machine import Machine
|
||||||
|
from .klippy_connection import KlippyConnection as Klippy
|
||||||
|
|
||||||
|
HOME = os.path.expanduser("~")
|
||||||
|
KLIPPER_DIR = os.path.join(HOME, "klipper/firmware")
|
||||||
|
MAIN_DEV = "/dev/ttyACM0"
|
||||||
|
SYSTEM_PYTHON = "python3"
|
||||||
|
|
||||||
|
class FirmwareUpdate:
|
||||||
|
def __init__(self, config: ConfigHelper) -> None:
|
||||||
|
self.server = config.get_server()
|
||||||
|
self.mcu_info: Dict[str, Dict[str, Any]] = {}
|
||||||
|
self._service_info: Dict[str, Any] = {}
|
||||||
|
self.min_version: str = ""
|
||||||
|
self.klipper_version: str = ""
|
||||||
|
self.current_progress = 0
|
||||||
|
self.updating = False
|
||||||
|
self.need_check_update = True
|
||||||
|
self.server.register_event_handler(
|
||||||
|
"server:klippy_started", self._on_klippy_startup)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def klippy_apis(self) -> KlippyAPI:
|
||||||
|
return self.server.lookup_component("klippy_apis")
|
||||||
|
|
||||||
|
def is_updating(self) -> bool:
|
||||||
|
return self.updating
|
||||||
|
|
||||||
|
async def _on_klippy_startup(self, state: KlippyState) -> None:
|
||||||
|
if not self.need_check_update or not self._is_firmware_dir_exists():
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
await self.build_mcu_info()
|
||||||
|
logging.info(f"{self.mcu_info}")
|
||||||
|
except Exception as e:
|
||||||
|
logging.exception(f"An error occurred during the building mcu info process: {e}")
|
||||||
|
for mcu_data in self.mcu_info.values():
|
||||||
|
if mcu_data.get('need_update', False):
|
||||||
|
await self.start_update()
|
||||||
|
break
|
||||||
|
|
||||||
|
async def _do_klipper_action(self, action: str) -> None:
|
||||||
|
try:
|
||||||
|
machine: Machine = self.server.lookup_component("machine")
|
||||||
|
await machine.do_service_action(action, "klipper")
|
||||||
|
logging.info(f"Klipper service {action}.")
|
||||||
|
except self.server.error:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _is_firmware_dir_exists(self):
|
||||||
|
return os.path.exists(KLIPPER_DIR)
|
||||||
|
|
||||||
|
async def start_update(self):
|
||||||
|
try:
|
||||||
|
self.updating = True
|
||||||
|
await self._do_klipper_action("stop")
|
||||||
|
await self.upgrade_needed_tool_mcus()
|
||||||
|
await self.upgrade_mcu()
|
||||||
|
await self._do_klipper_action("start")
|
||||||
|
self.updating = False
|
||||||
|
except Exception as e:
|
||||||
|
logging.exception(f"An error occurred during the update process: {e}")
|
||||||
|
self.updating = False
|
||||||
|
|
||||||
|
async def build_mcu_info(self) -> None:
|
||||||
|
printer_info: Dict[str, Any] = {}
|
||||||
|
cfg_status: Dict[str, Any] = {}
|
||||||
|
try:
|
||||||
|
printer_info = await self.klippy_apis.get_klippy_info()
|
||||||
|
cfg_status = await self.klippy_apis.query_objects({'configfile': None})
|
||||||
|
except self.server.error:
|
||||||
|
logging.exception("PanelDue initialization request failed")
|
||||||
|
config = cfg_status.get('configfile', {}).get('config', {})
|
||||||
|
self.klipper_version = printer_info.get("software_version", "").split('-')[0]
|
||||||
|
try:
|
||||||
|
self._build_basic_mcu_info(config)
|
||||||
|
await self._update_mcu_versions()
|
||||||
|
self._check_mcu_update_needed()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logging.exception(f"An error occurred while building MCU info: {e}")
|
||||||
|
|
||||||
|
def _build_basic_mcu_info(self, config: Dict[str, Any]) -> None:
|
||||||
|
for mcu, value in config.items():
|
||||||
|
if mcu.startswith("mcu") and "canbus_uuid" in value:
|
||||||
|
self.mcu_info[mcu] = {"canbus_uuid": value["canbus_uuid"]}
|
||||||
|
|
||||||
|
async def _update_mcu_versions(self) -> None:
|
||||||
|
for mcu in self.mcu_info:
|
||||||
|
try:
|
||||||
|
response = await self.klippy_apis.query_objects({mcu: None})
|
||||||
|
mcu_data = response.get(mcu, {})
|
||||||
|
mcu_version: str = mcu_data.get('mcu_version', '')
|
||||||
|
if mcu == "mcu":
|
||||||
|
self.min_version = mcu_data.get('min_firmware_version', "")
|
||||||
|
if mcu_version:
|
||||||
|
self.need_check_update = False
|
||||||
|
short_version: str = mcu_version.split('-')[0]
|
||||||
|
if short_version.lower().startswith('v'):
|
||||||
|
short_version = short_version[1:]
|
||||||
|
self.mcu_info[mcu]['mcu_version'] = short_version
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error querying {mcu}: {e}")
|
||||||
|
|
||||||
|
def _compare_versions(self, version1, version2):
|
||||||
|
v1_parts = [int(part) for part in version1.split('.') if part]
|
||||||
|
v2_parts = [int(part) for part in version2.split('.') if part]
|
||||||
|
|
||||||
|
max_length = max(len(v1_parts), len(v2_parts))
|
||||||
|
v1_parts.extend([0] * (max_length - len(v1_parts)))
|
||||||
|
v2_parts.extend([0] * (max_length - len(v2_parts)))
|
||||||
|
|
||||||
|
for i in range(max_length):
|
||||||
|
if v1_parts[i] < v2_parts[i]:
|
||||||
|
return -1
|
||||||
|
elif v1_parts[i] > v2_parts[i]:
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def _check_mcu_update_needed(self) -> None:
|
||||||
|
if self.klipper_version.lower().startswith('v'):
|
||||||
|
self.klipper_version = self.klipper_version[1:]
|
||||||
|
logging.info(f"min version: {self.min_version}")
|
||||||
|
logging.info(f"klipper version: {self.klipper_version}")
|
||||||
|
for mcu in self.mcu_info:
|
||||||
|
mcu_version = self.mcu_info[mcu].get('mcu_version', "")
|
||||||
|
|
||||||
|
mcu_vs_min = self._compare_versions(mcu_version, self.min_version)
|
||||||
|
mcu_vs_klipper = self._compare_versions(mcu_version, self.klipper_version)
|
||||||
|
|
||||||
|
if mcu_vs_min < 0 or mcu_vs_klipper > 0:
|
||||||
|
self.mcu_info[mcu]['need_update'] = True
|
||||||
|
else:
|
||||||
|
self.mcu_info[mcu]['need_update'] = False
|
||||||
|
|
||||||
|
async def upgrade_needed_tool_mcus(self):
|
||||||
|
firmware_mapping = {
|
||||||
|
"mcu L_tool": os.path.join(KLIPPER_DIR, "F072_L.bin"),
|
||||||
|
"mcu R_tool": os.path.join(KLIPPER_DIR, "F072_R.bin"),
|
||||||
|
"mcu tool": os.path.join(KLIPPER_DIR, "F072_L.bin")
|
||||||
|
}
|
||||||
|
for mcu_name, mcu_data in self.mcu_info.items():
|
||||||
|
if mcu_data.get('need_update', False) and mcu_name != "mcu":
|
||||||
|
firmware_path = firmware_mapping.get(mcu_name)
|
||||||
|
if not firmware_path:
|
||||||
|
logging.warning(f"No firmware specified for {mcu_name}, skipping upgrade.")
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
flash_tool = FlashTool(
|
||||||
|
self.server,
|
||||||
|
uuid = mcu_data['canbus_uuid'],
|
||||||
|
firmware = firmware_path
|
||||||
|
)
|
||||||
|
exit_code = await flash_tool.run()
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
if exit_code == 0:
|
||||||
|
logging.info(f"Upgrade operation for {mcu_name} succeeded, exit code: {exit_code}")
|
||||||
|
else:
|
||||||
|
logging.error(f"Upgrade operation for {mcu_name} failed, exit code: {exit_code}")
|
||||||
|
except Exception as e:
|
||||||
|
logging.exception(f"An exception occurred during the upgrade process for {mcu_name}: {e}")
|
||||||
|
|
||||||
|
async def upgrade_mcu(self):
|
||||||
|
for mcu_name, mcu_data in self.mcu_info.items():
|
||||||
|
if mcu_name == "mcu" and mcu_data.get('need_update', False):
|
||||||
|
try:
|
||||||
|
flash_tool = FlashTool(
|
||||||
|
self.server,
|
||||||
|
uuid=mcu_data['canbus_uuid'],
|
||||||
|
request_bootloader=True
|
||||||
|
)
|
||||||
|
exit_code = await flash_tool.run()
|
||||||
|
if exit_code != 0:
|
||||||
|
logging.error(f"Failed to request bootloader for {mcu_name}, exit code: {exit_code}")
|
||||||
|
continue
|
||||||
|
await asyncio.sleep(2)
|
||||||
|
flash_tool = FlashTool(
|
||||||
|
self.server,
|
||||||
|
device=MAIN_DEV,
|
||||||
|
firmware=os.path.join(KLIPPER_DIR, "F446.bin")
|
||||||
|
)
|
||||||
|
exit_code = await flash_tool.run()
|
||||||
|
if exit_code == 0:
|
||||||
|
logging.info(f"Upgrade operation for {mcu_name} succeeded, exit code: {exit_code}")
|
||||||
|
else:
|
||||||
|
logging.error(f"Upgrade operation for {mcu_name} failed, exit code: {exit_code}")
|
||||||
|
except Exception as e:
|
||||||
|
logging.exception(f"An exception occurred during the upgrade process for {mcu_name}: {e}")
|
||||||
|
|
||||||
|
def load_component(config: ConfigHelper) -> FirmwareUpdate:
|
||||||
|
return FirmwareUpdate(config)
|
1201
moonraker/components/flash_tool.py
Normal file
1201
moonraker/components/flash_tool.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -39,6 +39,7 @@ if TYPE_CHECKING:
|
|||||||
from .http_client import HttpClient
|
from .http_client import HttpClient
|
||||||
from .klippy_connection import KlippyConnection
|
from .klippy_connection import KlippyConnection
|
||||||
from .shell_command import ShellCommandFactory as ShellCommand
|
from .shell_command import ShellCommandFactory as ShellCommand
|
||||||
|
from .firmware_manager import FirmwareUpdate
|
||||||
|
|
||||||
class PrinterPower:
|
class PrinterPower:
|
||||||
def __init__(self, config: ConfigHelper) -> None:
|
def __init__(self, config: ConfigHelper) -> None:
|
||||||
@ -411,6 +412,12 @@ class PowerDevice:
|
|||||||
raise self.server.error(
|
raise self.server.error(
|
||||||
f"Unable to change power for {self.name} "
|
f"Unable to change power for {self.name} "
|
||||||
"while printing")
|
"while printing")
|
||||||
|
updata: FirmwareUpdate
|
||||||
|
updata = self.server.lookup_component("firmware_manager")
|
||||||
|
if updata.is_updating():
|
||||||
|
raise self.server.error(
|
||||||
|
f"Unable to change power for {self.name} "
|
||||||
|
"while updating")
|
||||||
ret = self.set_power(req)
|
ret = self.set_power(req)
|
||||||
if ret is not None:
|
if ret is not None:
|
||||||
await ret
|
await ret
|
||||||
|
@ -258,6 +258,9 @@ class AppDeploy(BaseDeploy):
|
|||||||
if svc == "klipper":
|
if svc == "klipper":
|
||||||
kconn: Klippy = self.server.lookup_component("klippy_connection")
|
kconn: Klippy = self.server.lookup_component("klippy_connection")
|
||||||
svc = kconn.unit_name
|
svc = kconn.unit_name
|
||||||
|
firmware_manager = self.server.lookup_component("firmware_manager", None)
|
||||||
|
if firmware_manager is not None:
|
||||||
|
firmware_manager.need_check_update = True
|
||||||
await machine.do_service_action("restart", svc)
|
await machine.do_service_action("restart", svc)
|
||||||
|
|
||||||
async def _read_system_dependencies(self) -> List[str]:
|
async def _read_system_dependencies(self) -> List[str]:
|
||||||
|
@ -101,6 +101,7 @@ class ZeroconfRegistrar:
|
|||||||
else:
|
else:
|
||||||
# Use the UUID. First 8 hex digits should be unique enough
|
# Use the UUID. First 8 hex digits should be unique enough
|
||||||
instance_name = f"Moonraker-{instance_uuid[:8]}"
|
instance_name = f"Moonraker-{instance_uuid[:8]}"
|
||||||
|
instance_name = "CreatBot"
|
||||||
hi = self.server.get_host_info()
|
hi = self.server.get_host_info()
|
||||||
host = self.mdns_name
|
host = self.mdns_name
|
||||||
zc_service_props = {
|
zc_service_props = {
|
||||||
@ -167,9 +168,9 @@ class ZeroconfRegistrar:
|
|||||||
|
|
||||||
|
|
||||||
SSDP_ADDR = ("239.255.255.250", 1900)
|
SSDP_ADDR = ("239.255.255.250", 1900)
|
||||||
SSDP_SERVER_ID = "Moonraker SSDP/UPNP Server"
|
SSDP_SERVER_ID = "CreatBot SSDP/UPNP Server"
|
||||||
SSDP_MAX_AGE = 1800
|
SSDP_MAX_AGE = 1800
|
||||||
SSDP_DEVICE_TYPE = "urn:arksine.github.io:device:Moonraker:1"
|
SSDP_DEVICE_TYPE = "urn:creatbot-com:device:3dprinter:2"
|
||||||
SSDP_DEVICE_XML = """
|
SSDP_DEVICE_XML = """
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<root xmlns="urn:schemas-upnp-org:device-1-0" configId="{config_id}">
|
<root xmlns="urn:schemas-upnp-org:device-1-0" configId="{config_id}">
|
||||||
@ -180,12 +181,12 @@ SSDP_DEVICE_XML = """
|
|||||||
<device>
|
<device>
|
||||||
<deviceType>{device_type}</deviceType>
|
<deviceType>{device_type}</deviceType>
|
||||||
<friendlyName>{friendly_name}</friendlyName>
|
<friendlyName>{friendly_name}</friendlyName>
|
||||||
<manufacturer>Arksine</manufacturer>
|
<manufacturer>CreatBot</manufacturer>
|
||||||
<manufacturerURL>https://github.com/Arksine/moonraker</manufacturerURL>
|
<manufacturerURL>https://www.creatbot.com</manufacturerURL>
|
||||||
<modelDescription>API Server for Klipper</modelDescription>
|
<modelDescription>API Server for Klipper</modelDescription>
|
||||||
<modelName>Moonraker</modelName>
|
<modelName>CreatBot</modelName>
|
||||||
<modelNumber>{model_number}</modelNumber>
|
<modelNumber>{model_number}</modelNumber>
|
||||||
<modelURL>https://github.com/Arksine/moonraker</modelURL>
|
<modelURL>https://github.com/CreatBotOfficail</modelURL>
|
||||||
<serialNumber>{serial_number}</serialNumber>
|
<serialNumber>{serial_number}</serialNumber>
|
||||||
<UDN>uuid:{device_uuid}</UDN>
|
<UDN>uuid:{device_uuid}</UDN>
|
||||||
<presentationURL>{presentation_url}</presentationURL>
|
<presentationURL>{presentation_url}</presentationURL>
|
||||||
@ -197,7 +198,10 @@ class SSDPServer(asyncio.protocols.DatagramProtocol):
|
|||||||
def __init__(self, config: ConfigHelper) -> None:
|
def __init__(self, config: ConfigHelper) -> None:
|
||||||
self.server = config.get_server()
|
self.server = config.get_server()
|
||||||
self.unique_id = uuid.UUID(self.server.get_app_args()["instance_uuid"])
|
self.unique_id = uuid.UUID(self.server.get_app_args()["instance_uuid"])
|
||||||
self.name: str = "Moonraker"
|
self.name: str = "CreatBot"
|
||||||
|
machine: Machine = self.server.lookup_component("machine")
|
||||||
|
self.serial_number = machine.get_system_info().get("cpu_info", {}).get("serial_number", "N/A")
|
||||||
|
self.serial_number = self.serial_number[1:].upper()
|
||||||
self.base_url: str = ""
|
self.base_url: str = ""
|
||||||
self.response_headers: List[str] = []
|
self.response_headers: List[str] = []
|
||||||
self.registered: bool = False
|
self.registered: bool = False
|
||||||
@ -280,10 +284,18 @@ class SSDPServer(asyncio.protocols.DatagramProtocol):
|
|||||||
if len(name) > 64:
|
if len(name) > 64:
|
||||||
name = name[:64]
|
name = name[:64]
|
||||||
self.name = name
|
self.name = name
|
||||||
|
model = self.name
|
||||||
|
device_name = self.name
|
||||||
|
if "(" in self.name:
|
||||||
|
model = self.name.split("(", 1)[-1].rsplit("-", 1)[0].rstrip(")")
|
||||||
|
elif "-" in self.name:
|
||||||
|
model = self.name.rsplit("-", 1)[0]
|
||||||
|
if "(" in self.name and ")" in self.name:
|
||||||
|
device_name = self.name.split("(", 1)[1].split(")", 1)[0]
|
||||||
app: MoonrakerApp = self.server.lookup_component("application")
|
app: MoonrakerApp = self.server.lookup_component("application")
|
||||||
self.base_url = f"http://{host_name_or_ip}:{port}{app.route_prefix}"
|
self.base_url = f"http://{host_name_or_ip}"
|
||||||
self.response_headers = [
|
self.response_headers = [
|
||||||
f"USN: uuid:{self.unique_id}::upnp:rootdevice",
|
f"USN: uuid:{self.serial_number}::upnp:rootdevice::urn:creatbot-com:device:3dprinter:2",
|
||||||
f"LOCATION: {self.base_url}/server/zeroconf/ssdp",
|
f"LOCATION: {self.base_url}/server/zeroconf/ssdp",
|
||||||
"ST: upnp:rootdevice",
|
"ST: upnp:rootdevice",
|
||||||
"EXT:",
|
"EXT:",
|
||||||
@ -291,6 +303,8 @@ class SSDPServer(asyncio.protocols.DatagramProtocol):
|
|||||||
f"CACHE-CONTROL: max-age={SSDP_MAX_AGE}",
|
f"CACHE-CONTROL: max-age={SSDP_MAX_AGE}",
|
||||||
f"BOOTID.UPNP.ORG: {self.boot_id}",
|
f"BOOTID.UPNP.ORG: {self.boot_id}",
|
||||||
f"CONFIGID.UPNP.ORG: {self.config_id}",
|
f"CONFIGID.UPNP.ORG: {self.config_id}",
|
||||||
|
f"DEVICE-MODEL: {model}",
|
||||||
|
f"DEVICE-NAME: {device_name}",
|
||||||
]
|
]
|
||||||
self.registered = True
|
self.registered = True
|
||||||
advertisements = self._build_notifications("ssdp:alive")
|
advertisements = self._build_notifications("ssdp:alive")
|
||||||
@ -302,14 +316,20 @@ class SSDPServer(asyncio.protocols.DatagramProtocol):
|
|||||||
|
|
||||||
async def _handle_xml_request(self, web_request: WebRequest) -> str:
|
async def _handle_xml_request(self, web_request: WebRequest) -> str:
|
||||||
if not self.registered:
|
if not self.registered:
|
||||||
raise self.server.error("Moonraker SSDP Device not registered", 404)
|
raise self.server.error("CreatBot SSDP Device not registered", 404)
|
||||||
app_args = self.server.get_app_args()
|
app_args = self.server.get_app_args()
|
||||||
|
if "(" in self.name:
|
||||||
|
model = self.name.split("(", 1)[-1].rsplit("-", 1)[0].rstrip(")")
|
||||||
|
elif "-" in self.name:
|
||||||
|
model = self.name.rsplit("-", 1)[0]
|
||||||
|
else:
|
||||||
|
model = self.name
|
||||||
return SSDP_DEVICE_XML.format(
|
return SSDP_DEVICE_XML.format(
|
||||||
device_type=SSDP_DEVICE_TYPE,
|
device_type=SSDP_DEVICE_TYPE,
|
||||||
config_id=str(self.config_id),
|
config_id=str(self.config_id),
|
||||||
friendly_name=self.name,
|
friendly_name=self.name,
|
||||||
model_number=app_args["software_version"],
|
model_number=model,
|
||||||
serial_number=self.unique_id.hex,
|
serial_number=self.serial_number,
|
||||||
device_uuid=str(self.unique_id),
|
device_uuid=str(self.unique_id),
|
||||||
presentation_url=self.base_url
|
presentation_url=self.base_url
|
||||||
)
|
)
|
||||||
@ -360,7 +380,7 @@ class SSDPServer(asyncio.protocols.DatagramProtocol):
|
|||||||
):
|
):
|
||||||
# Not a discovery request
|
# Not a discovery request
|
||||||
return
|
return
|
||||||
if headers.get("ST") not in ["upnp:rootdevice", "ssdp:all"]:
|
if headers.get("ST") not in ["upnp:rootdevice", "ssdp:all", "urn:creatbot-com:device:3dprinter:2",]:
|
||||||
# Service Type doesn't apply
|
# Service Type doesn't apply
|
||||||
return
|
return
|
||||||
if self.response_handle is not None:
|
if self.response_handle is not None:
|
||||||
@ -390,7 +410,7 @@ class SSDPServer(asyncio.protocols.DatagramProtocol):
|
|||||||
notify_types = [
|
notify_types = [
|
||||||
("upnp:rootdevice", f"uuid:{self.unique_id}::upnp:rootdevice"),
|
("upnp:rootdevice", f"uuid:{self.unique_id}::upnp:rootdevice"),
|
||||||
(f"uuid:{self.unique_id}", f"uuid:{self.unique_id}"),
|
(f"uuid:{self.unique_id}", f"uuid:{self.unique_id}"),
|
||||||
(SSDP_DEVICE_TYPE, f"uuid:{self.unique_id}::{SSDP_DEVICE_TYPE}")
|
(SSDP_DEVICE_TYPE, f"uuid:{self.serial_number}::{SSDP_DEVICE_TYPE}"),
|
||||||
]
|
]
|
||||||
for (nt, usn) in notify_types:
|
for (nt, usn) in notify_types:
|
||||||
notifications.append(
|
notifications.append(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user