dev new features
This commit is contained in:
@@ -118,16 +118,29 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
|
||||
self.print_complete = False
|
||||
|
||||
def get_settings_version(self):
|
||||
return 4
|
||||
return 6
|
||||
|
||||
def on_settings_migrate(self, target, current=None):
|
||||
self._logger.warn("######### settings not compatible #########")
|
||||
self._logger.warn("######### current settings version %s target settings version %s #########",
|
||||
current, target)
|
||||
self._settings.set(["rpi_outputs"], [])
|
||||
self._settings.set(["rpi_inputs"], [])
|
||||
self.rpi_outputs = self._settings.get(["rpi_outputs"])
|
||||
self.rpi_inputs = self._settings.get(["rpi_inputs"])
|
||||
self._logger.warn("######### current settings version %s target settings version %s #########", current, target)
|
||||
|
||||
if current >= 4 and target == 6:
|
||||
self._logger.warn(
|
||||
"######### migrating settings to v6 #########")
|
||||
for rpi_output in old_outputs:
|
||||
if 'shutdown_on_failed' not in rpi_output:
|
||||
rpi_output['shutdown_on_failed'] = False
|
||||
if 'shutdown_on_failed' not in rpi_output:
|
||||
if current == 4 and target == 5:
|
||||
self._logger.warn("######### migrating settings from v4 to v5 #########")
|
||||
old_outputs = self._settings.get(["rpi_outputs"])
|
||||
for rpi_output in old_outputs:
|
||||
rpi_output['shutdown_on_failed'] = False
|
||||
self._settings.set(["rpi_outputs"], old_outputs)
|
||||
else:
|
||||
self._logger.warn("######### settings not compatible #########")
|
||||
self._settings.set(["rpi_outputs"], [])
|
||||
self._settings.set(["rpi_inputs"], [])
|
||||
self.rpi_inputs = self._settings.get(["rpi_inputs"])
|
||||
|
||||
# ~~ Blueprintplugin mixin
|
||||
@octoprint.plugin.BlueprintPlugin.route("/setEnclosureTempHum", methods=["GET"])
|
||||
@@ -175,6 +188,19 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
|
||||
self.write_gpio(self.to_int(rpi_output['gpio_pin']), val)
|
||||
return flask.jsonify(success=True)
|
||||
|
||||
@octoprint.plugin.BlueprintPlugin.route("/sendShellCommand", methods=["GET"])
|
||||
def send_shell_command(self):
|
||||
output_index = self.to_int(flask.request.values["index_id"])
|
||||
|
||||
rpi_output = [r_out for r_out in self.rpi_outputs if self.to_int(
|
||||
r_out['index_id']) == output_index].pop()
|
||||
|
||||
if rpi_output:
|
||||
command = rpi_output['shell_script']
|
||||
self.shell_command(command)
|
||||
return flask.jsonify(success=True)
|
||||
|
||||
|
||||
@octoprint.plugin.BlueprintPlugin.route("/setAutoStartUp", methods=["GET"])
|
||||
def set_auto_startup(self):
|
||||
index = flask.request.values["index_id"]
|
||||
@@ -262,6 +288,16 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
|
||||
|
||||
return flask.jsonify(success=True)
|
||||
|
||||
def shell_command(self, command):
|
||||
try:
|
||||
stdout = (Popen(command, shell=True, stdout=PIPE).stdout).read()
|
||||
self._plugin_manager.send_plugin_message(
|
||||
self._identifier, dict(is_msg=True, msg=stdout, msg_type="success"))
|
||||
except Exception as ex:
|
||||
self.log_error(ex)
|
||||
self._plugin_manager.send_plugin_message(
|
||||
self._identifier, dict(is_msg=True, msg="Could not execute shell script", msg_type="error"))
|
||||
|
||||
def send_neopixel_command(self, led_pin, led_count, led_brightness, red, green, blue, address,
|
||||
neopixel_dirrect, index_id, queue_id=None):
|
||||
"""Send neopixel command
|
||||
@@ -790,7 +826,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
|
||||
tempstr + " as pin numbers. Please update GPIO accordingly!"
|
||||
self._logger.info(warn_msg)
|
||||
self._plugin_manager.send_plugin_message(
|
||||
self._identifier, dict(isMsg=True, msg=warn_msg))
|
||||
self._identifier, dict(is_msg=True, msg=warn_msg, msg_type="error"))
|
||||
GPIO.setwarnings(False)
|
||||
except Exception as ex:
|
||||
self.log_error(ex)
|
||||
@@ -978,6 +1014,9 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
|
||||
str(rpi_input['label']) + \
|
||||
". Sending GCODE command"
|
||||
self.send_notification(msg)
|
||||
if rpi_output['output_type'] == 'shell_output':
|
||||
command = rpi_output['shell_script']
|
||||
self.shell_command(command)
|
||||
except Exception as ex:
|
||||
self.log_error(ex)
|
||||
pass
|
||||
@@ -1007,11 +1046,18 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
|
||||
self._printer.cancel_print()
|
||||
elif rpi_input['printer_action'] == 'toggle':
|
||||
self._logger.info("Printer action toggle.")
|
||||
if self._printer.is_operational():
|
||||
self._printer.toggle_pause_print()
|
||||
else:
|
||||
self._printer.connect()
|
||||
elif rpi_input['printer_action'] == 'start':
|
||||
self._printer.start_print()
|
||||
elif rpi_input['printer_action'] == 'toggle_job':
|
||||
if self._printer.is_operational():
|
||||
if self._printer.is_printing():
|
||||
self._printer.pause_print()
|
||||
elif self._printer.is_paused():
|
||||
self._printer.resume_print()
|
||||
self._printer.cancel_print()
|
||||
elif self._printer.is_ready():
|
||||
self._printer.start_print()
|
||||
else:
|
||||
self._printer.connect()
|
||||
elif rpi_input['printer_action'] == 'stop_temp_hum_control':
|
||||
@@ -1157,8 +1203,6 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
|
||||
delay_seconds = self.to_float(shutdown_time)
|
||||
self.schedule_auto_shutdown_outputs(
|
||||
rpi_output, delay_seconds)
|
||||
if rpi_output['output_type'] == 'temp_hum_control':
|
||||
rpi_output['temp_ctr_set_value'] = 0
|
||||
self.run_tasks()
|
||||
self.update_ui()
|
||||
|
||||
@@ -1198,6 +1242,10 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
|
||||
if (rpi_output['output_type'] == 'neopixel_indirect' or rpi_output['output_type'] == 'neopixel_direct'):
|
||||
self.add_neopixel_output_to_queue(
|
||||
rpi_output, shutdown_delay_seconds, 0, 0, 0, sufix)
|
||||
if rpi_output['output_type'] == 'temp_hum_control':
|
||||
value = 0
|
||||
self.add_temperature_output_temperature_queue(
|
||||
delay_seconds, rpi_output, value, sufix)
|
||||
if self._settings.get(["debug"]) is True:
|
||||
self._logger.info("Events scheduled to run %s", self.event_queue)
|
||||
|
||||
@@ -1240,7 +1288,8 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
|
||||
self.add_neopixel_output_to_queue(
|
||||
rpi_output, delay_seconds, red, green, blue, sufix)
|
||||
if rpi_output['output_type'] == 'temp_hum_control':
|
||||
rpi_output['temp_ctr_set_value'] = rpi_output['temp_ctr_default_value']
|
||||
value = rpi_output['temp_ctr_default_value']
|
||||
self.add_temperature_output_temperature_queue(delay_seconds, rpi_output, value, sufix)
|
||||
if self._settings.get(["debug"]) is True:
|
||||
self._logger.info("Events scheduled to run %s", self.event_queue)
|
||||
|
||||
@@ -1325,6 +1374,42 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
|
||||
|
||||
self.event_queue.append(dict(queue_id=queue_id, thread=thread))
|
||||
|
||||
def add_temperature_output_temperature_queue(self, delay_seconds, rpi_output, value, sufix):
|
||||
queue_id = '{0!s}_{1!s}'.format(rpi_output['index_id'], sufix)
|
||||
if self._settings.get(["debug"]) is True:
|
||||
self._logger.info("Scheduling temperature control id %s on %s delay_seconds", queue_id, delay_seconds)
|
||||
|
||||
thread = threading.Timer(delay_seconds,
|
||||
self.write_temperature_to_output,
|
||||
args=[self.to_int(rpi_output['index_id']), value, queue_id])
|
||||
|
||||
self.event_queue.append(dict(queue_id=queue_id, thread=thread))
|
||||
|
||||
def write_temperature_to_output(self, rpi_output_index, value, queue_id=None):
|
||||
try:
|
||||
rpi_output = [r_out for r_out in self.rpi_outputs if self.to_int(
|
||||
r_out['index_id']) == rpi_output_index].pop()
|
||||
|
||||
if rpi_output['output_type'] == 'temp_hum_control':
|
||||
rpi_output['temp_ctr_set_value'] = value
|
||||
|
||||
if self._settings.get(["debug"]) is True:
|
||||
if queue_id is not None:
|
||||
self._logger.info("Runing scheduled queue id %s", queue_id)
|
||||
self._logger.info(
|
||||
"Setting temperature to output index: %s value %s", rpi_output['index_id'], value)
|
||||
|
||||
self.update_ui()
|
||||
if queue_id is not None:
|
||||
self.stop_queue_item(queue_id)
|
||||
|
||||
except Exception as ex:
|
||||
template = "An exception of type {0} occurred on {1} when writing on pin {2}. Arguments:\n{3!r}"
|
||||
message = template.format(
|
||||
type(ex).__name__, inspect.currentframe().f_code.co_name, gpio, ex.args)
|
||||
self._logger.warn(message)
|
||||
pass
|
||||
|
||||
def get_startup_delay_from_output(self, rpi_output):
|
||||
start_up_time = rpi_output['startup_time']
|
||||
if self.is_hour(start_up_time):
|
||||
|
||||
@@ -21,7 +21,7 @@ $(function () {
|
||||
|
||||
self.settings_possible_outputs = ko.pureComputed(function () {
|
||||
return ko.utils.arrayFilter(self.settingsViewModel.settings.plugins.enclosure.rpi_outputs(), function (item) {
|
||||
return ((item.output_type() === "regular" && !item.toggle_timer()) || item.output_type() === "gcode_output");
|
||||
return ((item.output_type() === "regular" && !item.toggle_timer()) || item.output_type() === "gcode_output" || item.output_type() === "shell_output");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -226,11 +226,11 @@ $(function () {
|
||||
})
|
||||
}
|
||||
|
||||
if (data.isMsg) {
|
||||
if (data.is_msg) {
|
||||
new PNotify({
|
||||
title: "Enclosure",
|
||||
text: data.msg,
|
||||
type: "error"
|
||||
type: data.msg_type
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -348,6 +348,7 @@ $(function () {
|
||||
index_id: ko.observable(nextIndex),
|
||||
label: ko.observable("Ouput " + nextIndex),
|
||||
output_type: ko.observable("regular"),
|
||||
shell_script: ko.observable(""),
|
||||
gpio_pin: ko.observable(0),
|
||||
gpio_status: ko.observable(false),
|
||||
hide_btn_ui: ko.observable(false),
|
||||
|
||||
@@ -53,6 +53,12 @@
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<label class="radio">
|
||||
<input type="radio" value="shell_output" data-bind="checked: output_type, attr: {name: 'output_type_' + $index() }"> {{ _('Shell Script') }}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ko if: ($data.output_type() != "temperature_alarm") -->
|
||||
<div class="control-group">
|
||||
@@ -70,6 +76,15 @@
|
||||
<span class="help-inline">Id used for API control</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ko if: ($data.output_type() == "shell_output") -->
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ _('Script') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-block-level" data-bind="value: shell_script">
|
||||
<span class="help-inline">Shell script to be executed</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
<!-- ko ifnot: ($data.output_type() == "gcode_output" || $data.output_type() == "temperature_alarm" ) -->
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ _('IO Number') }}</label>
|
||||
@@ -88,45 +103,45 @@
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
|
||||
|
||||
<!-- ko if: ($data.output_type() == "pwm" ) -->
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" data-bind="checked: pwm_temperature_linked"> {{ _('Link PWM to Temperature') }}
|
||||
</label>
|
||||
<span class="help-inline">Link PWM ouput to temperature. PWM output will be interpolated between the point from duty A, temperature A -> duty B, temperature B.
|
||||
This output will automatomatically start when a print starts and will default to the default duty cycle when print is complete.
|
||||
</span>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" data-bind="checked: pwm_temperature_linked"> {{ _('Link PWM to Temperature') }}
|
||||
</label>
|
||||
<span class="help-inline">Link PWM ouput to temperature. PWM output will be interpolated between the point from duty A, temperature A -> duty
|
||||
B, temperature B. This output will automatomatically start when a print starts and will default to the default
|
||||
duty cycle when print is complete.
|
||||
</span>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko if: ($data.output_type() == "pwm" && $data.pwm_temperature_linked()) -->
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ _('Duty A') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-block-level" data-bind="value: duty_a">
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ _('Duty A') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-block-level" data-bind="value: duty_a">
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ _('Temperature A') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-block-level" data-bind="value: temperature_a">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ _('Temperature A') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-block-level" data-bind="value: temperature_a">
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ _('Duty B') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-block-level" data-bind="value: duty_b">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ _('Duty B') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-block-level" data-bind="value: duty_b">
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ _('Temperature B') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-block-level" data-bind="value: temperature_b">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ _('Temperature B') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-block-level" data-bind="value: temperature_b">
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko if: ($data.output_type() == "regular" || ($data.output_type() == "pwm" && !$data.pwm_temperature_linked()) ) -->
|
||||
@@ -212,15 +227,16 @@
|
||||
<span class="help-inline">Time delay in secconds to turn on GPIO when print starts OR exact time that the event should happen, note that
|
||||
events will only be scheduled after a print starts, time should be formated as HH:MM on a 24 hours format, don't
|
||||
forget to check timezone of your raspberry pi.</span>
|
||||
<span class="label label-important">Attention</span>
|
||||
<span> Hour schedule does not work with <b>Link PWM to Temperature</b> option</span>
|
||||
<span class="label label-important">Attention</span>
|
||||
<span> Hour schedule does not work with
|
||||
<b>Link PWM to Temperature</b> option</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko if: ($data.output_type() == "regular" || $data.output_type() == "temp_hum_control") -->
|
||||
<!-- ko if: ($data.output_type() == "regular" || $data.output_type() == "temp_hum_control" ) -->
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
@@ -231,7 +247,7 @@
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko if: ($data.output_type() == "regular" || $data.output_type() == "gcode_output" ) -->
|
||||
<!-- ko if: ($data.output_type() == "regular" || $data.output_type() == "gcode_output" || $data.output_type() == "shell_output") -->
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
@@ -637,7 +653,9 @@
|
||||
<option value="resume">Printer Resume</option>
|
||||
<option value="pause">Printer Pause</option>
|
||||
<option value="cancel">Printer Cancel</option>
|
||||
<option value="start">Start Print</option>
|
||||
<option value="toggle">Printer Toggle (Connect / Pause / Resume)</option>
|
||||
<option value="toggle_job">Job Toggle (Connect / Start / Cancel)</option>
|
||||
<option value="stop_temp_hum_control">Stop Temperature Control</option>
|
||||
</select>
|
||||
<span class="help-inline"> You can use filament change on your filament detectors and add buttons to resume and pause the print job.</span>
|
||||
|
||||
Reference in New Issue
Block a user