Compare commits
7 Commits
0.1.5
...
3ccce10648
Author | SHA1 | Date | |
---|---|---|---|
3ccce10648 | |||
c99eb38655 | |||
698f8f4151 | |||
7a0293bac7 | |||
d0fd4a5434 | |||
3c218a548d | |||
03af51608d |
3
.github/FUNDING.yml
vendored
Normal file
3
.github/FUNDING.yml
vendored
Normal 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
26
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal 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?
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal 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
16
.github/stale.yml
vendored
Normal 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
27
.github/workflows/stale.yml
vendored
Normal 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
|
@ -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",
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
@ -580,8 +680,9 @@ class BambuVirtualPrinter:
|
||||
|
||||
def report_print_job_status(self):
|
||||
if self.current_print_job is not None:
|
||||
file_position = 1 if self.current_print_job.file_position == 0 else self.current_print_job.file_position
|
||||
self.sendIO(
|
||||
f"SD printing byte {self.current_print_job.file_position}"
|
||||
f"SD printing byte {file_position}"
|
||||
f"/{self.current_print_job.file_info.size}"
|
||||
)
|
||||
else:
|
||||
@ -633,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)
|
||||
|
@ -14,3 +14,4 @@ OctoPrint~=1.10.2
|
||||
setuptools~=70.0.0
|
||||
pyserial~=3.5
|
||||
Flask~=2.2.5
|
||||
paho-mqtt~=2.1.0
|
||||
|
8
setup.py
8
setup.py
@ -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.5"
|
||||
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"
|
||||
|
Reference in New Issue
Block a user