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