Skip to content

Commit

Permalink
Restructure to address review comments
Browse files Browse the repository at this point in the history
Regular messages now generated based on time, not percent done.
Config flag to disable regular messages
Simplified generation of data to display
  • Loading branch information
tsh-xx committed Jun 26, 2017
1 parent 9362654 commit adbc739
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 72 deletions.
123 changes: 54 additions & 69 deletions octoprint_octobullet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import os

import time
import traceback
import octoprint.util
import octoprint.plugin

Expand All @@ -33,10 +32,9 @@ def __init__(self):
self._bullet = None
self._channel = None
self._sender = None
self._interval_percent = 5
self._message_count = 0
self._quiet_time_sec = 1800
self._last_message = 0
self._update_period_sec = 0
self._periodic_updates_disabled = True
self._next_message = 0
self._time_remaining_format = "{days:d}d {hours:02d}h {minutes:02d}min"
self._eta_strftime = "%H:%M %d-%m"

Expand All @@ -45,26 +43,16 @@ def _connect_bullet(self, apikey, channel_name=""):

#~~ progress message helpers
def _sanitize_current_data(self, currentData):
if (currentData["progress"]["printTimeLeft"] == None):
currentData["progress"]["printTimeLeft"] = currentData["job"]["estimatedPrintTime"]
if (currentData["progress"]["printTimeLeft"] == None):
self._logger.debug("Still got no print time {}".format(currentData["progress"]["printTimeLeft"]))
currentData["progress"]["printTimeLeft"] = 1000
if (currentData["progress"]["filepos"] == None):
currentData["progress"]["filepos"] = 0
if (currentData["progress"]["printTime"] == None):
currentData["progress"]["printTime"] = currentData["job"]["estimatedPrintTime"]

currentData["progress"]["printTimeLeftString"] = "No ETL yet"

#Default messages if no data available
currentData["progress"]["printTimeLeftString"] = "No Time Remaining yet"
currentData["progress"]["printTimeString"] = "Not started yet"
currentData["progress"]["ETA"] = "No ETA yet"
#Add additional data
try:
if (currentData["progress"]["printTimeLeft"] != None):
currentData["progress"]["printTimeLeftString"] = self._get_time_from_seconds(currentData["progress"]["printTimeLeft"])
currentData["progress"]["printTimeString"] = self._get_time_from_seconds(currentData["progress"]["printTime"])
currentData["progress"]["ETA"] = time.strftime(self._eta_strftime, time.localtime(time.time() + currentData["progress"]["printTimeLeft"]))
except Exception as e:
self._logger.warning("Caught an exception trying to parse data: {0}\n Error is: {1}\nTraceback:{2}".format(currentData,e,traceback.format_exc()))
if (currentData["progress"]["printTime"] != None):
currentData["progress"]["printTimeString"] = self._get_time_from_seconds(currentData["progress"]["printTime"])

return currentData

Expand All @@ -76,51 +64,39 @@ def _get_time_from_seconds(self, seconds):

#~~ PrintProgressPlugin
def on_print_progress(self, storage, path, progress):
if(progress % self._interval_percent == 0):
self._quiet_time_sec = int(self._settings.get(["quiet_minutes"])) * 60
if self._quiet_time_sec == 0:
self._quiet_time_sec = 7* 24 * 3600 # use a week if we don't want messages
self._logger.debug("Progress: {} {} {}".format(storage,path,progress))
try:
currentData = self._printer.get_current_data()
currentData = self._sanitize_current_data(currentData)
except Exception as e:
self._logger.info("Caught an exception {0}\nTraceback:{1}".format(e,traceback.format_exc()))

self._logger.debug("Remaining {} ({})".format(currentData["progress"]["printTimeLeftString"],currentData["progress"]["printTimeLeftOrigin"]))
self._logger.debug("Total Print time {}".format(currentData["progress"]["printTimeString"]))
self._logger.debug("Estimated Completion {}".format(currentData["progress"]["ETA"]))
# first 3 messages, re-calculate interval (not first, analysis estimate can be inacurate)
self._message_count += 1
if self._message_count < 4 and self._message_count > 1:
total_job = currentData["progress"]["printTime"] + currentData["progress"]["printTimeLeft"]
self._interval_percent = int(100 * self._quiet_time_sec / total_job)
if self._interval_percent == 0:
self._interval_percent = 1
self._logger.debug("Set interval to {} percent count {} Total estimated {}".format(self._interval_percent, self._message_count,total_job))

# Suppress message if print is nearly done or interval calculation is off
need_message = True
if(currentData["progress"]["printTime"] < (self._quiet_time_sec * 0.5 + self._last_message)):
self._logger.debug("Skip message {} since print is only been running {} since last at {}".format(self._message_count, currentData["progress"]["printTime"], self._last_message))
need_message = False

