From c9103bcdf8c29bab9621ec62a68b99ed668c5485 Mon Sep 17 00:00:00 2001 From: raoulh Date: Fri, 5 Feb 2021 17:44:31 +0100 Subject: [PATCH 01/16] Add i2c gpio support (#1) Implement support for i2c gpio devices (GPIO outputs and temp/humidity inputs) --- octoprint_enclosure/__init__.py | 238 +++++++++++++++--- octoprint_enclosure/static/js/enclosure.js | 14 +- .../templates/enclosure_settings.jinja2 | 98 +++++++- setup.py | 2 +- 4 files changed, 315 insertions(+), 37 deletions(-) diff --git a/octoprint_enclosure/__init__.py b/octoprint_enclosure/__init__.py index 473321c..8116e81 100644 --- a/octoprint_enclosure/__init__.py +++ b/octoprint_enclosure/__init__.py @@ -21,6 +21,8 @@ import inspect import threading import json import copy +from smbus2 import SMBus +import struct #Function that returns Boolean output state of the GPIO inputs / outputs @@ -148,7 +150,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP self.print_complete = False def get_settings_version(self): - return 6 + return 8 def on_settings_migrate(self, target, current=None): self._logger.warn("######### current settings version %s target settings version %s #########", current, target) @@ -156,15 +158,39 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP self._logger.info("rpi_outputs: %s", self.rpi_outputs) self._logger.info("rpi_inputs: %s", self.rpi_inputs) self._logger.info("######### End Current Settings #########") - if current >= 4 and target == 6: - self._logger.warn("######### migrating settings to v6 #########") + if current >= 4 and target == 8: + self._logger.warn("######### migrating settings to v8 #########") old_outputs = self._settings.get(["rpi_outputs"]) for rpi_output in old_outputs: if 'shutdown_on_failed' not in rpi_output: rpi_output['shutdown_on_failed'] = False if 'shell_script' not in rpi_output: rpi_output['shell_script'] = "" + if 'gpio_i2c_enabled' not in rpi_output: + rpi_output['gpio_i2c_enabled'] = False + if 'gpio_i2c_bus' not in rpi_output: + rpi_output['gpio_i2c_bus'] = 1 + if 'gpio_i2c_address' not in rpi_output: + rpi_output['gpio_i2c_address'] = 1 + if 'gpio_i2c_register' not in rpi_output: + rpi_output['gpio_i2c_register'] = 1 + if 'gpio_i2c_data_on' not in rpi_output: + rpi_output['gpio_i2c_data_on'] = 1 + if 'gpio_i2c_data_off' not in rpi_output: + rpi_output['gpio_i2c_data_off'] = 0 + if 'gpio_i2c_register_status' not in rpi_output: + rpi_output['gpio_i2c_register_status'] = 1 self._settings.set(["rpi_outputs"], old_outputs) + + old_inputs = self._settings.get(["rpi_inputs"]) + for rpi_input in old_inputs: + if 'temp_i2c_bus' not in rpi_input: + rpi_input['temp_i2c_bus'] = 1 + if 'temp_i2c_address' not in rpi_input: + rpi_input['temp_i2c_address'] = 1 + if 'temp_i2c_register' not in rpi_input: + rpi_input['temp_i2c_register'] = 1 + self._settings.set(["rpi_inputs"], old_inputs) else: self._logger.warn("######### settings not compatible #########") self._settings.set(["rpi_outputs"], []) @@ -191,7 +217,11 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP ConfiguredAs = "Output" ActiveLow = CheckInputActiveLow(rpi_output['active_low']) pin = self.to_int(rpi_output['gpio_pin']) - val = PinState_Human(pin,ActiveLow) + if rpi_output['gpio_i2c_enabled']: + b = self.gpio_i2c_input(rpi_output, ActiveLow) + val = " ON " if b else " OFF " + else: + val = PinState_Human(pin,ActiveLow) label = rpi_output['label'] Resp.append(dict(Configured_As=ConfiguredAs, label=label, GPIO_Pin=pin, Active_Low=ActiveLow, State=val)) if MatchFound == False: @@ -279,7 +309,11 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP label = rpi_output['label'] pin = self.to_int(rpi_output['gpio_pin']) ActiveLow = rpi_output['active_low'] - val = PinState_Human(pin,ActiveLow) + if rpi_output['gpio_i2c_enabled']: + b = self.gpio_i2c_input(rpi_output, ActiveLow) + val = " ON " if b else " OFF " + else: + val = PinState_Human(pin,ActiveLow) outputs.append(dict(index_id=index, label=label, GPIO_Pin=pin, State=val)) return Response(json.dumps(outputs), mimetype='application/json') @@ -290,7 +324,10 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP if identifier == self.to_int(rpi_output['index_id']): out = copy.deepcopy(rpi_output) pin = self.to_int(rpi_output['gpio_pin']) - out['current_value'] = PinState_Boolean(pin, rpi_output['active_low'] ) + if rpi_output['gpio_i2c_enabled']: + out['current_value'] = self.gpio_i2c_input(rpi_output, rpi_output['active_low']) + else: + out['current_value'] = PinState_Boolean(pin, rpi_output['active_low'] ) return Response(json.dumps(out), mimetype='application/json') return make_response('', 404) @@ -313,7 +350,10 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP for rpi_output in self.rpi_outputs: if identifier == self.to_int(rpi_output['index_id']): val = (not value) if rpi_output['active_low'] else value - self.write_gpio(self.to_int(rpi_output['gpio_pin']), val) + if rpi_output['gpio_i2c_enabled']: + self.gpio_i2c_write(rpi_output, val) + else: + self.write_gpio(self.to_int(rpi_output['gpio_pin']), val) return make_response('', 204) @@ -520,7 +560,10 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP if rpi_output['output_type'] == 'regular': pin = self.to_int(rpi_output['gpio_pin']) ActiveLow = rpi_output['active_low'] - val = PinState_Boolean(pin, ActiveLow) + if rpi_output['gpio_i2c_enabled']: + val = self.gpio_i2c_input(rpi_output, rpi_output['active_low']) + else: + val = PinState_Boolean(pin, ActiveLow) val2 = PinState_Human(pin, ActiveLow) index = self.to_int(rpi_output['index_id']) gpio_status.append(dict(index_id=index, status=val, State=val2)) @@ -533,7 +576,10 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP for rpi_output in self.rpi_outputs: if self.to_int(index) == self.to_int(rpi_output['index_id']): val = (not value) if rpi_output['active_low'] else value - self.write_gpio(self.to_int(rpi_output['gpio_pin']), val) + if rpi_output['gpio_i2c_enabled']: + self.gpio_i2c_write(rpi_output, val) + else: + self.write_gpio(self.to_int(rpi_output['gpio_pin']), val) return jsonify(success=True) @octoprint.plugin.BlueprintPlugin.route("/sendShellCommand", methods=["GET"]) @@ -642,7 +688,62 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP # DEPREACTION END + # GPIO over i2c + def gpio_i2c_input(self, output, active_low=None): + state = False + try: + i2cbus = self.to_int(output['gpio_i2c_bus']) + i2caddr = self.to_int(output['gpio_i2c_address']) + i2creg = self.to_int(output['gpio_i2c_register_status']) + data_on = self.to_int(output['gpio_i2c_data_on']) + + with SMBus(i2cbus) as bus: + data = bus.read_i2c_block_data(i2caddr, i2creg, 1) + if data[0] == data_on: + state = True + + self._logger.debug("gpio_i2c_input(i2cbus=%s, i2caddr=%s, i2creg=%s, data_on=%s) data == %s", + i2cbus, i2caddr, i2creg, data_on, data) + + if active_low is None and state: return state + + except Exception as ex: + self.log_error(ex) + + if active_low and not state: return True + if not active_low and state: return True + return False + + def gpio_i2c_write(self, output, state, queue_id=None): + try: + i2cbus = self.to_int(output['gpio_i2c_bus']) + i2caddr = self.to_int(output['gpio_i2c_address']) + i2creg = self.to_int(output['gpio_i2c_register']) + data_on = self.to_int(output['gpio_i2c_data_on']) + data_off = self.to_int(output['gpio_i2c_data_off']) + + with SMBus(i2cbus) as bus: + data = [] + if state: + data.append(data_on) + else: + data.append(data_off) + + bus.write_i2c_block_data(i2caddr, i2creg, data) + + if queue_id is not None: + self._logger.debug("Running scheduled queue id %s", queue_id) + self._logger.debug("Writing on GPIO (i2c): %s/%s value %s", output['gpio_i2c_address'], output['gpio_i2c_register'], state) + 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 i2c address {2}, reg {3}. Arguments:\n{4!r}" + message = template.format(type(ex).__name__, inspect.currentframe().f_code.co_name, output['gpio_i2c_address'], output['gpio_i2c_register'], ex.args) + self._logger.warn(message) + pass def send_neopixel_command(self, led_pin, led_count, led_brightness, red, green, blue, address, neopixel_dirrect, @@ -720,10 +821,13 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP index_id = self.to_int(output['index_id']) if output['output_type'] == 'regular': - if first_run: - current_value = False + if output['gpio_i2c_enabled']: + current_value = self.gpio_i2c_input(output) else: - current_value = (not GPIO.input(gpio_pin)) if output['active_low'] else GPIO.input(gpio_pin) + if first_run: + current_value = False + else: + current_value = (not GPIO.input(gpio_pin)) if output['active_low'] else GPIO.input(gpio_pin) if current_value: time_delay = self.to_int(output['toggle_timer_off']) @@ -731,12 +835,18 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP time_delay = self.to_int(output['toggle_timer_on']) if not self.print_complete: - self.write_gpio(gpio_pin, not current_value) + if output['gpio_i2c_enabled']: + self.gpio_i2c_write(output, not current_value) + else: + self.write_gpio(gpio_pin, not current_value) thread = threading.Timer(time_delay, self.toggle_output, args=[index_id]) thread.start() else: off_value = True if output['active_low'] else False - self.write_gpio(gpio_pin, off_value) + if output['gpio_i2c_enabled']: + self.gpio_i2c_write(output, off_value) + else: + self.write_gpio(gpio_pin, off_value) self.update_ui_outputs() return @@ -810,11 +920,17 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP shutdown = output['auto_shutdown'] if output['output_type'] == 'regular': - val = GPIO.input(pin) if not output['active_low'] else (not GPIO.input(pin)) + if output['gpio_i2c_enabled']: + val = self.gpio_i2c_input(output) + else: + val = GPIO.input(pin) if not output['active_low'] else (not GPIO.input(pin)) regular_status.append( dict(index_id=index, status=val, auto_startup=startup, auto_shutdown=shutdown)) if output['output_type'] == 'temp_hum_control': - val = GPIO.input(pin) if not output['active_low'] else (not GPIO.input(pin)) + if output['gpio_i2c_enabled']: + val = self.gpio_i2c_input(output) + else: + val = GPIO.input(pin) if not output['active_low'] else (not GPIO.input(pin)) temp_control_status.append( dict(index_id=index, status=val, auto_startup=startup, auto_shutdown=shutdown)) if output['output_type'] == 'neopixel_indirect' or output['output_type'] == 'neopixel_direct': @@ -876,6 +992,12 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP elif sensor['temp_sensor_type'] == "mcp9808": temp = self.read_mcp_temp(sensor['temp_sensor_address']) hum = 0 + elif sensor['temp_sensor_type'] == "temp_raw_i2c": + temp = self.read_raw_i2c_temp(sensor) + hum = 0 + elif sensor['temp_sensor_type'] == "hum_raw_i2c": + temp = 0 + hum = self.read_raw_i2c_temp(sensor) else: self._logger.info("temp_sensor_type no match") temp = None @@ -901,8 +1023,12 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP for rpi_controlled_output in self.rpi_outputs: if self.to_int(temperature_alarm['controlled_io']) == self.to_int( rpi_controlled_output['index_id']): - val = GPIO.LOW if temperature_alarm['controlled_io_set_value'] == 'low' else GPIO.HIGH - self.write_gpio(self.to_int(rpi_controlled_output['gpio_pin']), val) + if rpi_controlled_output['gpio_i2c_enabled']: + val = False if temperature_alarm['controlled_io_set_value'] == 'low' else True + self.gpio_i2c_write(rpi_controlled_output, val) + else: + val = GPIO.LOW if temperature_alarm['controlled_io_set_value'] == 'low' else GPIO.HIGH + self.write_gpio(self.to_int(rpi_controlled_output['gpio_pin']), val) for notification in self.notifications: if notification['temperatureAction']: msg = ("Temperature action: enclosure temperature exceed " + temperature_alarm[ @@ -920,6 +1046,28 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP return return_value, return_value + def read_raw_i2c_temp(self, sensor): + try: + i2cbus = self.to_int(sensor['temp_i2c_bus']) + i2caddr = self.to_int(sensor['temp_i2c_address']) + i2creg = self.to_int(sensor['temp_i2c_register']) + + with SMBus(i2cbus) as bus: + data = bus.read_i2c_block_data(i2caddr, i2creg, 4) + val = struct.unpack('f', bytearray(data)) + fval = val[0] + + self._logger.debug("read_raw_i2c_temp(i2cbus=%s, i2caddr=%s, i2creg=%s) data == %s (%s)", + i2cbus, i2caddr, i2creg, data, fval) + + return str(fval) + + except Exception as ex: + template = "An exception of type {0} occurred on {1} when reading on i2c address {2}, reg {3}. Arguments:\n{4!r}" + message = template.format(type(ex).__name__, inspect.currentframe().f_code.co_name, i2caddr, i2creg, ex.args) + self._logger.warn(message) + return str(-1) + def read_mcp_temp(self, address): try: script = os.path.dirname(os.path.realpath(__file__)) + "/mcp9808.py" @@ -1173,7 +1321,10 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP if current_status: self._logger.info("Turning gpio to control temperature on.") val = False if temp_hum_control['active_low'] else True - self.write_gpio(self.to_int(temp_hum_control['gpio_pin']), val) + if temp_hum_control['gpio_i2c_enabled']: + self.gpio_i2c_write(temp_hum_control, val) + else: + self.write_gpio(self.to_int(temp_hum_control['gpio_pin']), val) else: index_id = temp_hum_control['index_id'] if index_id in self.waiting_temperature: @@ -1184,7 +1335,10 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP self._logger.info("Turning gpio to control temperature off.") val = True if temp_hum_control['active_low'] else False - self.write_gpio(self.to_int(temp_hum_control['gpio_pin']), val) + if temp_hum_control['gpio_i2c_enabled']: + self.gpio_i2c_write(temp_hum_control, val) + else: + self.write_gpio(self.to_int(temp_hum_control['gpio_pin']), val) for control_status in self.temp_hum_control_status: if control_status['index_id'] == temp_hum_control['index_id']: control_status['status'] = current_status @@ -1202,8 +1356,9 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP set_mode = GPIO.BOARD if self._settings.get(["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 item[ - 'output_type'] == 'temp_hum_control' or item['output_type'] == 'neopixel_direct', + lambda item: (item['output_type'] == 'regular' or item['output_type'] == 'pwm' or item[ + 'output_type'] == 'temp_hum_control' or item['output_type'] == 'neopixel_direct') and + item['gpio_i2c_enabled'] == False, self.rpi_outputs)) inputs = list(filter(lambda item: item['input_type'] == 'gpio', self.rpi_inputs)) gpios = outputs + inputs @@ -1227,8 +1382,9 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP try: for gpio_out in list(filter( - lambda item: item['output_type'] == 'regular' or item['output_type'] == 'pwm' or item[ - 'output_type'] == 'temp_hum_control' or item['output_type'] == 'neopixel_direct', + lambda item: (item['output_type'] == 'regular' or item['output_type'] == 'pwm' or item[ + 'output_type'] == 'temp_hum_control' or item['output_type'] == 'neopixel_direct') and + item['gpio_i2c_enabled'] == False, self.rpi_outputs)): gpio_pin = self.to_int(gpio_out['gpio_pin']) if gpio_pin not in self.rpi_outputs_not_changed: @@ -1260,7 +1416,8 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP try: for gpio_out in list( - filter(lambda item: item['output_type'] == 'regular' or item['output_type'] == 'temp_hum_control', + filter(lambda item: (item['output_type'] == 'regular' or item['output_type'] == 'temp_hum_control') and + item['gpio_i2c_enabled'] == False, self.rpi_outputs)): initial_value = GPIO.HIGH if gpio_out['active_low'] else GPIO.LOW pin = self.to_int(gpio_out['gpio_pin']) @@ -1387,8 +1544,12 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP 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': - 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) + if rpi_output['gpio_i2c_enabled']: + val = False if rpi_input['controlled_io_set_value'] == 'low' else True + self.gpio_i2c_write(rpi_output, val) + 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) except Exception as ex: self.log_error(ex) pass @@ -1420,7 +1581,10 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP 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) + if rpi_output['gpio_i2c_enabled']: + self.gpio_i2c_write(rpi_output, val) + else: + 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( @@ -1685,7 +1849,10 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP gpio = self.to_int(rpi_output['gpio_pin']) if rpi_output['output_type'] == 'regular': value = False if rpi_output['active_low'] else True - self.write_gpio(gpio, value) + if rpi_output['gpio_i2c_enabled']: + self.gpio_i2c_write(rpi_output, value) + else: + self.write_gpio(gpio, value) if rpi_output['output_type'] == 'ledstrip': self.ledstrip_set_rgb(rpi_output) if rpi_output['output_type'] == 'pwm' and not rpi_output['pwm_temperature_linked']: @@ -1788,8 +1955,12 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP self._logger.debug("Scheduling regular output id %s on %s delay_seconds", queue_id, delay_seconds) - thread = threading.Timer(delay_seconds, self.write_gpio, - args=[self.to_int(rpi_output['gpio_pin']), value, queue_id]) + if rpi_output['gpio_i2c_enabled']: + thread = threading.Timer(delay_seconds, self.gpio_i2c_write, + args=[rpi_output, value, queue_id]) + else: + thread = threading.Timer(delay_seconds, self.write_gpio, + args=[self.to_int(rpi_output['gpio_pin']), value, queue_id]) self.event_queue.append(dict(queue_id=queue_id, thread=thread)) @@ -1904,7 +2075,10 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP set_value = self.constrain(set_value, 0, 1) value = True if set_value == 1 else False value = (not value) if output['active_low'] else value - self.write_gpio(self.to_int(output['gpio_pin']), value) + if output['gpio_i2c_enabled']: + self.gpio_i2c_write(output, value) + else: + self.write_gpio(self.to_int(output['gpio_pin']), value) comm_instance._log("Setting REGULAR output %s to value %s" % (index_id, value)) return if output['output_type'] == 'pwm': diff --git a/octoprint_enclosure/static/js/enclosure.js b/octoprint_enclosure/static/js/enclosure.js index e9c4847..048b45e 100644 --- a/octoprint_enclosure/static/js/enclosure.js +++ b/octoprint_enclosure/static/js/enclosure.js @@ -421,7 +421,14 @@ $(function () { ledstrip_gpio_dat: ko.observable(""), microcontroller_address: ko.observable(0), gcode: ko.observable(""), - show_on_navbar: ko.observable(false) + show_on_navbar: ko.observable(false), + gpio_i2c_enabled: ko.observable(false), + gpio_i2c_bus: ko.observable(1), + gpio_i2c_address: ko.observable(1), + gpio_i2c_register: ko.observable(1), + gpio_i2c_data_on: ko.observable(1), + gpio_i2c_data_off: ko.observable(0), + gpio_i2c_register_status: ko.observable(1) }); }; @@ -456,7 +463,10 @@ $(function () { temp_sensor_navbar: ko.observable(true), filament_sensor_timeout: ko.observable(120), filament_sensor_enabled: ko.observable(true), - temp_sensor_i2cbus: ko.observable(1) + temp_sensor_i2cbus: ko.observable(1), + temp_i2c_bus: ko.observable(1), + temp_i2c_address: ko.observable(1), + temp_i2c_register: ko.observable(1) }); }; diff --git a/octoprint_enclosure/templates/enclosure_settings.jinja2 b/octoprint_enclosure/templates/enclosure_settings.jinja2 index a30ca69..01ddaed 100644 --- a/octoprint_enclosure/templates/enclosure_settings.jinja2 +++ b/octoprint_enclosure/templates/enclosure_settings.jinja2 @@ -91,7 +91,7 @@ - +
@@ -263,6 +263,69 @@
+ +
+
+ + Active low means that the GPIO will turn on when receive a low signal (ground) from Raspberry PI +
+
+ + + +
+ +
+ + This value should remain 1 unless you've used dtoverlay=i2c-gpio or you are using another bus. + +
+
+ +
+ +
+ + I2C address in HEX value, you can find it by running + i2cdetect -y 1 on your Raspberry Pi +
+
+ +
+ +
+ + I2C register in HEX value +
+
+ +
+ +
+ + I2C data to write in HEX value when ON +
+
+ +
+ +
+ + I2C data to write in HEX value when OFF +
+
+ +
+ +
+ + I2C register for reading gpio state in HEX value +
+
+ +
@@ -540,6 +603,8 @@ + + Attention You need to install and configure the necessary libraries for the temperature sensor, check @@ -547,6 +612,35 @@ github page
+ + +
+ +
+ + This value should remain 1 unless you've used dtoverlay=i2c-gpio or you are using another bus. + +
+
+ +
+ +
+ + I2C address in HEX value, you can find it by running + i2cdetect -y 1 on your Raspberry Pi +
+
+ +
+ +
+ + I2C register in HEX value +
+
+ +
@@ -614,7 +708,7 @@
- +
diff --git a/setup.py b/setup.py index 3dd24a9..bcf8339 100644 --- a/setup.py +++ b/setup.py @@ -33,7 +33,7 @@ plugin_url = "https://github.com/vitormhenrique/OctoPrint-Enclosure" plugin_license = "AGPLv3" # Any additional requirements besides OctoPrint should be listed here -plugin_requires = ["RPi.GPIO>=0.6.5","requests>=2.7"] +plugin_requires = ["RPi.GPIO>=0.6.5","requests>=2.7","smbus2>=0.3.0"] additional_setup_parameters = {} From 05cf1e9684253dae8f5941b10849ad513efd426e Mon Sep 17 00:00:00 2001 From: Daniel Korgel Date: Wed, 10 Feb 2021 21:05:43 +0100 Subject: [PATCH 02/16] Implemented temperature and humidity display in graph --- octoprint_enclosure/__init__.py | 27 ++++++++++++++++--- octoprint_enclosure/static/js/enclosure.js | 4 ++- .../templates/enclosure_settings.jinja2 | 18 +++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/octoprint_enclosure/__init__.py b/octoprint_enclosure/__init__.py index 473321c..2559987 100644 --- a/octoprint_enclosure/__init__.py +++ b/octoprint_enclosure/__init__.py @@ -148,7 +148,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP self.print_complete = False def get_settings_version(self): - return 6 + return 7 def on_settings_migrate(self, target, current=None): self._logger.warn("######### current settings version %s target settings version %s #########", current, target) @@ -157,14 +157,25 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP self._logger.info("rpi_inputs: %s", self.rpi_inputs) self._logger.info("######### End Current Settings #########") if current >= 4 and target == 6: - self._logger.warn("######### migrating settings to v6 #########") old_outputs = self._settings.get(["rpi_outputs"]) + old_inputs = self._settings.get(["rpi_inputs"]) + 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 'shell_script' not in rpi_output: rpi_output['shell_script'] = "" + + if target >= 7: + self._logger.warn("######### migrating settings to v7+ #########") + for rpi_input in old_inputs: + if 'show_graph_temp' not in rpi_input: + rpi_input['show_graph_temp'] = False + if 'show_graph_humidity' not in rpi_input: + rpi_input['show_graph_humidity'] = False + self._settings.set(["rpi_outputs"], old_outputs) + self._settings.set(["rpi_inputs"], old_inputs) else: self._logger.warn("######### settings not compatible #########") self._settings.set(["rpi_outputs"], []) @@ -1944,6 +1955,15 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP comm_instance._log("Setting TEMP/HUM control output %s to value %s" % (index_id, set_value)) return + def get_graph_data(self, comm, parsed_temps): + for sensor in list(filter(lambda item: item['input_type'] == 'temperature_sensor', self.rpi_inputs)): + if sensor["show_graph_temp"]: + parsed_temps[str(sensor["label"])] = (sensor['temp_sensor_temp'], None) + if sensor["show_graph_humidity"]: + parsed_temps[str(sensor["label"])+" Humidity"] = (sensor['temp_sensor_humidity'], None) + + return parsed_temps + __plugin_name__ = "Enclosure Plugin" __plugin_pythoncompat__ = ">=2.7,<4" @@ -1956,5 +1976,6 @@ def __plugin_load__(): global __plugin_hooks__ __plugin_hooks__ = { "octoprint.comm.protocol.gcode.queuing" : __plugin_implementation__.hook_gcode_queuing, - "octoprint.plugin.softwareupdate.check_config": __plugin_implementation__.get_update_information + "octoprint.plugin.softwareupdate.check_config": __plugin_implementation__.get_update_information, + "octoprint.comm.protocol.temperatures.received": (__plugin_implementation__.get_graph_data, 1) } diff --git a/octoprint_enclosure/static/js/enclosure.js b/octoprint_enclosure/static/js/enclosure.js index e9c4847..36367e8 100644 --- a/octoprint_enclosure/static/js/enclosure.js +++ b/octoprint_enclosure/static/js/enclosure.js @@ -456,7 +456,9 @@ $(function () { temp_sensor_navbar: ko.observable(true), filament_sensor_timeout: ko.observable(120), filament_sensor_enabled: ko.observable(true), - temp_sensor_i2cbus: ko.observable(1) + temp_sensor_i2cbus: ko.observable(1), + show_graph_temp: ko.observable(false), + show_graph_humidity: ko.observable(false) }); }; diff --git a/octoprint_enclosure/templates/enclosure_settings.jinja2 b/octoprint_enclosure/templates/enclosure_settings.jinja2 index a30ca69..ab88291 100644 --- a/octoprint_enclosure/templates/enclosure_settings.jinja2 +++ b/octoprint_enclosure/templates/enclosure_settings.jinja2 @@ -765,6 +765,24 @@ Enable and disable temperature on navbar
+
+ + Enable to show temperature in temperature graph, when a printer is connected. + +

Note:This feature currently requires a custom graph plugin like PlotlyTempGraph

+ +
+
+ + Enable to show humidity in temperature graph, when a printer is connected. + +

Note:This feature currently requires a custom graph plugin like PlotlyTempGraph

+ +
From 77ac49ecf98bfef2b3fac9ac2f7a51edf2f5276f Mon Sep 17 00:00:00 2001 From: Daniel Korgel Date: Sun, 7 Mar 2021 11:44:58 +0100 Subject: [PATCH 03/16] Fixed bug in config updater --- octoprint_enclosure/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/octoprint_enclosure/__init__.py b/octoprint_enclosure/__init__.py index 2559987..fd9b0f8 100644 --- a/octoprint_enclosure/__init__.py +++ b/octoprint_enclosure/__init__.py @@ -156,7 +156,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP self._logger.info("rpi_outputs: %s", self.rpi_outputs) self._logger.info("rpi_inputs: %s", self.rpi_inputs) self._logger.info("######### End Current Settings #########") - if current >= 4 and target == 6: + if current >= 4 and target >= 6: old_outputs = self._settings.get(["rpi_outputs"]) old_inputs = self._settings.get(["rpi_inputs"]) self._logger.warn("######### migrating settings to v6+ #########") From 330d70e531b7dc26a04468b7eff2d95d1b3ac6a2 Mon Sep 17 00:00:00 2001 From: Vitor de Miranda Henrique Date: Thu, 18 Mar 2021 21:52:01 -0500 Subject: [PATCH 04/16] Update README.md --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e7e67fd..0224ec7 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +# QUICK NOTE: I suffered an injury last Sunday (06/20/20) and broke both bones on my left forearm, it will be impossible to work on on this plugin in the near future, I'm struggling to make it work with a full time job + masters in computers science. This plugin is not abandoned but it is on vacation mode. + + Find the plugin useful? Buy me a coffee [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/VitorHenrique/2) @@ -32,7 +35,7 @@ Check pictures on thingiverse: http://www.thingiverse.com/thing:2245493 Install the plugin using the Plugin Manager bundled with OctoPrint, you can search for the Enclosure plugin or just use the url: https://github.com/vitormhenrique/OctoPrint-Enclosure/archive/master.zip. -To control the enclosure temperature or get temperature triggered events, you need to install and configure a temperature sensor. This plugin can support DHT11, DHT22, AM2302, DS18B20, SI7021, BME280 and TMP102 temperature sensors. +To control the encosure temperature or get temperature trigged events, you need to install and configure a temperature sensor. This plugin can support DHT11, DHT22, AM2302, DS18B20, SI7021, BME280 and TMP102 temperature sensors. * For the DHT11, DHT22 and AM2302 follow this steps: @@ -170,7 +173,7 @@ Outputs can be set to the following types: * Regular GPIO * PWM GPIO -* Neopixel Control via Microcontroller +* Neopixel Control via Microcontroler * Neopixel Control directly from raspberry pi * Temperature and Humidity Control * Temperature Alarm @@ -191,7 +194,7 @@ Temperature Sensors will be used to input temperature and humidity data, they ca GPIO inputs will trigger events for the plugin, this feature can be used to add buttons to the enclosure and cause pressing those buttons to act on the printer or other pre-configured outputs. -After selecting GPIO for the input type, and selecting output control on the action type, the button will be able to turn on / off or toggle linked regular outputs, basically being able to control your lights / fan using mechanical buttons instead of the octoprint interface. You can also use buttons to send g-code commands. +After selecting GPIO for the input type, and selecting output control on the action type, the button will be able to turn on / off or toggle linked regular_gpio outputs, basically being able to control your lights / fan using mechanical buttons instead of the octoprint interface. You can also use buttons to send g-code commands. Selecting print control on the action type will trigger printer actions when the configured GPIO receives a signal. The actions can be Resume and Pause a print job or Change Filament. You can use the "change filament" action and set up the input GPIO according to your filament sensor, for example, if your filament sensor connects to ground when detects the end of the filament, you should choose PULL UP resistors and detect the event on the falling edge. You can also add mechanical buttons to pause, resume and change filaments near your printer for convenience. From 65c015243733dd09e1fb588fc8f43cb9283cc2cf Mon Sep 17 00:00:00 2001 From: Mitch Gallman Date: Mon, 3 May 2021 23:17:22 -0400 Subject: [PATCH 05/16] Add hum_raw_i2c & temp_raw_i2c as humidity capable --- octoprint_enclosure/static/js/enclosure.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/octoprint_enclosure/static/js/enclosure.js b/octoprint_enclosure/static/js/enclosure.js index 048b45e..7dab1b4 100644 --- a/octoprint_enclosure/static/js/enclosure.js +++ b/octoprint_enclosure/static/js/enclosure.js @@ -56,7 +56,7 @@ $(function () { self.notifications = ko.observableArray([]); self.humidityCapableSensor = function(sensor){ - if (['11', '22', '2302', 'bme280', 'am2320', 'si7021'].indexOf(sensor) >= 0){ + if (['11', '22', '2302', 'bme280', 'am2320', 'si7021', 'hum_raw_i2c', 'temp_raw_i2c'].indexOf(sensor) >= 0){ return true; } return false; From 04d57cc6d7691de938e4b971d0109ab8f8a0a01c Mon Sep 17 00:00:00 2001 From: Mitch Gallman Date: Mon, 3 May 2021 23:22:52 -0400 Subject: [PATCH 06/16] Change read_raw_i2c_temp to return both temp & hum Change read_raw_i2c_temp to return both temperature and humidity. Slave code concatenates the two float values into a byte array. --- octoprint_enclosure/__init__.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/octoprint_enclosure/__init__.py b/octoprint_enclosure/__init__.py index 8116e81..969d6a2 100644 --- a/octoprint_enclosure/__init__.py +++ b/octoprint_enclosure/__init__.py @@ -993,11 +993,9 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP temp = self.read_mcp_temp(sensor['temp_sensor_address']) hum = 0 elif sensor['temp_sensor_type'] == "temp_raw_i2c": - temp = self.read_raw_i2c_temp(sensor) - hum = 0 + temp, hum = self.read_raw_i2c_temp(sensor) elif sensor['temp_sensor_type'] == "hum_raw_i2c": - temp = 0 - hum = self.read_raw_i2c_temp(sensor) + hum, temp = self.read_raw_i2c_temp(sensor) else: self._logger.info("temp_sensor_type no match") temp = None @@ -1053,14 +1051,16 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP i2creg = self.to_int(sensor['temp_i2c_register']) with SMBus(i2cbus) as bus: - data = bus.read_i2c_block_data(i2caddr, i2creg, 4) - val = struct.unpack('f', bytearray(data)) - fval = val[0] + data = bus.read_i2c_block_data(i2caddr, i2creg, 8) + val = struct.unpack('f', bytearray(data[0:4])) + fval1 = val[0] + val = struct.unpack('f', bytearray(data[4:8])) + fval2 = val[0] - self._logger.debug("read_raw_i2c_temp(i2cbus=%s, i2caddr=%s, i2creg=%s) data == %s (%s)", - i2cbus, i2caddr, i2creg, data, fval) + self._logger.debug("read_raw_i2c_temp(i2cbus=%s, i2caddr=%s, i2creg=%s) data == %s (%s, %s)", + i2cbus, i2caddr, i2creg, data, fval1, fval2) - return str(fval) + return (fval1, fval2) except Exception as ex: template = "An exception of type {0} occurred on {1} when reading on i2c address {2}, reg {3}. Arguments:\n{4!r}" From 0c88c333a1fe2350cabaa5edcc401727fb52db1e Mon Sep 17 00:00:00 2001 From: Mitch Gallman Date: Tue, 4 May 2021 20:11:04 -0400 Subject: [PATCH 07/16] Handle nan in read_raw_i2c_temp --- octoprint_enclosure/__init__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/octoprint_enclosure/__init__.py b/octoprint_enclosure/__init__.py index 969d6a2..100908d 100644 --- a/octoprint_enclosure/__init__.py +++ b/octoprint_enclosure/__init__.py @@ -1054,9 +1054,13 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP data = bus.read_i2c_block_data(i2caddr, i2creg, 8) val = struct.unpack('f', bytearray(data[0:4])) fval1 = val[0] + if fval1 != fval1: + fval1 = 0 val = struct.unpack('f', bytearray(data[4:8])) fval2 = val[0] - + if fval2 != fval2: + fval2 = 0 + self._logger.debug("read_raw_i2c_temp(i2cbus=%s, i2caddr=%s, i2creg=%s) data == %s (%s, %s)", i2cbus, i2caddr, i2creg, data, fval1, fval2) From f90347105bc62788584419c95f1f080a6d675085 Mon Sep 17 00:00:00 2001 From: Mitch Gallman Date: Tue, 4 May 2021 20:38:15 -0400 Subject: [PATCH 08/16] Update __init__.py --- octoprint_enclosure/__init__.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/octoprint_enclosure/__init__.py b/octoprint_enclosure/__init__.py index 100908d..81fa589 100644 --- a/octoprint_enclosure/__init__.py +++ b/octoprint_enclosure/__init__.py @@ -1052,12 +1052,10 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP with SMBus(i2cbus) as bus: data = bus.read_i2c_block_data(i2caddr, i2creg, 8) - val = struct.unpack('f', bytearray(data[0:4])) - fval1 = val[0] + fval1 = struct.unpack('f', bytearray(data[0:4]))[0] if fval1 != fval1: fval1 = 0 - val = struct.unpack('f', bytearray(data[4:8])) - fval2 = val[0] + fval2 = struct.unpack('f', bytearray(data[4:8]))[0] if fval2 != fval2: fval2 = 0 From aa5bbe50ffcd6b34ca53ebd1a792bf687a057c7f Mon Sep 17 00:00:00 2001 From: Mitchell Way Date: Sat, 10 Jul 2021 21:33:08 -0500 Subject: [PATCH 09/16] adapt getDHTTemp.py to python3 --- octoprint_enclosure/__init__.py | 2 +- octoprint_enclosure/getDHTTemp.py | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/octoprint_enclosure/__init__.py b/octoprint_enclosure/__init__.py index 8116e81..0a6dfb3 100644 --- a/octoprint_enclosure/__init__.py +++ b/octoprint_enclosure/__init__.py @@ -1091,7 +1091,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP sudo_str = "sudo " else: sudo_str = "" - cmd = sudo_str + "python " + script + str(sensor) + " " + str(pin) + cmd = sudo_str + "python3 " + script + str(sensor) + " " + str(pin) if self._settings.get(["debug_temperature_log"]) is True: self._logger.debug("Temperature dht cmd: %s", cmd) stdout = (Popen(cmd, shell=True, stdout=PIPE).stdout).read() diff --git a/octoprint_enclosure/getDHTTemp.py b/octoprint_enclosure/getDHTTemp.py index cd6c18f..cb9bfef 100644 --- a/octoprint_enclosure/getDHTTemp.py +++ b/octoprint_enclosure/getDHTTemp.py @@ -1,19 +1,23 @@ import sys -import Adafruit_DHT +import adafruit_dht # Parse command line parameters. -sensor_args = { '11': Adafruit_DHT.DHT11, - '22': Adafruit_DHT.DHT22, - '2302': Adafruit_DHT.AM2302 } +sensor_args = { + '11': adafruit_dht.DHT11, + '22': adafruit_dht.DHT22, + '2302': adafruit_dht.DHT22 + } + if len(sys.argv) == 3 and sys.argv[1] in sensor_args: sensor = sensor_args[sys.argv[1]] pin = sys.argv[2] else: sys.exit(1) - -humidity, temperature = Adafruit_DHT.read_retry(sensor, pin,2,0.5) +dht_dev = sensor(pin) +humidity = dht_dev.humidity +temperature = dht_dev.temperature if humidity is not None and temperature is not None: print('{0:0.1f} | {1:0.1f}'.format(temperature, humidity)) From d56eab29e9bfbf178994001876a3731ffc904c83 Mon Sep 17 00:00:00 2001 From: Pierre-Alexis Ciavaldini Date: Tue, 3 Aug 2021 19:58:21 +0200 Subject: [PATCH 10/16] add description to the output id argument After struggling a bit to find the right argument, I think this description is a little more clear to what should be passed (tried the pin number and zero-based array before finding the right way in the code) --- API.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/API.md b/API.md index dbee16d..a09d46c 100644 --- a/API.md +++ b/API.md @@ -144,7 +144,7 @@ Error Responses: Endpoint: **PATCH** `/outputs/` -*Note: id needs to be int (index_id)* +*Note: id needs to be int (index_id), one-based index in octoprint settings' enclosure section's `rpi_outputs` list* Body (Content-Type: `application/json`): ``` @@ -340,4 +340,4 @@ Body: empty Response (204): No-Content Error Responses: -- none \ No newline at end of file +- none From 1ce086b42089d60fecb4b44b548a23884a59eb74 Mon Sep 17 00:00:00 2001 From: Chuck Bass Date: Wed, 4 Aug 2021 21:59:04 -0700 Subject: [PATCH 11/16] Update enclosure_settings.jinja2 Modified grammar to on settings page to sound correct to native English speakers. Fixed minor spelling errors. --- .../templates/enclosure_settings.jinja2 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/octoprint_enclosure/templates/enclosure_settings.jinja2 b/octoprint_enclosure/templates/enclosure_settings.jinja2 index 01ddaed..dfdf111 100644 --- a/octoprint_enclosure/templates/enclosure_settings.jinja2 +++ b/octoprint_enclosure/templates/enclosure_settings.jinja2 @@ -1,10 +1,10 @@

{{ _('Raspberry Pi Outputs') }}

Configure all - outputs. Outputs can be everything that do actions based on UI button presses or automatic events or alarms. + outputs. Outputs can be everything that performs actions based on UI button presses, or automatic events or alarms.

- Example of possible outputs are gpio pins, neopixel LED's, temperature control or sending gcode to the printer. + Example of possible outputs are GPIO pins, neopixel LED's, temperature control or sending gcode to the printer.

@@ -773,7 +773,7 @@ - Choose what type of pull resistors that you want on the output. If you signal is active low, that means it should + Choose what type of pull resistors that you want on the output. If your signal is active low, that means it should run the action when receive a low signal (ground), you should choose PULL UP resistors.
@@ -784,8 +784,8 @@ - Do you want thrigger the event on the rise or falling edge? If you signal is active low, that means it should run - the action when receive a low signal (ground), you should choose FALLING EDGE. + Do you want to trigger the event on the rise or falling edge? If you signal is active low, that means it should run + the action when it receives a low signal (ground), you should choose FALLING EDGE.
@@ -796,7 +796,7 @@ - When the event happen, you want control which OUTPUT? + When the event happens, do you want control of which OUTPUT? @@ -808,7 +808,7 @@ - When the event happen, you want to turn the controlled IO HIGH or LOW? + When the event happens, you do want to turn the controlled IO HIGH or LOW? @@ -947,7 +947,7 @@
GCODE that will be sent to the printer to pause and allow filament to be changed. You should add - ENTER on the end of every line sent to the printer + ENTER to the end of every line sent to the printer
From f5ed2790c3080048c47e04a796a0f6aaea54e4e6 Mon Sep 17 00:00:00 2001 From: Chuck Bass Date: Thu, 9 Sep 2021 12:58:21 -0700 Subject: [PATCH 12/16] Update octoprint_enclosure/templates/enclosure_settings.jinja2 Co-authored-by: Mitch Gallman --- octoprint_enclosure/templates/enclosure_settings.jinja2 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/octoprint_enclosure/templates/enclosure_settings.jinja2 b/octoprint_enclosure/templates/enclosure_settings.jinja2 index dfdf111..e79032c 100644 --- a/octoprint_enclosure/templates/enclosure_settings.jinja2 +++ b/octoprint_enclosure/templates/enclosure_settings.jinja2 @@ -808,7 +808,8 @@ - When the event happens, you do want to turn the controlled IO HIGH or LOW? + When the event happens, do you want to turn the controlled IO HIGH or LOW? + From d615faef8d3d4ab521d3be07c0d55a989d24ae67 Mon Sep 17 00:00:00 2001 From: Adam Demuri Date: Wed, 6 Oct 2021 19:46:48 -0600 Subject: [PATCH 13/16] Add option for pullup for DS18B20 These sensors need a pullup resistor on the data pin. Instead of using an external pullup, this adds an option to use an internal pullup. --- README.md | 14 +++++++++++++- octoprint_enclosure/__init__.py | 12 +++++++++++- .../templates/enclosure_settings.jinja2 | 10 ++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0224ec7..1a01df6 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ Note that the first argument is the temperature sensor (11, 22, or 2302), and th * For the DS18B20 sensor: -Follow the wiring diagram on the pictures on thingiverse. The DS18B20 uses "1-wire" communication protocol, you need to use 4.7K to 10K resistor from the data pin to VCC, DS18B20 only works on GPIO pin number 4 by default. You also need to add OneWire support for your raspberry pi. +Follow the wiring diagram on the pictures on thingiverse. The DS18B20 uses "1-wire" communication protocol, DS18B20 only works on GPIO pin number 4 by default. You also need to add OneWire support for your raspberry pi. Start by adding the following line to /boot/config.txt @@ -76,6 +76,16 @@ After rebooting, you can check if the OneWire device was found properly with You should see something like
[    3.030368] w1-gpio onewire@0: gpio pin 4, external pullup pin -1, parasitic power 0
+If you're using the internal pullup resistor, you'll need to enable it manually by running these Python commands. Or, you can simply configure the sensor inside of the Enclosure plugin, which will do this for you. + +```python +import RPi.GPIO as GPIO + +PIN=4 +GPIO.setmode(GPIO.BCM) +GPIO.setup(PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) +``` + You should be able to test your sensor by rebooting your system with sudo reboot. When the Pi is back up and you're logged in again, type the commands you see below into a terminal window. When you are in the 'devices' directory, the directory starting '28-' may have a different name, so cd to the name of whatever directory is there.
sudo modprobe w1-gpio
@@ -89,6 +99,8 @@ The response will either have YES or NO at the end of the first line. If it is y
 
 Copy the serial number, you will need to configure the plugin.  Note that for the serial number includes the 28-, for example 28-0000069834ff.
 
+The DS18B20 needs a pullup resistor on the data pin. On modern Pi models, you can use a resistor built into the Pi, configured in software. To do this, set the "Input Pull Resistor" option to "Input Pullup". If this doesn't work, you need to use a 4.7K to 10K resistor from the data pin to VCC.
+
 * For the SI7021, BME280, TMP102 and MCP9808 sensors
 
 Enable I2C on your raspberry pi, depending on raspi-config version, step by step can be different:
diff --git a/octoprint_enclosure/__init__.py b/octoprint_enclosure/__init__.py
index 8116e81..0ab7c83 100644
--- a/octoprint_enclosure/__init__.py
+++ b/octoprint_enclosure/__init__.py
@@ -1348,7 +1348,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP
     def log_error(self, ex):
         template = "An exception of type {0} occurred on {1}. Arguments:\n{2!r}"
         message = template.format(type(ex).__name__, inspect.currentframe().f_code.co_name, ex.args)
-        self._logger.warn(message)
+        self._logger.warn(message, exc_info = True)
 
     def setup_gpio(self):
         try:
@@ -1461,6 +1461,16 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP
                 if (rpi_input['action_type'] == 'printer_control' and rpi_input['printer_action'] != 'filament'):
                     GPIO.add_event_detect(gpio_pin, edge, callback=self.handle_printer_action, bouncetime=200)
                     self._logger.info("Adding PRINTER CONTROL event detect on pin %s with edge: %s", gpio_pin, edge)
+            
+            for rpi_input in list(filter(lambda item: item['input_type'] == 'temperature_sensor', self.rpi_inputs)):
+                gpio_pin = self.to_int(rpi_input['gpio_pin'])
+                if rpi_input['input_pull_resistor'] == 'input_pull_up':
+                    pull_resistor = GPIO.PUD_UP
+                elif rpi_input['input_pull_resistor'] == 'input_pull_down':
+                    pull_resistor = GPIO.PUD_DOWN
+                else:
+                    pull_resistor = GPIO.PUD_OFF
+                GPIO.setup(gpio_pin, GPIO.IN, pull_up_down=pull_resistor)
         except Exception as ex:
             self.log_error(ex)
 
diff --git a/octoprint_enclosure/templates/enclosure_settings.jinja2 b/octoprint_enclosure/templates/enclosure_settings.jinja2
index 01ddaed..506153f 100644
--- a/octoprint_enclosure/templates/enclosure_settings.jinja2
+++ b/octoprint_enclosure/templates/enclosure_settings.jinja2
@@ -649,6 +649,16 @@
           GPIO pin for temperature sensor, recommended to use 4 as DS18B20 has default support to pin #4 (BCM)
         
       
+      
+ +
+ + Whether to enable the built-in pullup for this temperature sensor. If set, then no external pullup is needed. +
+
From 528e3e8a2c27a6c3209bc851bc0d6fc543de02eb Mon Sep 17 00:00:00 2001 From: jneilliii Date: Wed, 13 Oct 2021 00:48:40 -0400 Subject: [PATCH 14/16] fix deprecated payload in PrintDone event This should resolve the error associated with #432 --- octoprint_enclosure/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/octoprint_enclosure/__init__.py b/octoprint_enclosure/__init__.py index 8116e81..70e6404 100644 --- a/octoprint_enclosure/__init__.py +++ b/octoprint_enclosure/__init__.py @@ -1800,7 +1800,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP if event == Events.PRINT_DONE: for notification in self.notifications: if notification['printFinish']: - file_name = os.path.basename(payload["file"]) + file_name = os.path.basename(payload["path"]) elapsed_time_in_seconds = payload["time"] elapsed_time = octoprint.util.get_formatted_timedelta(timedelta(seconds=elapsed_time_in_seconds)) msg = "Print job finished: " + file_name + "finished printing in " + file_name, elapsed_time From 21281c9711ba0f12e2655febcf4034349031d933 Mon Sep 17 00:00:00 2001 From: Daniel Korgel Date: Wed, 13 Oct 2021 14:40:11 +0200 Subject: [PATCH 15/16] incremented settings version number --- octoprint_enclosure/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/octoprint_enclosure/__init__.py b/octoprint_enclosure/__init__.py index 6f0d00f..5d4af89 100644 --- a/octoprint_enclosure/__init__.py +++ b/octoprint_enclosure/__init__.py @@ -150,7 +150,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP self.print_complete = False def get_settings_version(self): - return 8 + return 9 def on_settings_migrate(self, target, current=None): self._logger.warn("######### current settings version %s target settings version %s #########", current, target) @@ -158,8 +158,8 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP self._logger.info("rpi_outputs: %s", self.rpi_outputs) self._logger.info("rpi_inputs: %s", self.rpi_inputs) self._logger.info("######### End Current Settings #########") - if current >= 4 and target == 8: - self._logger.warn("######### migrating settings to v8 #########") + if current >= 4 and target == 9: + self._logger.warn("######### migrating settings to v9 #########") old_outputs = self._settings.get(["rpi_outputs"]) old_inputs = self._settings.get(["rpi_inputs"]) for rpi_output in old_outputs: From ac8929842c654b734020d6607abb8e4622bd7f4c Mon Sep 17 00:00:00 2001 From: Vitor de Miranda Henrique Date: Wed, 13 Oct 2021 12:38:11 -0500 Subject: [PATCH 16/16] Update README.md --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 1a01df6..982b585 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,3 @@ -# QUICK NOTE: I suffered an injury last Sunday (06/20/20) and broke both bones on my left forearm, it will be impossible to work on on this plugin in the near future, I'm struggling to make it work with a full time job + masters in computers science. This plugin is not abandoned but it is on vacation mode. - - Find the plugin useful? Buy me a coffee [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/VitorHenrique/2)