Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for adafruit EMC2101 #480

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions octoprint_enclosure/EMC2101.py
Original file line number Diff line number Diff line change
@@ -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 changes: 23 additions & 0 deletions octoprint_enclosure/SETEMC2101.py
Original file line number Diff line number Diff line change
@@ -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()
106 changes: 106 additions & 0 deletions octoprint_enclosure/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,33 @@ def set_pwm(self, identifier):
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):
Expand Down Expand Up @@ -835,6 +862,7 @@ def check_enclosure_temp(self):
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}
Expand Down Expand Up @@ -1006,6 +1034,10 @@ def get_sensor_data(self, sensor):
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
Expand Down Expand Up @@ -1226,6 +1258,31 @@ def read_am2320_temp(self):
"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:
Expand Down Expand Up @@ -1346,6 +1403,55 @@ def read_max31855_temp(self, address):
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'],
Expand Down
33 changes: 25 additions & 8 deletions octoprint_enclosure/templates/enclosure_settings.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down Expand Up @@ -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">
Expand All @@ -110,21 +115,21 @@
</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>
</div>
</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">
Expand Down Expand Up @@ -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">
Expand Down Expand Up @@ -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">
Expand Down Expand Up @@ -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">
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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">
Expand Down