Added support for adafruit EMC2101 #480
26
octoprint_enclosure/EMC2101.py
Normal file
26
octoprint_enclosure/EMC2101.py
Normal file
@@ -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()
|
||||
23
octoprint_enclosure/SETEMC2101.py
Normal file
23
octoprint_enclosure/SETEMC2101.py
Normal file
@@ -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()
|
||||
@@ -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/<int:identifier>", 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/<int:identifier>", 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'],
|
||||
|
||||
@@ -22,6 +22,11 @@
|
||||
<label class="radio">
|
||||
<input type="radio" value="pwm" data-bind="checked: output_type, attr: {name: 'output_type_' + $index() }"> {{ _('PWM') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<label class="radio">
|
||||
<input type="radio" value="emc" data-bind="checked: output_type, attr: {name: 'output_type_' + $index() }"> {{ _('EMC 2101') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<label class="radio">
|
||||
@@ -91,7 +96,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
<!-- ko ifnot: ($data.output_type() == "gcode_output" || $data.output_type() == "temperature_alarm" || $data.output_type() == "shell_output" || $data.output_type() == "ledstrip" || ($data.output_type() == "regular" && $data.gpio_i2c_enabled())) -->
|
||||
<!-- ko ifnot: ($data.output_type() == "gcode_output" || $data.output_type() == "temperature_alarm" || $data.output_type() == "emc" || $data.output_type() == "shell_output" || $data.output_type() == "ledstrip" || ($data.output_type() == "regular" && $data.gpio_i2c_enabled())) -->
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ _('IO Number') }}</label>
|
||||
<div class="controls">
|
||||
@@ -110,13 +115,13 @@
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko if: ($data.output_type() == "pwm" ) -->
|
||||
<!-- ko if: (($data.output_type() == "pwm" ) || ($data.output_type() == "emc" )) -->
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" data-bind="checked: pwm_temperature_linked"> {{ _('Link PWM to Temperature') }}
|
||||
<input type="checkbox" data-bind="checked: pwm_temperature_linked"> {{ _('Link PWM/EMC2101 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
|
||||
<span class="help-inline">Link PWM/EMC2101 ouput to temperature. PWM/EMC2101 output will be interpolated between the point from duty A, temperature A -> duty
|
||||
B, temperature B. This output will automatically start when a print starts and will default to the default
|
||||
duty cycle when print is complete.
|
||||
</span>
|
||||
@@ -124,7 +129,7 @@
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
|
||||
<!-- ko if: ($data.output_type() == "pwm" && $data.pwm_temperature_linked()) -->
|
||||
<!-- ko if: (($data.output_type() == "pwm" || $data.output_type() == "emc") && $data.pwm_temperature_linked()) -->
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ _('Duty A') }}</label>
|
||||
<div class="controls">
|
||||
@@ -184,6 +189,7 @@
|
||||
<!-- ko ifnot: (($data.output_type() == "regular" || $data.output_type() == "pwm") && $data.toggle_timer()) -->
|
||||
<!-- ko ifnot: ($data.output_type() == "gcode_output" || $data.output_type() == "temperature_alarm" || $data.output_type() == "shell_output") -->
|
||||
<!-- ko ifnot: ($data.output_type() == "pwm" && $data.pwm_temperature_linked()) -->
|
||||
<!-- ko ifnot: ($data.output_type() == "emc") -->
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
@@ -215,7 +221,8 @@
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
<!-- /ko -->
|
||||
<!-- ko ifnot: ($data.output_type() == "gcode_output" || $data.output_type() == "temperature_alarm" || $data.output_type() == "shell_output") -->
|
||||
<!-- /ko -->
|
||||
<!-- ko ifnot: ($data.output_type() == "gcode_output" || $data.output_type() == "emc" || $data.output_type() == "temperature_alarm" || $data.output_type() == "shell_output") -->
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
@@ -250,7 +257,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
<!-- ko ifnot: ($data.output_type() == "gcode_output" || $data.output_type() == "temperature_alarm" || $data.output_type() == "shell_output") -->
|
||||
<!-- ko ifnot: ($data.output_type() == "gcode_output" || $data.output_type() == "emc" || $data.output_type() == "temperature_alarm" || $data.output_type() == "shell_output") -->
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
@@ -475,6 +482,15 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
<!-- ko if: ($data.output_type() == "emc") -->
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ _('Default fan speed') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-block-level" data-bind="value: default_duty_cycle">
|
||||
<span class="help-inline">Value is in percentage, between 0 and 100</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /ko -->
|
||||
<!-- ko if: ($data.output_type() == "neopixel_indirect") -->
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="settings-enclosure-dhtPin">{{ _('Microcontroller Address') }}</label>
|
||||
@@ -612,6 +628,7 @@
|
||||
<option value="bme680">BME680</option>
|
||||
<option value="am2320">AM2320</option>
|
||||
<option value="aht10">AHT10</option>
|
||||
<option value="emc2101">EMC2101</option>
|
||||
<option value="tmp102">TMP102</option>
|
||||
<option value="max31855">MAX31855</option>
|
||||
<option value="rpi">Raspberry Pi CPU</option>
|
||||
@@ -731,7 +748,7 @@
|
||||
</div>
|
||||
|
||||
<!-- /ko -->
|
||||
<!-- ko ifnot: ($data.temp_sensor_type() == "rpi") || ($data.temp_sensor_type() == "18b20") || ($data.temp_sensor_type() == "si7021") || ($data.temp_sensor_type() == "bme280") || ($data.temp_sensor_type() == "am2320") || ($data.temp_sensor_type() == "tmp102") || ($data.temp_sensor_type() == "max31855") || ($data.temp_sensor_type() == "mcp9808") || ($data.temp_sensor_type() == "temp_raw_i2c") || ($data.temp_sensor_type() == "hum_raw_i2c") -->
|
||||
<!-- ko ifnot: ($data.temp_sensor_type() == "rpi") || $data.temp_sensor_type() == "emc2101" || ($data.temp_sensor_type() == "18b20") || ($data.temp_sensor_type() == "si7021") || ($data.temp_sensor_type() == "bme280") || ($data.temp_sensor_type() == "am2320") || ($data.temp_sensor_type() == "tmp102") || ($data.temp_sensor_type() == "max31855") || ($data.temp_sensor_type() == "mcp9808") || ($data.temp_sensor_type() == "temp_raw_i2c") || ($data.temp_sensor_type() == "hum_raw_i2c") -->
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="settings-enclosure-dhtPin">{{ _('Sensor Pin') }}</label>
|
||||
<div class="controls">
|
||||
|
||||
Reference in New Issue
Block a user