Compare commits

..

6 Commits

9 changed files with 219 additions and 23 deletions

3
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,3 @@
github: [jneilliii]
patreon: jneilliii
custom: ['https://www.paypal.me/jneilliii']

26
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,26 @@
---
name: Bug report
about: Please make sure to check other issues, including closed ones, prior to submitting a bug report. Debug logs are required and any bug report submitted without them will be ignored and closed.
title: "[BUG]: "
labels: ''
assignees: ''
---
**Describe the Bug**
<!-- A clear and concise description of what the bug is. -->
**Expected Behavior**
<!-- A clear and concise description of what you expected to happen. -->
**Debug Logs**
<!-- If logs are not included in your bug report it will be closed. Enable debug logging for octoprint.plugins.bambu_printer in OctoPrint's logging section of settings and recreate the issue then attach octoprint.log and plugin_bambu_printer_serial.log to this bug report. -->
**Screenshots**
<!-- Please share any relevant screenshots related to the issue. -->
**Printer and Plugin Setting Details**
* Printer model?
* Is your printer connected to Bambu Cloud?
* Is the plugin configured for local access only?

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Create a feature request for an improvement or change you'd like implemented.
title: "[FR]: "
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
**Describe the solution you'd like**
<!-- A clear and concise description of what you want to happen. -->
**Describe alternatives you've considered**
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
**Additional context**
<!-- Add any other context or screenshots about the feature request here. -->

16
.github/stale.yml vendored Normal file
View File

@ -0,0 +1,16 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 14
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- enhancement
- bug
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
activity in 14 days. It will be closed if no further activity occurs in 7 days.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

27
.github/workflows/stale.yml vendored Normal file
View File

@ -0,0 +1,27 @@
name: Mark Stale Issues
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * *"
permissions:
actions: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue has been automatically marked as stale because it has not had activity in 14 days. It will be closed if no further activity occurs in 7 days'
days-before-stale: 14
days-before-close: 7
stale-issue-label: 'stale'
days-before-issue-stale: 14
days-before-pr-stale: -1
days-before-issue-close: 7
days-before-pr-close: -1
exempt-issue-labels: 'bug,enhancement'
- uses: actions/checkout@v4
- uses: gautamkrishnar/keepalive-workflow@v2
with:
use_api: true

View File

