fixes and improvements

This commit is contained in:
Vitor de Miranda Henrique
2018-06-14 18:05:12 -05:00
parent b559843f92
commit 6429487d5f
4 changed files with 139 additions and 64 deletions

View File

@@ -117,20 +117,26 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
self.configure_gpio()
self.update_ui()
self.start_outpus_with_server()
self.handle_initial_gpio_control()
self.start_timer()
self.print_complete = False
def get_settings_version(self):
return 4
return 5
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"])
def on_settings_migrate(self, target, current):
self._logger.warn("######### current settings version %s target settings version %s #########", current, target)
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"])
@@ -302,7 +308,14 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
sudo_str = ""
cmd = sudo_str + "python " + script + str(led_pin) + " " + str(led_count) + " " + str(
led_brightness) + " " + str(red) + " " + str(green) + " " + str(blue) + " " + str(address)
led_brightness) + " " + str(red) + " " + str(green) + " " + str(blue) + " "
if neopixel_dirrect:
dma = self._settings.get(["neopixel_dma"]) or 10
cmd = cmd + str(dma)
else:
cmd = cmd + str(address)
if self._settings.get(["debug"]) is True:
if queue_id is not None:
self._logger.info("Runing scheduled queue id %s", queue_id)
@@ -496,7 +509,6 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
temp, hum = self.read_dummy_temp()
else:
if sensor['temp_sensor_type'] in ["11", "22", "2302"]:
self._logger.info("temp_sensor_type dht")
temp, hum = self.read_dht_temp(
sensor['temp_sensor_type'], sensor['gpio_pin'])
elif sensor['temp_sensor_type'] == "18b20":
@@ -799,7 +811,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
try:
current_mode = GPIO.getmode()
set_mode = GPIO.BOARD if self._settings.get(
["useBoardPinNumber"]) else GPIO.BCM
["use_board_pin_number"]) else GPIO.BCM
if current_mode is None:
outputs = list(filter(lambda item: item['output_type'] == 'regular' or
item['output_type'] == 'pwm' or
@@ -815,7 +827,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
elif current_mode != set_mode:
GPIO.setmode(current_mode)
tempstr = "BOARD" if current_mode == GPIO.BOARD else "BCM"
self._settings.set(["useBoardPinNumber"],
self._settings.set(["use_board_pin_number"],
True if current_mode == GPIO.BOARD else False)
warn_msg = "GPIO mode was configured before, GPIO mode will be forced to use: " + \
tempstr + " as pin numbers. Please update GPIO accordingly!"
@@ -889,10 +901,20 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
self.clear_channel(pin)
for rpi_input in list(filter(lambda item: item['input_type'] == 'gpio', self.rpi_inputs)):
pull_resistor = GPIO.PUD_UP if rpi_input['input_pull_resistor'] == 'input_pull_up' else GPIO.PUD_DOWN
gpio_pin = self.to_int(rpi_input['gpio_pin'])
pull_resistor = GPIO.PUD_UP if rpi_input['input_pull_resistor'] == 'input_pull_up' else GPIO.PUD_DOWN
GPIO.setup(gpio_pin, GPIO.IN, pull_resistor)
edge = GPIO.RISING if rpi_input['edge'] == 'rise' else GPIO.FALLING
inputs_same_gpio = list(
[r_inp for r_inp in self.rpi_inputs if self.to_int(r_inp['gpio_pin']) == gpio_pin])
if len(inputs_same_gpio) > 1:
GPIO.remove_event_detect(gpio_pin)
for other_input in inputs_same_gpio:
if other_input['edge'] is not edge:
edge = GPIO.BOTH
if rpi_input['action_type'] == 'output_control':
self._logger.info(
"Adding GPIO event detect on pin %s with edge: %s", gpio_pin, edge)
@@ -980,39 +1002,50 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
self._logger.warn("Failed to stop task %s.", task)
pass
def handle_gpio_control(self, channel):
try:
if self._settings.get(["debug"]) is True:
self._logger.info(
"GPIO event triggered on channel %s", channel)
rpi_input = [r_inp for r_inp in self.rpi_inputs if self.to_int(
r_inp['gpio_pin']) == self.to_int(channel)].pop()
def handle_initial_gpio_control(self):
for rpi_input in [r_inp for r_inp in self.rpi_inputs if r_inp['action_type'] == 'output_control']:
gpio_pin = self.to_int(rpi_input['gpio_pin'])
controlled_io = self.to_int(rpi_input['controlled_io'])
if (rpi_input['edge'] == 'fall') ^ GPIO.input(gpio_pin):
rpi_output = [r_out for r_out in self.rpi_outputs if self.to_int(
r_out['index_id']) == controlled_io].pop()
if rpi_output['output_type'] == 'regular':
if rpi_input['controlled_io_set_value'] == 'toggle':
val = GPIO.LOW if GPIO.input(self.to_int(
rpi_output['gpio_pin'])) == GPIO.HIGH else GPIO.HIGH
else:
val = GPIO.LOW if rpi_input['controlled_io_set_value'] == 'low' else GPIO.HIGH
val = GPIO.LOW if rpi_input['controlled_io_set_value'] == 'low' else GPIO.HIGH
self.write_gpio(self.to_int(
rpi_output['gpio_pin']), val)
for notification in self.notifications:
if notification['gpioAction']:
msg = "GPIO control action caused by input " + str(rpi_input['label']) + ". Setting GPIO" + str(
rpi_input['controlled_io']) + " to: " + str(rpi_input['controlled_io_set_value'])
self.send_notification(msg)
if rpi_output['output_type'] == 'gcode_output':
self.send_gcode_command(rpi_output['gcode'])
for notification in self.notifications:
if notification['gpioAction']:
msg = "GPIO control action caused by input " + \
str(rpi_input['label']) + \
". Sending GCODE command"
self.send_notification(msg)
def handle_gpio_control(self, channel):
try:
if self._settings.get(["debug"]) is True:
self._logger.info(
"GPIO event triggered on channel %s", channel)
for rpi_input in [r_inp for r_inp in self.rpi_inputs if self.to_int(r_inp['gpio_pin']) == self.to_int(channel)]:
gpio_pin = self.to_int(rpi_input['gpio_pin'])
controlled_io = self.to_int(rpi_input['controlled_io'])
if (rpi_input['edge'] == 'fall') ^ GPIO.input(gpio_pin):
rpi_output = [r_out for r_out in self.rpi_outputs if self.to_int(
r_out['index_id']) == controlled_io].pop()
if rpi_output['output_type'] == 'regular':
if rpi_input['controlled_io_set_value'] == 'toggle':
val = GPIO.LOW if GPIO.input(self.to_int(
rpi_output['gpio_pin'])) == GPIO.HIGH else GPIO.HIGH
else:
val = GPIO.LOW if rpi_input['controlled_io_set_value'] == 'low' else GPIO.HIGH
self.write_gpio(self.to_int(
rpi_output['gpio_pin']), val)
for notification in self.notifications:
if notification['gpioAction']:
msg = "GPIO control action caused by input " + str(rpi_input['label']) + ". Setting GPIO" + str(
rpi_input['controlled_io']) + " to: " + str(rpi_input['controlled_io_set_value'])
self.send_notification(msg)
if rpi_output['output_type'] == 'gcode_output':
self.send_gcode_command(rpi_output['gcode'])
for notification in self.notifications:
if notification['gpioAction']:
msg = "GPIO control action caused by input " + \
str(rpi_input['label']) + \
". Sending GCODE command"
self.send_notification(msg)
except Exception as ex:
self.log_error(ex)
pass
@@ -1162,6 +1195,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
if event == Events.PRINT_STARTED:
self.print_complete = False
self.cancel_all_events_on_queue()
self.event_queue = []
self.start_filament_detection()
for rpi_output in self.rpi_outputs:
if rpi_output['auto_startup']:
@@ -1199,6 +1233,19 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
elif event in (Events.PRINT_CANCELLED, Events.PRINT_FAILED):
self.stop_filament_detection()
self.cancel_all_events_on_queue()
self.event_queue = []
for rpi_output in self.rpi_outputs:
if rpi_output['shutdown_on_failed']:
shutdown_time = rpi_output['shutdown_time']
if rpi_output['output_type'] == 'pwm' and rpi_output['pwm_temperature_linked']:
rpi_output['duty_cycle'] = rpi_output['default_duty_cycle']
if rpi_output['auto_shutdown'] and not self.is_hour(shutdown_time):
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()
if event == Events.PRINT_DONE:
for notification in self.notifications:
@@ -1228,7 +1275,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
shutdown_delay_seconds, rpi_output, value, sufix)
if rpi_output['output_type'] == 'pwm' and rpi_output['pwm_temperature_linked']:
self.schedule_pwm_duty_on_queue(
shutdown_delay_seconds, rpi_output, 0)
shutdown_delay_seconds, rpi_output, 0, sufix)
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)
@@ -1330,9 +1377,9 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
self.event_queue.append(dict(queue_id=queue_id, thread=thread))
def schedule_pwm_duty_on_queue(self, delay_seconds, rpi_output, value):
queue_id = '{0!s}_{1!s}'.format(
rpi_output['index_id'], "pwm_linked_temp")
def schedule_pwm_duty_on_queue(self, delay_seconds, rpi_output, value, sufix):
queue_id = '{0!s}_{1!s}_{2!s}'.format(
rpi_output['index_id'], "pwm_linked_temp", sufix)
thread = threading.Timer(delay_seconds,
self.set_pwm_duty_cycle,
args=[rpi_output, value, queue_id])
@@ -1415,10 +1462,11 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
"M82 ;Set extruder to Absolute Mode\n" +
"G92 E0 ;Set Extruder to 0",
use_sudo=True,
neopixel_dma=10,
debug=False,
gcode_control=False,
debug_temperature_log=False,
useBoardPinNumber=False,
use_board_pin_number=False,
notification_provider="disabled",
notification_api_key="",
notification_event_name="printer_event",

