dev new features

This commit is contained in:
Vitor de Miranda Henrique
2018-06-15 13:53:00 -05:00
parent ce17b3cb1e
commit e954dbefc0
3 changed files with 157 additions and 53 deletions

View File

@@ -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):

View File

@@ -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),

View File

@@ -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>