Skip to content

Commit

Permalink
save progress - layer status updating
Browse files Browse the repository at this point in the history
  • Loading branch information
aarontuftss committed May 9, 2023
1 parent 9d912c4 commit 567635c
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 11 deletions.
18 changes: 9 additions & 9 deletions octoprint-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,16 @@ server:
tracking: null
temperature:
profiles:
- bed: 100
chamber: null
extruder: 210
name: ABS
- bed: 60
chamber: null
extruder: 180
name: PLA
- bed: 100
chamber: null
extruder: 210
name: ABS
- bed: 60
chamber: null
extruder: 180
name: PLA
webcam:
ffmpeg: /usr/bin/avconv
snapshot: http://mjpeg:8080/?action=snapshot
stream: http://localhost:8080/?action=stream
streamRatio: '4:3'
streamRatio: "4:3"
98 changes: 97 additions & 1 deletion octoprint_obico/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
from .printer_discovery import PrinterDiscovery
from .gcode_hooks import GCodeHooks

import octoprint.filemanager
import re

import octoprint.plugin

__python_version__ = 3 if sys.version_info >= (3, 0) else 2
Expand All @@ -52,6 +55,36 @@
_print_job_tracker = PrintJobTracker()


class GcodePreProcessor(octoprint.filemanager.util.LineProcessorStream):

def __init__(self, fileBufferedReader, layer_indicator_patterns ):
super(GcodePreProcessor, self).__init__(fileBufferedReader)
self.layer_indicator_patterns = layer_indicator_patterns
self.python_version = __python_version__
self.layer_count = 0

def process_line(self, line):
if not len(line):
return None

if self.python_version == 3:
line = line.decode('utf-8').lstrip()
else:
line = line.lstrip()

for layer_indicator_pattern in self.layer_indicator_patterns:

if re.match(layer_indicator_pattern['regx'], line):
self.layer_count += 1
line = line + "M117 DASHBOARD_LAYER_INDICATOR " + str(self.layer_count) + "\r\n"

break

line = line.encode('utf-8')

return line


class ObicoPlugin(
octoprint.plugin.SettingsPlugin,
octoprint.plugin.StartupPlugin,
Expand All @@ -73,7 +106,7 @@ def __init__(self):
self.status_update_lock = threading.RLock()
self.remote_status = RemoteStatus()
self.pause_resume_sequence = PauseResumeGCodeSequence()
self.gcode_hooks = GCodeHooks(self)
self.gcode_hooks = GCodeHooks(self, _print_job_tracker)
self.octoprint_settings_updater = OctoPrintSettingsUpdater(self)
self.jpeg_poster = JpegPoster(self)
self.file_downloader = FileDownloader(self, _print_job_tracker)
Expand All @@ -86,11 +119,59 @@ def __init__(self):
self.bailed_because_tsd_plugin_running = False
self.printer_events_posted = dict()

self.gcode_preprocessors = {}
self.total_layers = 0

self.layer_indicator_patterns = [
dict(slicer='CURA',
regx=r'^;LAYER:([0-9]+)'),
dict(slicer='Simplify3D',
regx=r'^; layer ([0-9]+)'),
dict(slicer='Slic3r/PrusaSlicer',
regx=r'^;BEFORE_LAYER_CHANGE'),
dict(slicer='Almost Everyone',
regx=r"^;(( BEGIN_|BEFORE_)+LAYER_(CHANGE|OBJECT)|LAYER:[0-9]+| [<]{0,1}layer [0-9]+[>,]{0,1}).*$")
]


# ~~ Custom event registration

def register_custom_events(*args, **kwargs):
return ["command"]

def load_from_meta(self, payload):
self.total_layers = 0
self.is_preprocessed = False

metaData = self._file_manager.get_metadata(payload.get("origin"), payload.get("path")) # Get OP metadata from file

try:
self.total_layers = metaData['obico']['layer_count']

except KeyError: pass

if self.total_layers > 0:
self.is_preprocessed = True
else:
if payload['origin'] == 'local':
_logger.warning("Gcode not pre-processed by Dashboard. Processing now.")

path = self._file_manager.path_on_disk(octoprint.filemanager.FileDestinations.LOCAL, payload['path'])
file_object = octoprint.filemanager.util.DiskFileWrapper(payload['name'], path)
stream = self.createFilePreProcessor(path, file_object)
stream.save(path)
self.unload_preprocesser(self.gcode_preprocessors[path], payload)
_logger.warning("Gcode pre-processing done.")
self.load_from_meta(payload)
return
else:
self._logger.warn("Gcode not pre-processed by Dashboard. Upload again to get layer metrics")

return

def unload_preprocesser(self, processor, payload):
additionalMetaData = {"layer_count": processor.layer_count}
self._file_manager.set_additional_metadata(payload.get("origin"), payload.get("path"), self._plugin_info.key, additionalMetaData, overwrite=True)

# ~~ SettingsPlugin mixin

Expand Down Expand Up @@ -164,6 +245,10 @@ def on_event(self, event, payload):
self.boost_status_update()

try:
if event == 'MetadataAnalysisFinished':
if payload['path'] in self.gcode_preprocessors:
gcpp = self.gcode_preprocessors.pop(payload['path'])
self.unload_preprocesser(gcpp, payload)
if event == 'FirmwareData':
self.octoprint_settings_updater.update_firmware(payload)
self.post_update_to_server()
Expand Down Expand Up @@ -540,6 +625,16 @@ def is_blueprint_protected(self):
def is_pro_user(self):
return self.linked_printer.get('is_pro')

def createFilePreProcessor(self, path, file_object, blinks=None, printer_profile=None, allow_overwrite=True, *args, **kwargs):
#create instance of preprocessor if wanted - db pg
fileName = file_object.filename
if not octoprint.filemanager.valid_file_type(fileName, type="gcode"):
return file_object
fileStream = file_object.stream()
_logger.warning("GcodePreProcessor started processing.")
self.gcode_preprocessors[path] = GcodePreProcessor(fileStream, self.layer_indicator_patterns )
return octoprint.filemanager.util.StreamWrapper(fileName, self.gcode_preprocessors[path])

# If you want your plugin to be registered within OctoPrint under a different name than what you defined in setup.py
# ("OctoPrint-PluginSkeleton"), you may define that here. Same goes for the other metadata derived from setup.py that
# can be overwritten via __plugin_xyz__ control properties. See the documentation for that.
Expand All @@ -562,4 +657,5 @@ def __plugin_load__():
"octoprint.comm.protocol.scripts": (__plugin_implementation__.pause_resume_sequence.script_hook, 100000),
"octoprint.plugin.softwareupdate.check_config": __plugin_implementation__.get_update_information,
"octoprint.events.register_custom_events": __plugin_implementation__.register_custom_events,
"octoprint.filemanager.preprocessor": __plugin_implementation__.createFilePreProcessor
}
6 changes: 5 additions & 1 deletion octoprint_obico/gcode_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,19 @@