View File

@@ -3,7 +3,6 @@ import sys
import time
LED_INVERT = False
LED_DMA = 5
LED_FREQ_HZ = 800000
if len(sys.argv) == 8:
@@ -13,7 +12,7 @@ if len(sys.argv) == 8:
red = int(sys.argv[4])
green = int(sys.argv[5])
blue = int(sys.argv[6])
address = int(sys.argv[7], 16)
LED_DMA = int(sys.argv[7], 16)
else:
print("fail")
sys.exit(1)

View File

@@ -43,13 +43,17 @@ $(function () {
});
});
self.use_sudo = ko.observable();
self.gcode_control = ko.observable();
self.neopixel_dma = ko.observable();
self.debug = ko.observable();
self.debug_temperature_log = ko.observable();
self.use_board_pin_number = ko.observable();
self.filament_sensor_gcode = ko.observable();
self.notification_provider = ko.observable();
self.notification_event_name = ko.observable();
self.notification_api_key = ko.observable();
self.notifications = ko.observable();
self.notifications = ko.observableArray([]);
self.humidityCapableSensor = function(sensor){
if (['11', '22', '2302', 'bme280', 'si7021'].indexOf(sensor) >= 0){
@@ -262,24 +266,28 @@ $(function () {
return duty_cycle;
}
self.bindSettings = function(){
self.bindFromSettings = function(){
self.rpi_outputs(self.settingsViewModel.settings.plugins.enclosure.rpi_outputs());
self.rpi_inputs(self.settingsViewModel.settings.plugins.enclosure.rpi_inputs());
self.debug(self.settingsViewModel.settings.plugins.enclosure.debug())
self.debug_temperature_log(self.settingsViewModel.settings.plugins.enclosure.debug_temperature_log())
self.filament_sensor_gcode(self.settingsViewModel.settings.plugins.enclosure.filament_sensor_gcode())
self.notification_provider(self.settingsViewModel.settings.plugins.enclosure.notification_provider())
self.notification_event_name(self.settingsViewModel.settings.plugins.enclosure.notification_event_name())
self.notification_api_key(self.settingsViewModel.settings.plugins.enclosure.notification_api_key())
self.notifications(self.settingsViewModel.settings.plugins.enclosure.notifications())
self.use_sudo(self.settingsViewModel.settings.plugins.enclosure.use_sudo());
self.gcode_control(self.settingsViewModel.settings.plugins.enclosure.gcode_control());
self.neopixel_dma(self.settingsViewModel.settings.plugins.enclosure.neopixel_dma());
self.debug(self.settingsViewModel.settings.plugins.enclosure.debug());
self.debug_temperature_log(self.settingsViewModel.settings.plugins.enclosure.debug_temperature_log());
self.use_board_pin_number(self.settingsViewModel.settings.plugins.enclosure.use_board_pin_number());
self.filament_sensor_gcode(self.settingsViewModel.settings.plugins.enclosure.filament_sensor_gcode());
self.notification_provider(self.settingsViewModel.settings.plugins.enclosure.notification_provider());
self.notification_event_name(self.settingsViewModel.settings.plugins.enclosure.notification_event_name());
self.notification_api_key(self.settingsViewModel.settings.plugins.enclosure.notification_api_key());
self.notifications(self.settingsViewModel.settings.plugins.enclosure.notifications());
};
self.onBeforeBinding = function () {
self.bindSettings();
self.bindFromSettings();
};
self.onSettingsBeforeSave = function() {
self.bindSettings();
self.bindFromSettings();
};
self.onStartupComplete = function () {
@@ -368,6 +376,7 @@ $(function () {
controlled_io_set_value: ko.observable("Low"),
startup_time: ko.observable(0),
auto_shutdown: ko.observable(false),
shutdown_on_failed: ko.observable(false),
shutdown_time: ko.observable(0),
linked_temp_sensor: ko.observable(""),
alarm_set_temp: ko.observable(0),

View File

@@ -204,6 +204,15 @@
</div>
<!-- /ko -->
<!-- ko if: $data.auto_shutdown -->
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: shutdown_on_failed"> {{ _('Shutdown on Failed or Canceled') }}
</label>
<span class="help-inline">Choose if output should turn off automatomatically when print is canceled or fails</span>
</div>
</div>
<div data-bind="attr: {id: 'auto_shutdownField_' + $index() }">
<div class="control-group">
<label class="control-label">{{ _('Shutdown Delay / Hour') }}</label>
@@ -294,13 +303,16 @@
</div>
</div>
<!-- ko if: $data.auto_startup || $data.startup_with_server -->
<div class="control-group">
<label class="control-label">{{ _('Default Value') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: temp_ctr_default_value">
<span class="help-inline">Default temperature / humidity that temperature control will be set when the print starts.</span>
<span class="help-inline">Default temperature / humidity that temperature control will be set when the print starts or the server starts.</span>
</div>
</div>
<!-- /ko -->
<div class="control-group">
<label class="control-label">{{ _('Value Deadband') }}</label>
<div class="controls">
@@ -714,6 +726,13 @@
<a href=" https://github.com/vitormhenrique/OctoPrint-Enclosure">github</a> page</span>
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('Neopixel DMA Channel') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: settingsViewModel.settings.plugins.enclosure.neopixel_dma">
<span class="help-inline">DMA channel used on direct control of neopixel.</span>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
@@ -722,7 +741,7 @@
<span class="help-inline">Log additional information on octoprint log to help trouble shoot the plugin</span>
</div>
</div>
<!-- ko if: ($root.settingsViewModel.settings.plugins.enclosure.debug()) -->
<!-- ko if: ($root.debug()) -->
<div class="control-group">
<div class="controls">
<label class="checkbox">
@@ -735,7 +754,7 @@
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: settingsViewModel.settings.plugins.enclosure.useBoardPinNumber"> {{ _('Use Board Pin #') }}
<input type="checkbox" data-bind="checked: settingsViewModel.settings.plugins.enclosure.use_board_pin_number"> {{ _('Use Board Pin #') }}
</label>
<span class="help-inline">Use BOARD pin numbers instead of BCM pin numbers</span>
</div>
@@ -749,7 +768,7 @@
</div>
<div class="control-group">
<label class="control-label" for="settings-enclosure-filament-sensor">{{ _('Filament Change Gcode') }}</label>
<label class="control-label">{{ _('Filament Change Gcode') }}</label>
<div class="controls">
<textarea rows="4" class="block" data-bind="value: settingsViewModel.settings.plugins.enclosure.filament_sensor_gcode"></textarea>
<span class="help-inline">GCODE that will be sent to the printer to pause and allow filament to be changed. You should add
@@ -770,17 +789,17 @@
<div class="control-group">
<label class="control-label">{{ _('Event Name') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value: settingsViewModel.settings.plugins.enclosure.notification_event_name">
<input type="text" class="input-block-level" data-bind="value: notification_event_name">
<span class="help-inline">Event name that was configured on the maker chanel of IFTTT, don't use space between the words</span>
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('IFTTT API KEY') }}</label>
<div class="controls">
<input type="text" class="input-block-level" data-bind="value:settingsViewModel.settings.plugins.enclosure.notification_api_key">
<input type="text" class="input-block-level" data-bind="value: notification_api_key">
</div>
</div>
<div class="control-group" data-bind="foreach: settingsViewModel.settings.plugins.enclosure.notifications">
<div class="control-group" data-bind="foreach: notifications">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: temperatureAction"> {{ _('Notify temperature actions') }}