From 3a7a12819b8244c10773584411d1d130dc9fbaa8 Mon Sep 17 00:00:00 2001 From: JeremyLaurenson Date: Wed, 16 Feb 2022 18:06:08 -0500 Subject: [PATCH] Added support for EMC2101 PWM/Temp board Added support for the Adafruit EMC2101 --- octoprint_enclosure/EMC2101.py | 26 ++++++++ octoprint_enclosure/SETEMC2101.py | 23 +++++++ octoprint_enclosure/__init__.py | 106 ++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 octoprint_enclosure/EMC2101.py create mode 100644 octoprint_enclosure/SETEMC2101.py diff --git a/octoprint_enclosure/EMC2101.py b/octoprint_enclosure/EMC2101.py new file mode 100644 index 0000000..8a373d1 --- /dev/null +++ b/octoprint_enclosure/EMC2101.py @@ -0,0 +1,26 @@ +import time +import board +from adafruit_emc2101.emc2101_lut import EMC2101_LUT as EMC2101 + +i2c = board.I2C() # uses board.SCL and board.SDA +FAN_MAX_RPM = 1700 +emc = EMC2101(i2c) + + +def getTemp(): + return(emc.internal_temperature) + +def getSpeed(): + return(emc.fan_speed) + +def main(): + + try: + temperature = getTemp() + fanspeed = getSpeed() + print('{0:0.1f} | {1:0.1f}'.format(temperature, fanspeed)) + except: + print('-1 | -1') + +if __name__ == "__main__": + main() diff --git a/octoprint_enclosure/SETEMC2101.py b/octoprint_enclosure/SETEMC2101.py new file mode 100644 index 0000000..688212f --- /dev/null +++ b/octoprint_enclosure/SETEMC2101.py @@ -0,0 +1,23 @@ +import sys +import board +from adafruit_emc2101.emc2101_lut import EMC2101_LUT as EMC2101 + +i2c = board.I2C() # uses board.SCL and board.SDA +FAN_MAX_RPM = 1700 +emc = EMC2101(i2c) + + + + +def main(): + # total arguments + n = len(sys.argv) + if n != 2: + print("No_duty_cycle_specified") + sys.exit(2) + + dutyCycle=int(sys.argv[1]) + emc.manual_fan_speed = dutyCycle + +if __name__ == "__main__": + main() diff --git a/octoprint_enclosure/__init__.py b/octoprint_enclosure/__init__.py index 441bc71..63dd42f 100644 --- a/octoprint_enclosure/__init__.py +++ b/octoprint_enclosure/__init__.py @@ -457,6 +457,33 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP self.write_pwm(gpio, set_value) return make_response('', 204) + @octoprint.plugin.BlueprintPlugin.route("/emc/", methods=["PATCH"]) + @restricted_access + def set_emc2101(self, identifier): + if "application/json" not in request.headers["Content-Type"]: + return make_response("expected json", 400) + try: + data = request.json + except BadRequest: + return make_response("malformed request", 400) + if 'duty_cycle' not in data: + return make_response("missing duty_cycle attribute", 406) + set_value = self.to_int(data['duty_cycle']) + script = os.path.dirname(os.path.realpath(__file__)) + "/SETEMC2101.py" + cmd = [sys.executable, script, str(set_value)] + if self._settings.get(["use_sudo"]): + cmd.insert(0, "sudo") + stdout = Popen(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True) + output, errors = stdout.communicate() + if self._settings.get(["debug_temperature_log"]) is True: + if len(errors) > 0: + self._logger.error("EMC2101 error: %s", errors) + else: + self._logger.debug("EMC2101 result: %s", output) + self._logger.debug(output + " " + errors) + return make_response('', 204) + + @octoprint.plugin.BlueprintPlugin.route("/rgb-led/", methods=["PATCH"]) @restricted_access def set_ledstrip_color(self, identifier): @@ -835,6 +862,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP self.handle_temp_hum_control() self.handle_temperature_events() self.handle_pwm_linked_temperature() + self.handle_emc_linked_temperature() self.update_ui() self.mqtt_sensor_topic = self.mqtt_root_topic + "/" + sensor['label'] self.mqtt_message = {"temperature": temp, "humidity": hum} @@ -1006,6 +1034,10 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP temp = self.read_18b20_temp(sensor['ds18b20_serial']) hum = 0 airquality = 0 + elif sensor['temp_sensor_type'] == "emc2101": + temp, hum = self.read_emc2101_temp(sensor['temp_sensor_address'], sensor['temp_sensor_i2cbus']) + hum =0 + airquality = 0 elif sensor['temp_sensor_type'] == "bme280": temp, hum = self.read_bme280_temp(sensor['temp_sensor_address']) airquality = 0 @@ -1226,6 +1258,31 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP "Failed to execute python scripts, try disabling use SUDO on advanced section of the plugin.") self.log_error(ex) return (0, 0) + + def read_emc2101_temp(self, address, i2cbus): + try: + script = os.path.dirname(os.path.realpath(__file__)) + "/EMC2101.py" + cmd = [sys.executable, script, str(address), str(i2cbus)] + if self._settings.get(["use_sudo"]): + cmd.insert(0, "sudo") + if self._settings.get(["debug_temperature_log"]) is True: + self._logger.debug("Temperature EMC2101 cmd: %s", cmd) + stdout = Popen(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True) + output, errors = stdout.communicate() + if self._settings.get(["debug_temperature_log"]) is True: + if len(errors) > 0: + self._logger.error("EMC2101 error: %s", errors) + else: + self._logger.debug("EMC2101 result: %s", output) + temp, fanspeed = output.split("|") + print (temp + " , " + fanspeed ) + return (self.to_float(temp.strip()), 0.0 ) + except Exception as ex: + print(ex) + self._logger.info( + "Failed to execute python scripts, try disabling use SUDO on advanced section of the plugin.") + self.log_error(ex) + return (0, 0) def read_aht10_temp(self, address, i2cbus): try: @@ -1346,6 +1403,55 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP self.log_error(ex) return 0 + + + def handle_emc_linked_temperature(self): + try: + for pwm_output in list(filter(lambda item: item['output_type'] == 'emc', + self.rpi_outputs)): + if self._printer.is_printing(): + index_id = self.to_int(pwm_output['index_id']) + linked_id = self.to_int(pwm_output['linked_temp_sensor']) + linked_data = self.get_linked_temp_sensor_data(linked_id) + current_temp = self.to_float(linked_data['temperature']) + + duty_a = self.to_float(pwm_output['duty_a']) + duty_b = self.to_float(pwm_output['duty_b']) + temp_a = self.to_float(pwm_output['temperature_a']) + temp_b = self.to_float(pwm_output['temperature_b']) + + try: + calculated_duty = ((current_temp - temp_a) * (duty_b - duty_a) / (temp_b - temp_a)) + duty_a + + if current_temp < temp_a: + calculated_duty = 0 + except: + calculated_duty = 0 + + self._logger.debug("Calculated duty for EMC %s is %s", index_id, calculated_duty) + elif self.print_complete: + calculated_duty = self.to_int(pwm_output['default_duty_cycle']) + else: + calculated_duty = self.to_int(pwm_output['default_duty_cycle']) + script = os.path.dirname(os.path.realpath(__file__)) + "/SETEMC2101.py" + cmd = [sys.executable, script, str(int(calculated_duty))] + if self._settings.get(["use_sudo"]): + cmd.insert(0, "sudo") + self._logger.info("Calculated fan speed is ", calculated_duty) + stdout = Popen(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True) + output, errors = stdout.communicate() + if self._settings.get(["debug_temperature_log"]) is True: + if len(errors) > 0: + self._logger.error("EMC2101 error: %s", errors) + else: + self._logger.debug("EMC2101 result: %s", output) + self._logger.debug(output + " " + errors) + + + except Exception as ex: + self.log_error(ex) + + def handle_pwm_linked_temperature(self): try: for pwm_output in list(filter(lambda item: item['output_type'] == 'pwm' and item['pwm_temperature_linked'],