From 00febb92b2f2061371766b3ac5b31692302cf464 Mon Sep 17 00:00:00 2001 From: TheHolyRoger Date: Wed, 3 Aug 2022 19:34:41 +0100 Subject: [PATCH 1/8] Add Event publishing (MQTT etc) --- octoprint_smart_filament_sensor/__init__.py | 41 ++++++++++++++++++- .../smartfilamentsensor_settings.jinja2 | 19 +++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/octoprint_smart_filament_sensor/__init__.py b/octoprint_smart_filament_sensor/__init__.py index c99632a..b0733ac 100644 --- a/octoprint_smart_filament_sensor/__init__.py +++ b/octoprint_smart_filament_sensor/__init__.py @@ -1,7 +1,7 @@ # coding=utf-8 from __future__ import absolute_import import octoprint.plugin -from octoprint.events import Events +from octoprint.events import Events, eventManager import RPi.GPIO as GPIO from time import sleep from datetime import datetime @@ -10,6 +10,12 @@ from octoprint_smart_filament_sensor.filament_motion_sensor_timeout_detection import FilamentMotionSensorTimeoutDetection from octoprint_smart_filament_sensor.data import SmartFilamentSensorDetectionData +PLUGIN_KEY_PREFIX = "SmartFilamentSensor_" + +EVENT_KEY_MOVEMENT = "Movement" +EVENT_KEY_FILAMENT_CHANGE = "FilamentChange" +EVENT_KEY_REMAIN_RATIO = "RemainRatio" + class SmartFilamentSensor(octoprint.plugin.StartupPlugin, octoprint.plugin.EventHandlerPlugin, octoprint.plugin.TemplatePlugin, @@ -57,6 +63,16 @@ def pause_command(self): def motion_sensor_detection_distance(self): return int(self._settings.get(["motion_sensor_detection_distance"])) +#Event Publishing + + @property + def enable_event_publishing(self): + return self._settings.get_boolean(["enable_event_publishing"]) + + @property + def enable_publish_remaining_ratio(self): + return self._settings.get_boolean(["enable_publish_remaining_ratio"]) + #Timeout detection @property def motion_sensor_max_not_moving(self): @@ -117,6 +133,8 @@ def get_settings_defaults(self): motion_sensor_enabled = True, #Sensor detection is enabled by default motion_sensor_pin=-1, # Default is no pin detection_method = 0, # 0 = timeout detection, 1 = distance detection + enable_event_publishing = True, + enable_publish_remaining_ratio = True, # Distance detection motion_sensor_detection_distance = 15, # Recommended detection distance from Marlin would be 7 @@ -202,15 +220,18 @@ def printer_change_filament (self): # Check if stop signal was already sent if(not self.send_code): self._logger.error("Motion sensor detected no movement") + self._sendDataToClient(EVENT_KEY_MOVEMENT, dict(movement_detected=False), skip_check=True) self._logger.info("Pause command: " + self.pause_command) self._printer.commands(self.pause_command) self.send_code = True + self._sendDataToClient(EVENT_KEY_FILAMENT_CHANGE, dict(printer_change_filament=True), skip_check=True) self._data.filament_moving = False self.lastE = -1 # Set to -1 so it ignores the first test then continues # Reset the distance, if the remaining distance is smaller than the new value def reset_distance (self, pPin): self._logger.debug("Motion sensor detected movement") + self._sendDataToClient(EVENT_KEY_MOVEMENT, dict(movement_detected=True), skip_check=True) self.send_code = False self.last_movement_time = datetime.now() if(self._data.remaining_distance < self.motion_sensor_detection_distance): @@ -232,6 +253,13 @@ def reset_remainin_distance(self): def calc_distance(self, pE): if (self.detection_method == 1): + if self.enable_publish_remaining_ratio: + try: + remain_ratio = (self._data.remaining_distance / self.motion_sensor_detection_distance) + self._sendDataToClient(EVENT_KEY_REMAIN_RATIO, dict(remaining_ratio=remain_ratio)) + except Exception as e: + self._logger.error(f"Error in publish ratio: {e}") + # First check if need continue after last move if(self._data.remaining_distance > 0): @@ -274,6 +302,17 @@ def calc_distance(self, pE): else: self._logger.debug("Ignored pause command due to 5 second rule") + _lastSendClientData = dict() + + def _sendDataToClient(self, event_id, dataDict, skip_check=False): + if self.enable_event_publishing: + if (self._lastSendClientData != dataDict) or skip_check: + eventKey = PLUGIN_KEY_PREFIX + event_id + eventManager().fire(eventKey, dataDict) + self._lastSendClientData = dataDict + else: + self._logger.info("Ignoring send data, duplicated dict:" + str(dataDict)) + def updateToUi(self): self._plugin_manager.send_plugin_message(self._identifier, self._data.toJSON()) diff --git a/octoprint_smart_filament_sensor/templates/smartfilamentsensor_settings.jinja2 b/octoprint_smart_filament_sensor/templates/smartfilamentsensor_settings.jinja2 index ab252cf..e319638 100644 --- a/octoprint_smart_filament_sensor/templates/smartfilamentsensor_settings.jinja2 +++ b/octoprint_smart_filament_sensor/templates/smartfilamentsensor_settings.jinja2 @@ -81,6 +81,25 @@ GCode commands that are sent to the printer are interpreted. Don't choose this value too small, because it could make the detection too sensitive. + +
{{ _('Advanced') }}
+ +
+
+ +
+
+ +
+
+ +
+
+
{{_('Connection Test') }}
From 0f65a0cbac8ad0f0f52a544d2a6fddc5e45cd05d Mon Sep 17 00:00:00 2001 From: TheHolyRoger Date: Wed, 3 Aug 2022 19:38:07 +0100 Subject: [PATCH 2/8] Add option to skip pause while moving --- octoprint_smart_filament_sensor/__init__.py | 10 ++++++++++ .../templates/smartfilamentsensor_settings.jinja2 | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/octoprint_smart_filament_sensor/__init__.py b/octoprint_smart_filament_sensor/__init__.py index b0733ac..c2abcf2 100644 --- a/octoprint_smart_filament_sensor/__init__.py +++ b/octoprint_smart_filament_sensor/__init__.py @@ -14,6 +14,7 @@ EVENT_KEY_MOVEMENT = "Movement" EVENT_KEY_FILAMENT_CHANGE = "FilamentChange" +EVENT_KEY_PAUSE_IGNORED = "PauseIgnored" EVENT_KEY_REMAIN_RATIO = "RemainRatio" class SmartFilamentSensor(octoprint.plugin.StartupPlugin, @@ -58,6 +59,10 @@ def motion_sensor_enabled(self): def pause_command(self): return self._settings.get(["pause_command"]) + @property + def skip_pause_while_moving(self): + return self._settings.get_boolean(["skip_pause_while_moving"]) + #Distance detection @property def motion_sensor_detection_distance(self): @@ -135,6 +140,7 @@ def get_settings_defaults(self): detection_method = 0, # 0 = timeout detection, 1 = distance detection enable_event_publishing = True, enable_publish_remaining_ratio = True, + skip_pause_while_moving = False, # Distance detection motion_sensor_detection_distance = 15, # Recommended detection distance from Marlin would be 7 @@ -295,6 +301,10 @@ def calc_distance(self, pE): ) self._data.remaining_distance = (self._data.remaining_distance - deltaDistance) + elif self._data.filament_moving and self.skip_pause_while_moving: + self._sendDataToClient(EVENT_KEY_PAUSE_IGNORED, dict(pause_ignored=True)) + self._logger.debug("Ignored pause command due to filament moving") + self.reset_distance(None) else: # Only pause the print if its been over 5 seconds since the last movement. Stops pausing when the CPU gets hung up. if (datetime.now() - self.last_movement_time).total_seconds() > 10: diff --git a/octoprint_smart_filament_sensor/templates/smartfilamentsensor_settings.jinja2 b/octoprint_smart_filament_sensor/templates/smartfilamentsensor_settings.jinja2 index e319638..32f7144 100644 --- a/octoprint_smart_filament_sensor/templates/smartfilamentsensor_settings.jinja2 +++ b/octoprint_smart_filament_sensor/templates/smartfilamentsensor_settings.jinja2 @@ -83,6 +83,14 @@
{{ _('Advanced') }}
+ +
+
+ +
+
From 28dc66aff31f025d2a8a8ee5509f145ac3e4f6bb Mon Sep 17 00:00:00 2001 From: TheHolyRoger Date: Wed, 3 Aug 2022 21:14:55 +0100 Subject: [PATCH 3/8] Add two more areas to publish movement event --- octoprint_smart_filament_sensor/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/octoprint_smart_filament_sensor/__init__.py b/octoprint_smart_filament_sensor/__init__.py index c2abcf2..b0bf44b 100644 --- a/octoprint_smart_filament_sensor/__init__.py +++ b/octoprint_smart_filament_sensor/__init__.py @@ -118,6 +118,7 @@ def _setup_sensor(self): if self.motion_sensor_enabled == False: self._logger.info("Motion sensor is deactivated") + self._sendDataToClient(EVENT_KEY_MOVEMENT, dict(movement_detected=False), skip_check=True) self._data.filament_moving = False self.motion_sensor_thread = None @@ -211,6 +212,7 @@ def motion_sensor_start(self): self._logger.info("Motion sensor started: Timeout detection") self.send_code = False + self._sendDataToClient(EVENT_KEY_MOVEMENT, dict(movement_detected=True), skip_check=True) self._data.filament_moving = True # Stop the motion_sensor thread From 4a1d444723ac0b37de05b71aed02079a761d9453 Mon Sep 17 00:00:00 2001 From: TheHolyRoger Date: Wed, 3 Aug 2022 21:18:30 +0100 Subject: [PATCH 4/8] Fix ratio rounding --- octoprint_smart_filament_sensor/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/octoprint_smart_filament_sensor/__init__.py b/octoprint_smart_filament_sensor/__init__.py index b0bf44b..041478a 100644 --- a/octoprint_smart_filament_sensor/__init__.py +++ b/octoprint_smart_filament_sensor/__init__.py @@ -263,7 +263,7 @@ def calc_distance(self, pE): if self.enable_publish_remaining_ratio: try: - remain_ratio = (self._data.remaining_distance / self.motion_sensor_detection_distance) + remain_ratio = (int((self._data.remaining_distance / self.motion_sensor_detection_distance) * 1e4) / 1e4) self._sendDataToClient(EVENT_KEY_REMAIN_RATIO, dict(remaining_ratio=remain_ratio)) except Exception as e: self._logger.error(f"Error in publish ratio: {e}") From b74f1e8789a8526ef9806fbf4e931e95aa703408 Mon Sep 17 00:00:00 2001 From: TheHolyRoger Date: Fri, 5 Aug 2022 17:19:27 +0100 Subject: [PATCH 5/8] Reset events on start --- octoprint_smart_filament_sensor/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/octoprint_smart_filament_sensor/__init__.py b/octoprint_smart_filament_sensor/__init__.py index 041478a..43bd205 100644 --- a/octoprint_smart_filament_sensor/__init__.py +++ b/octoprint_smart_filament_sensor/__init__.py @@ -212,6 +212,9 @@ def motion_sensor_start(self): self._logger.info("Motion sensor started: Timeout detection") self.send_code = False + if self.skip_pause_while_moving: + self._sendDataToClient(EVENT_KEY_PAUSE_IGNORED, dict(pause_ignored=False)) + self._sendDataToClient(EVENT_KEY_FILAMENT_CHANGE, dict(printer_change_filament=False), skip_check=True) self._sendDataToClient(EVENT_KEY_MOVEMENT, dict(movement_detected=True), skip_check=True) self._data.filament_moving = True From c7dddaa439ccd3c92c248a6a5125852406dd7525 Mon Sep 17 00:00:00 2001 From: TheHolyRoger Date: Fri, 5 Aug 2022 20:15:19 +0100 Subject: [PATCH 6/8] Fix mac ratio num --- octoprint_smart_filament_sensor/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/octoprint_smart_filament_sensor/__init__.py b/octoprint_smart_filament_sensor/__init__.py index 43bd205..47b7e3b 100644 --- a/octoprint_smart_filament_sensor/__init__.py +++ b/octoprint_smart_filament_sensor/__init__.py @@ -266,7 +266,7 @@ def calc_distance(self, pE): if self.enable_publish_remaining_ratio: try: - remain_ratio = (int((self._data.remaining_distance / self.motion_sensor_detection_distance) * 1e4) / 1e4) + remain_ratio = min((int((self._data.remaining_distance / self.motion_sensor_detection_distance) * 1e4) / 1e4), 1.0) self._sendDataToClient(EVENT_KEY_REMAIN_RATIO, dict(remaining_ratio=remain_ratio)) except Exception as e: self._logger.error(f"Error in publish ratio: {e}") From 7b6aba94614dd0d071427e9719349a19d7422f09 Mon Sep 17 00:00:00 2001 From: TheHolyRoger Date: Mon, 29 Aug 2022 19:44:46 +0100 Subject: [PATCH 7/8] Fix logging level in dup dict --- octoprint_smart_filament_sensor/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/octoprint_smart_filament_sensor/__init__.py b/octoprint_smart_filament_sensor/__init__.py index 47b7e3b..b06ea80 100644 --- a/octoprint_smart_filament_sensor/__init__.py +++ b/octoprint_smart_filament_sensor/__init__.py @@ -326,7 +326,7 @@ def _sendDataToClient(self, event_id, dataDict, skip_check=False): eventManager().fire(eventKey, dataDict) self._lastSendClientData = dataDict else: - self._logger.info("Ignoring send data, duplicated dict:" + str(dataDict)) + self._logger.debug("Ignoring send data, duplicated dict:" + str(dataDict)) def updateToUi(self): self._plugin_manager.send_plugin_message(self._identifier, self._data.toJSON()) From 05dbba81b850ef98128e4a2530eec491339f2360 Mon Sep 17 00:00:00 2001 From: TheHolyRoger Date: Fri, 10 Feb 2023 12:55:50 +0000 Subject: [PATCH 8/8] Add configurable interval between remaining ratio publishing --- octoprint_smart_filament_sensor/__init__.py | 26 ++++++++++++++++--- .../smartfilamentsensor_settings.jinja2 | 12 +++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/octoprint_smart_filament_sensor/__init__.py b/octoprint_smart_filament_sensor/__init__.py index b06ea80..763cc5d 100644 --- a/octoprint_smart_filament_sensor/__init__.py +++ b/octoprint_smart_filament_sensor/__init__.py @@ -23,6 +23,7 @@ class SmartFilamentSensor(octoprint.plugin.StartupPlugin, octoprint.plugin.SettingsPlugin, octoprint.plugin.AssetPlugin, octoprint.plugin.SimpleApiPlugin): + _last_event_publish_data = dict() def initialize(self): self._logger.info("Running RPi.GPIO version '{0}'".format(GPIO.VERSION)) @@ -32,6 +33,8 @@ def initialize(self): self.print_started = False self.last_movement_time = None + self._last_event_publish_data = dict() + self._last_event_publish_time = None self.lastE = -1 self.currentE = -1 self.START_DISTANCE_OFFSET = 7 @@ -78,6 +81,10 @@ def enable_event_publishing(self): def enable_publish_remaining_ratio(self): return self._settings.get_boolean(["enable_publish_remaining_ratio"]) + @property + def event_publish_interval_remaining_ratio(self): + return int(self._settings.get(["event_publish_interval_remaining_ratio"])) + #Timeout detection @property def motion_sensor_max_not_moving(self): @@ -141,6 +148,7 @@ def get_settings_defaults(self): detection_method = 0, # 0 = timeout detection, 1 = distance detection enable_event_publishing = True, enable_publish_remaining_ratio = True, + event_publish_interval_remaining_ratio = 5, skip_pause_while_moving = False, # Distance detection @@ -317,14 +325,26 @@ def calc_distance(self, pE): else: self._logger.debug("Ignored pause command due to 5 second rule") - _lastSendClientData = dict() + def _checkShouldPublish(self, event_id, dataDict, skip_check=False): + if skip_check: + return True + if self._last_event_publish_data != dataDict: + if event_id != EVENT_KEY_REMAIN_RATIO: + return True + if not self._last_event_publish_time: + return True + last_publish_diff = (datetime.now() - self._last_event_publish_time).total_seconds() + if last_publish_diff > self.event_publish_interval_remaining_ratio: + return True + return False def _sendDataToClient(self, event_id, dataDict, skip_check=False): if self.enable_event_publishing: - if (self._lastSendClientData != dataDict) or skip_check: + if self._checkShouldPublish(event_id, dataDict, skip_check): eventKey = PLUGIN_KEY_PREFIX + event_id eventManager().fire(eventKey, dataDict) - self._lastSendClientData = dataDict + self._last_event_publish_data = dataDict + self._last_event_publish_time = datetime.now() else: self._logger.debug("Ignoring send data, duplicated dict:" + str(dataDict)) diff --git a/octoprint_smart_filament_sensor/templates/smartfilamentsensor_settings.jinja2 b/octoprint_smart_filament_sensor/templates/smartfilamentsensor_settings.jinja2 index 32f7144..14567dd 100644 --- a/octoprint_smart_filament_sensor/templates/smartfilamentsensor_settings.jinja2 +++ b/octoprint_smart_filament_sensor/templates/smartfilamentsensor_settings.jinja2 @@ -93,6 +93,7 @@
+
+
+ +
+ +
+
+ + sec +
+
+
{{_('Connection Test') }}