class GCodeHooks:

def __init__(self, plugin):
def __init__(self, plugin, _print_job_tracker):
self.plugin = plugin
self._print_job_tracker = _print_job_tracker

def queuing_gcode(self, comm_instance, phase, cmd, cmd_type, gcode, subcode=None, tags=None, *args, **kwargs):
self.plugin.pause_resume_sequence.track_gcode(comm_instance, phase, cmd, cmd_type, gcode, subcode=None, tags=None, *args, **kwargs)

if gcode and gcode in ('M600', 'M701' or 'M702'):
self.plugin.post_filament_change_event()

elif gcode and 'M117 DASHBOARD_LAYER_INDICATOR' in cmd:
self._print_job_tracker.increment_layer_height(int(cmd.replace("M117 DASHBOARD_LAYER_INDICATOR ", "")))

def received_gcode(self, comm, line, *args, **kwargs):

# credit: https://github.com/QuinnDamerell/OctoPrint-OctoEverywhere/blob/ef37e6c9ce6798e8af54a5fd81215d430c05bfad/octoprint_octoeverywhere/__init__.py#L272
Expand Down
11 changes: 11 additions & 0 deletions octoprint_obico/print_job_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@ def __init__(self):
self.current_print_ts = -1 # timestamp when current print started, acting as a unique identifier for a print
self.obico_g_code_file_id = None
self._file_metadata_cache = None
self.current_layer_height = -1
self.total_layers = -1

def on_event(self, plugin, event, payload):
if event == 'PrintStarted':
with self._mutex:
plugin.load_from_meta(payload)
self.current_print_ts = int(time.time())
self._file_metadata_cache = None
self.current_layer_height = 1
self.total_layers = plugin.total_layers # grab total from main

md5_hash = plugin._file_manager.get_metadata(path=payload['path'], destination=payload['origin'])['hash']
g_code_data = dict(
Expand Down Expand Up @@ -57,6 +62,7 @@ def status(self, plugin, status_only=False):
with self._mutex:
data['current_print_ts'] = self.current_print_ts
current_file = data.get('status', {}).get('job', {}).get('file')
data['status']['total_layers'] = self.total_layers
if self.get_obico_g_code_file_id() and current_file:
current_file['obico_g_code_file_id'] = self.get_obico_g_code_file_id()

Expand All @@ -68,6 +74,7 @@ def status(self, plugin, status_only=False):

data['status']['temperatures'] = temperatures
data['status']['_ts'] = int(time.time())
data['status']['current_layer_height'] = self.current_layer_height

if status_only:
if self._file_metadata_cache:
Expand All @@ -81,6 +88,10 @@ def status(self, plugin, status_only=False):
data['settings'] = octo_settings

return data

def increment_layer_height(self, val):
with self._mutex:
self.current_layer_height = val

def set_obico_g_code_file_id(self, obico_g_code_file_id):
with self._mutex:
Expand Down

0 comments on commit 567635c

Please sign in to comment.