@ -85,7 +85,7 @@ class BambuPrintPlugin(
"serial": "",
"host": "",
"access_code": "",
"username": "bblp",
"username": "octobambu",
"timelapse": False,
"bed_leveling": True,
"flow_cali": False,
@ -286,10 +286,10 @@ class BambuPrintPlugin(
def get_update_information(self):
return {
"bambu_printer": {
"displayName": "Bambu Printer",
"displayName": "Manus Bambu Printer",
"displayVersion": self._plugin_version,
"type": "github_release",
"user": "jneilliii",
"user": "ManuelW",
"repo": "OctoPrint-BambuPrinter",
"current": self._plugin_version,
"stable_branch": {
@ -304,6 +304,6 @@ class BambuPrintPlugin(
"comittish": ["rc", "master"],
}
],
"pip": "https://github.com/jneilliii/OctoPrint-BambuPrinter/archive/{target_version}.zip",
"pip": "https://gitlab.fire-devils.org/3D-Druck/OctoPrint-BambuPrinter/archive/{target_version}.zip",
}
}

View File

@ -14,6 +14,9 @@ from octoprint_bambu_printer.printer.print_job import PrintJob
from pybambu import BambuClient, commands
import logging
import logging.handlers
import paho.mqtt.client as mqtt
import json
import ssl
from octoprint.util import RepeatedTimer
@ -105,6 +108,10 @@ class BambuVirtualPrinter:
self._serial_io.start()
self._printer_thread.start()
self._mqtt_client = None
self._mqtt_connected = False
self._bambu_client = None
self._bambu_client: BambuClient = self._create_client_connection_async()
@property
@ -193,7 +200,7 @@ class BambuVirtualPrinter:
or print_job_state == "FAILED"
):
self.change_state(self._state_idle)
elif print_job_state == "RUNNING":
elif print_job_state == "RUNNING" or print_job_state == "PREPARE":
self.change_state(self._state_printing)
elif print_job_state == "PAUSE":
self.change_state(self._state_paused)
@ -220,6 +227,48 @@ class BambuVirtualPrinter:
self._log.debug(f"on connect called")
return on_connect
def _on_mqtt_connect(self, client, userdata, flags, rc):
self._log.debug(f"MQTT connected with result code: {rc}")
if rc == 0:
self._mqtt_connected = True
# Subscribe to the relevant topics for the Bambu printer
device_topic = f"device/{self._settings.get(['serial'])}/report"
client.subscribe(device_topic)
self._log.debug(f"Subscribed to topic: {device_topic}")
# Notify that we're connected
self.sendOk()
else:
self._mqtt_connected = False
self._log.error(f"Failed to connect to MQTT broker with result code: {rc}")
def _on_mqtt_disconnect(self, client, userdata, rc):
self._mqtt_connected = False
self._log.debug(f"MQTT disconnected with result code: {rc}")
def _on_mqtt_message(self, client, userdata, msg):
try:
# Decode message and update client data
payload = json.loads(msg.payload.decode('utf-8'))
# If this is a Bambu Lab printer message, process it
if 'print' in payload or 'info' in payload:
# Forward the message to pybambu for processing
if self._bambu_client:
self._bambu_client._process_message(msg.topic, payload)
# Trigger our update handler
if 'print' in payload:
self.new_update("event_printer_data_update")
if 'info' in payload and 'hms' in payload['info']:
self.new_update("event_hms_errors")
self._log.debug(f"MQTT message received on topic {msg.topic}")
except Exception as e:
self._log.error(f"Error processing MQTT message: {e}")
def _create_client_connection_async(self):
self._create_client_connection()
if self._bambu_client is None:
@ -237,31 +286,82 @@ class BambuVirtualPrinter:
self._log.debug(msg)
raise ValueError(msg)
self._log.debug(
f"connecting via local mqtt: {self._settings.get_boolean(['local_mqtt'])}"
)
use_local_mqtt = self._settings.get_boolean(['local_mqtt'])
self._log.debug(f"connecting via local mqtt: {use_local_mqtt}")
# Create a BambuClient but don't let it handle the MQTT connection
bambu_client = BambuClient(
device_type=self._settings.get(["device_type"]),
serial=self._settings.get(["serial"]),
host=self._settings.get(["host"]),
username=(
"bblp"
if self._settings.get_boolean(["local_mqtt"])
else self._settings.get(["username"])
),
username="bambuocto",
access_code=self._settings.get(["access_code"]),
local_mqtt=self._settings.get_boolean(["local_mqtt"]),
local_mqtt=use_local_mqtt,
region=self._settings.get(["region"]),
email=self._settings.get(["email"]),
auth_token=self._settings.get(["auth_token"]),
)
bambu_client.on_disconnect = self.on_disconnect(bambu_client.on_disconnect)
bambu_client.on_connect = self.on_connect(bambu_client.on_connect)
bambu_client.connect(callback=self.new_update)
self._log.info(f"bambu connection status: {bambu_client.connected}")
self.sendOk()
# Set up our own MQTT client
self._mqtt_client = mqtt.Client()
self._mqtt_client.on_connect = self._on_mqtt_connect
self._mqtt_client.on_disconnect = self._on_mqtt_disconnect
self._mqtt_client.on_message = self._on_mqtt_message
# Configure connection based on local or cloud
if use_local_mqtt:
host = self._settings.get(["host"])
port = 1883
username = "octobambu"
self._mqtt_client.username_pw_set(username)
else:
# Cloud connection settings
region = self._settings.get(["region"])
host = f"mqtt-{region}.bambulab.com"
port = 8883
username = self._settings.get(["email"])
password = self._settings.get(["auth_token"])
self._mqtt_client.username_pw_set(username, password)
self._mqtt_client.tls_set()
# Connect MQTT
try:
self._mqtt_client.connect(host, port, 60)
self._mqtt_client.loop_start()
self._log.info(f"MQTT client started with {host}:{port}")
except Exception as e:
self._log.error(f"Failed to connect to MQTT broker: {e}")
raise
# Inject our MQTT client into the BambuClient
bambu_client._mqtt_client = self._mqtt_client
bambu_client.connected = True
# Store the Bambu client
self._bambu_client = bambu_client
self._log.info(f"Bambu connection status: {bambu_client.connected}")
def publish_mqtt(self, topic, payload):
"""Publish a message to the MQTT broker"""
if self._mqtt_client and self._mqtt_connected:
return self._mqtt_client.publish(topic, json.dumps(payload))
return False
# Override BambuClient's publish method to use our MQTT client
def publish(self, command):
"""Publish a command using our MQTT client"""
if not self._mqtt_connected:
self._log.error("Cannot publish command: MQTT not connected")
return False
serial = self._settings.get(["serial"])
topic = f"device/{serial}/request"
return self.publish_mqtt(topic, command)
def __str__(self):
return "BAMBU(read_timeout={read_timeout},write_timeout={write_timeout},options={options})".format(
read_timeout=self.timeout,
@ -634,6 +734,9 @@ class BambuVirtualPrinter:
return False
def close(self):
if self._mqtt_client and self._mqtt_connected:
self._mqtt_client.loop_stop()
self._mqtt_client.disconnect()
if self.bambu_client.connected:
self.bambu_client.disconnect()
self.change_state(self._state_idle)

View File

@ -14,3 +14,4 @@ OctoPrint~=1.10.2
setuptools~=70.0.0
pyserial~=3.5
Flask~=2.2.5
paho-mqtt~=2.1.0

View File

@ -14,20 +14,20 @@ plugin_package = "octoprint_bambu_printer"
plugin_name = "OctoPrint-BambuPrinter"
# The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module
plugin_version = "0.1.6"
plugin_version = "1.0.0"
# The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin
# module
plugin_description = """Connects OctoPrint to BambuLabs printers."""
# The plugin's author. Can be overwritten within OctoPrint's internal data via __plugin_author__ in the plugin module
plugin_author = "jneilliii"
plugin_author = "ManuelW"
# The plugin's author's mail address.
plugin_author_email = "jneilliii+github@gmail.com"
plugin_author_email = "manuelw@example.com"
# The plugin's homepage URL. Can be overwritten within OctoPrint's internal data via __plugin_url__ in the plugin module
plugin_url = "https://github.com/jneilliii/OctoPrint-BambuPrinter"
plugin_url = "https://gitlab.fire-devils.org/3D-Druck/OctoPrint-BambuPrinter"
# The plugin's license. Can be overwritten within OctoPrint's internal data via __plugin_license__ in the plugin module
plugin_license = "AGPLv3"