if(currentData["progress"]["printTimeLeft"] < self._quiet_time_sec):
self._logger.debug("Skip trailing message since print is nearly done {} of {}".format(currentData["progress"]["printTimeLeft"], self._quiet_time_sec))
need_message = False

if need_message:
self._last_message = currentData["progress"]["printTime"]
path = currentData["job"]["file"]["path"]
eta = currentData["progress"]["ETA"]
print_time = currentData["progress"]["printTimeString"]
remaining = currentData["progress"]["printTimeLeftString"]

title = self._settings.get(["printProgress", "title"]).format(**locals())
body = self._settings.get(["printProgress", "body"]).format(**locals())
filename = os.path.splitext(path)[0] + ".jpg"
if(self._periodic_updates_disabled):
return

self._send_message_with_webcam_image(title, body, filename=filename)
# Called every 1% of progress
self._logger.debug("Progress: {} {} {}".format(storage,path,progress))

# Check if enough time has passed since last message
if(time.time() < self._next_message):
return

currentData = self._printer.get_current_data()
currentData = self._sanitize_current_data(currentData)

self._logger.debug("Remaining {} ({})".format(currentData["progress"]["printTimeLeftString"],currentData["progress"]["printTimeLeftOrigin"]))
self._logger.debug("Total Print time {}".format(currentData["progress"]["printTimeString"]))
self._logger.debug("Estimated Completion {}".format(currentData["progress"]["ETA"]))

#Now we have print time left, check if there is time for another message before job ends
if(currentData["progress"]["printTimeLeft"] < self._update_period_sec):
self._logger.debug("Skip trailing message since print is nearly done {} of {}".format(currentData["progress"]["printTimeLeft"], self._update_period_sec))
return

self._next_message = time.time() + self._update_period_sec

path = currentData["job"]["file"]["path"]
eta = currentData["progress"]["ETA"]
print_time = currentData["progress"]["printTimeString"]
remaining = currentData["progress"]["printTimeLeftString"]
title = self._settings.get(["printProgress", "title"]).format(**locals())
body = self._settings.get(["printProgress", "body"]).format(**locals())
filename = os.path.splitext(path)[0] + ".jpg"

self._send_message_with_webcam_image(title, body, filename=filename)



Expand Down Expand Up @@ -151,10 +127,18 @@ def on_settings_save(self, data):
self._settings.get(["push_channel"])))
thread.daemon = True
thread.start()
# Periodic update settings
self._update_period_sec = self._settings.get_int(["update_interval"]) * 60
self._periodic_updates_disabled = self._settings.get(["periodic_updates_disabled"])
self._logger.debug("Config: {} {}".format(self._update_period_sec, self._periodic_updates_disabled))
# Changing settings mid-print resets the timer
self._next_message = time.time() + self._update_period_sec


def get_settings_defaults(self):
return dict(
quiet_minutes = 0,
update_interval = 0,
progress_updates_enabled = False,
access_token=None,
push_channel=None,
printDone=dict(
Expand Down Expand Up @@ -223,9 +207,10 @@ def on_event(self, event, payload):
self._send_message_with_webcam_image(title, body, filename=filename)

if event == Events.PRINT_STARTED:
self._interval_percent = 5
self._message_count = 0
self._last_message = 0
self._update_period_sec = self._settings.get_int(["update_interval"]) * 60
self._periodic_updates_disabled = self._settings.get(["periodic_updates_disabled"])
self._next_message = time.time() + self._update_period_sec
self._logger.debug("Started: {} {}".format(self._update_period_sec, self._periodic_updates_disabled))


##~~ Softwareupdate hook
Expand Down
17 changes: 14 additions & 3 deletions octoprint_octobullet/templates/octobullet_settings.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,24 @@
</div>
</div>
{% trans %}<p>
You can define a time interval (in minutes) here for regular update messages as the print progresses. Set to 0 to prevent updates. First and last messages will usually not be sent. Be aware of the monthly message limit applied to free PushBullet accounts.
You can define a time interval (in minutes) here for regular update messages as the print progresses. The first message will come at this interval after printing has started. No messages are sent if the estimated time remaining is less than the interval. Be aware of the monthly message limit applied to free PushBullet accounts.
</p>{% endtrans %}

<div class="control-group">
<label class="control-label">{{ _('Quiet Time') }}</label>
<label class="control-label">{{ _('Update interval') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: settings.settings.plugins.octobullet.quiet_minutes">
<input type="text" class="input-block-level" data-bind="value: settings.settings.plugins.octobullet.update_interval">
</div>
</div>
{% trans %}<p>
Set this to disable periodic updates leaving just the end-of-print message.
</p>{% endtrans %}

<div class="control-group">
<label class="checkbox">
<div class="controls">
<input type="checkbox" class="input-block-level" data-bind="checked: settings.settings.plugins.octobullet.periodic_updates_disabled">{{ _('Updates Disabled') }}
</label>
</div>
</div>

Expand Down

0 comments on commit adbc739

Please sign in to comment.