Update __init__.py
Unlimited GPIO Outputs Unlimited Trigggger actions based on events (Temeprature, fillament or GPIO) Showing status of GPIO on enclosure tab Shutdown timeout reset after print start Default temperature for enclosure
This commit is contained in:
committed by
GitHub
parent
62fb5343f6
commit
bd542a1d08
@@ -8,44 +8,12 @@ import RPi.GPIO as GPIO
|
||||
import flask
|
||||
import sched
|
||||
import time
|
||||
import sys
|
||||
import glob
|
||||
import os
|
||||
|
||||
scheduler = sched.scheduler(time.time, time.sleep)
|
||||
|
||||
class EnclosureGPIO():
|
||||
def __init__(self, pinNumber, label, activeLow, enable,autoStartup, autoShutDown,isOutput,timeDelay,timeOffDelay):
|
||||
self.pinNumber = pinNumber
|
||||
self.label = label
|
||||
self.activeLow = activeLow
|
||||
self.enable = enable
|
||||
self.autoShutDown = autoShutDown
|
||||
self.autoStartup = autoStartup
|
||||
self.isOutput = isOutput
|
||||
self.timeDelay = timeDelay
|
||||
self.timeOffDelay = timeOffDelay
|
||||
|
||||
def configureGPIO(self):
|
||||
try:
|
||||
if self.enable:
|
||||
if self.isOutput:
|
||||
if self.activeLow: #if is active low, we start disabelling it by making it high!
|
||||
GPIO.setup(self.pinNumber, GPIO.OUT, initial=GPIO.HIGH)
|
||||
else:
|
||||
GPIO.setup(self.pinNumber, GPIO.OUT, initial=GPIO.LOW)
|
||||
else:
|
||||
if self.activeLow:
|
||||
GPIO.setup(self.pinNumber, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
||||
else:
|
||||
GPIO.setup(self.pinNumber, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
|
||||
except:
|
||||
self._logger.info("Error while configuring GPIO: %s",self.pinNumber)
|
||||
pass
|
||||
|
||||
def write(self,active):
|
||||
if self.activeLow:
|
||||
active = not active
|
||||
GPIO.output(self.pinNumber, active)
|
||||
|
||||
class EnclosurePlugin(octoprint.plugin.StartupPlugin,
|
||||
octoprint.plugin.TemplatePlugin,
|
||||
octoprint.plugin.SettingsPlugin,
|
||||
@@ -53,56 +21,16 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
|
||||
octoprint.plugin.BlueprintPlugin,
|
||||
octoprint.plugin.EventHandlerPlugin):
|
||||
|
||||
previousHeaterStatus = False
|
||||
currentHeaterStatus = False
|
||||
previousTempControlStatus = False
|
||||
currentTempControlStatus = False
|
||||
enclosureSetTemperature=0.0
|
||||
enclosureCurrentTemperature=0.0
|
||||
enclosureCurrentHumidity=0.0
|
||||
lastFilamentEndDetected=0
|
||||
def startGPIO(self):
|
||||
if self._settings.get(["useBoardPinNumber"]):
|
||||
GPIO.cleanup()
|
||||
GPIO.setmode(GPIO.BOARD)
|
||||
else:
|
||||
GPIO.cleanup()
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
GPIO.setwarnings(False)
|
||||
|
||||
self.io1 = EnclosureGPIO(self._settings.get_int(["io1Pin"]),self._settings.get(["io1Label"]),self._settings.get(["io1ActiveLow"]),
|
||||
self._settings.get(["io1Enable"]),self._settings.get(["io1AutoStartup"]),
|
||||
self._settings.get(["io1AutoShutDown"]),True,self._settings.get(["io1TimeDelay"]),
|
||||
self._settings.get(["io1OffTimeDelay"]))
|
||||
|
||||
self.io2 = EnclosureGPIO(self._settings.get_int(["io2Pin"]),self._settings.get(["io2Label"]),self._settings.get(["io2ActiveLow"]),
|
||||
self._settings.get(["io2Enable"]),self._settings.get(["io2AutoStartup"]),
|
||||
self._settings.get(["io2AutoShutDown"]),True,self._settings.get(["io2TimeDelay"]),
|
||||
self._settings.get(["io2OffTimeDelay"]))
|
||||
|
||||
self.io3 = EnclosureGPIO(self._settings.get_int(["io3Pin"]),self._settings.get(["io3Label"]),self._settings.get(["io3ActiveLow"]),
|
||||
self._settings.get(["io3Enable"]),self._settings.get(["io3AutoStartup"]),
|
||||
self._settings.get(["io3AutoShutDown"]),True,self._settings.get(["io3TimeDelay"]),
|
||||
self._settings.get(["io3OffTimeDelay"]))
|
||||
|
||||
self.io4 = EnclosureGPIO(self._settings.get_int(["io4Pin"]),self._settings.get(["io4Label"]),self._settings.get(["io4ActiveLow"]),
|
||||
self._settings.get(["io4Enable"]),self._settings.get(["io4AutoStartup"]),
|
||||
self._settings.get(["io4AutoShutDown"]),True,self._settings.get(["io4TimeDelay"]),
|
||||
self._settings.get(["io4OffTimeDelay"]))
|
||||
|
||||
self.heater = EnclosureGPIO(self._settings.get_int(["heaterPin"]),"heater",self._settings.get(["heaterActiveLow"]),
|
||||
self._settings.get(["heaterEnable"]),False,True,True,0,0)
|
||||
|
||||
self.filamentSensor = EnclosureGPIO(self._settings.get_int(["filamentSensorPin"]),"filamentSensor",
|
||||
self._settings.get(["filamentSensorActiveLow"]),self._settings.get(["filamentSensorEnable"]),
|
||||
False,False,False,0,0)
|
||||
|
||||
self.io1.configureGPIO()
|
||||
self.io2.configureGPIO()
|
||||
self.io3.configureGPIO()
|
||||
self.io4.configureGPIO()
|
||||
self.heater.configureGPIO()
|
||||
self.filamentSensor.configureGPIO()
|
||||
|
||||
self._settings.set(["useCelsius"],not self._settings.get(["useFahrenheit"]))
|
||||
temperature_reading = []
|
||||
temperature_control = []
|
||||
rpi_outputs = []
|
||||
rpi_inputs = []
|
||||
|
||||
def startTimer(self):
|
||||
self._checkTempTimer = RepeatedTimer(10, self.checkEnclosureTemp, None, None, True)
|
||||
@@ -115,106 +43,47 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
|
||||
except:
|
||||
return 0
|
||||
|
||||
def checkEnclosureTemp(self):
|
||||
if self._settings.get(["temperatureReadingEnable"]):
|
||||
if self._settings.get(["dhtModel"]) == 1820 or self._settings.get(["dhtModel"]) == '1820':
|
||||
stdout = Popen("sudo "+self._settings.get(["getTempScript"])+" "+str(self._settings.get(["dhtModel"])), shell=True, stdout=PIPE).stdout
|
||||
else:
|
||||
stdout = Popen("sudo "+self._settings.get(["getTempScript"])+" "+str(self._settings.get(["dhtModel"]))+" "+str(self._settings.get(["dhtPin"])), shell=True, stdout=PIPE).stdout
|
||||
sTemp = stdout.read()
|
||||
if self._settings.get(["debug"]) == True:
|
||||
self._logger.info("DEBUG -> Reading temperature stdout: %s",stdout)
|
||||
sTemp.replace(" ", "")
|
||||
fTemp = self.toFloat(sTemp)
|
||||
if sTemp.find("Failed") != -1 or fTemp == 0:
|
||||
self._logger.info("Failed to read Temperature")
|
||||
else:
|
||||
self.enclosureCurrentTemperature = fTemp*1.8 + 32 if self._settings.get(["useFahrenheit"]) else fTemp
|
||||
|
||||
if self._settings.get(["dhtModel"]) != '1820':
|
||||
stdout = Popen("sudo "+self._settings.get(["getHumiScript"])+" "+str(self._settings.get(["dhtModel"]))+" "+str(self._settings.get(["dhtPin"])), shell=True, stdout=PIPE).stdout
|
||||
sHum = stdout.read()
|
||||
if self._settings.get(["debug"]) == True:
|
||||
self._logger.info("DEBUG -> Reading humidity stdout: %s",stdout)
|
||||
sHum.replace(" ", "")
|
||||
fHum = self.toFloat(sHum)
|
||||
if sHum.find("Failed") != -1 or fHum == 0:
|
||||
self._logger.info("Failed to read Humidity")
|
||||
else:
|
||||
self.enclosureCurrentHumidity = fHum
|
||||
self._plugin_manager.send_plugin_message(self._identifier, dict(enclosuretemp=self.enclosureCurrentTemperature,enclosureHumidity=self.enclosureCurrentHumidity))
|
||||
self.heaterHandler()
|
||||
|
||||
def heaterHandler(self):
|
||||
if self._settings.get(["heaterEnable"]):
|
||||
self.currentHeaterStatus = self.enclosureCurrentTemperature<float(self.enclosureSetTemperature)
|
||||
if self._settings.get(["debug"]) == True:
|
||||
self._logger.info("DEBUG -> Current heater status: %s previous heater status %s",self.currentHeaterStatus,self.previousHeaterStatus)
|
||||
if self.currentHeaterStatus != self.previousHeaterStatus:
|
||||
if self.currentHeaterStatus and self.heater.enable:
|
||||
self._logger.info("Turning heater on.")
|
||||
self.heater.write(True)
|
||||
else:
|
||||
self._logger.info("Turning heater off.")
|
||||
self.heater.write(False)
|
||||
self.previousHeaterStatus = self.currentHeaterStatus
|
||||
|
||||
def startFilamentDetection(self):
|
||||
if not GPIO.input(self.filamentSensor.pinNumber):
|
||||
self._logger.info("Started printing with no filament.")
|
||||
self._printer.toggle_pause_print()
|
||||
def toInt(self, value):
|
||||
try:
|
||||
GPIO.remove_event_detect(self.filamentSensor.pinNumber)
|
||||
val = int(value)
|
||||
return val
|
||||
except:
|
||||
pass
|
||||
if self.filamentSensor.pinNumber != -1:
|
||||
self._logger.info("Started filament detection.")
|
||||
if self._settings.get(["filamentSensorActiveLow"]):
|
||||
GPIO.add_event_detect(self.filamentSensor.pinNumber, GPIO.FALLING, callback=self.handleFilamentDetection, bouncetime=300)
|
||||
else:
|
||||
GPIO.add_event_detect(self.filamentSensor.pinNumber, GPIO.RISING, callback=self.handleFilamentDetection, bouncetime=300)
|
||||
|
||||
def handleFilamentDetection(self,channel):
|
||||
if self._printer.is_printing():
|
||||
activeLow = self._settings.get(["filamentSensorActiveLow"])
|
||||
gpioStatus = GPIO.input(self.filamentSensor.pinNumber)
|
||||
|
||||
if self._settings.get(["debug"]) == True:
|
||||
self._logger.info("DEBUG -> Filament detection active low: %s gpio status: %s",activeLow,gpioStatus)
|
||||
if activeLow ^ gpioStatus:
|
||||
if time.time() - lastFilamentEndDetected > self._settings.get(["filamentSensorTimeout"]):
|
||||
self._logger.info("Detected end of filament.")
|
||||
lastFilamentEndDetected = time.time()
|
||||
for line in self._settings.get(["filamentSensorGcode"]).split(';'):
|
||||
if line:
|
||||
self._printer.commands(line.strip().capitalize())
|
||||
self._logger.info("Sending GCODE command: %s",line.strip().capitalize())
|
||||
else:
|
||||
self._logger.info("Prevented end of filament detection, filament sensor timeout not elapsed.")
|
||||
|
||||
def stopFilamentDetection(self):
|
||||
try:
|
||||
GPIO.remove_event_detect(self.filamentSensor.pinNumber)
|
||||
except:
|
||||
pass
|
||||
return 0
|
||||
|
||||
#~~ StartupPlugin mixin
|
||||
def on_after_startup(self):
|
||||
self.temperature_reading = self._settings.get(["temperature_reading"])
|
||||
self.temperature_control = self._settings.get(["temperature_control"])
|
||||
self.rpi_outputs = self._settings.get(["rpi_outputs"])
|
||||
self.rpi_inputs = self._settings.get(["rpi_inputs"])
|
||||
self.startTimer()
|
||||
self.startGPIO()
|
||||
self.clearGPIO()
|
||||
self.configureGPIO()
|
||||
|
||||
#~~ Blueprintplugin mixin
|
||||
@octoprint.plugin.BlueprintPlugin.route("/setEnclosureTemperature", methods=["GET"])
|
||||
def setEnclosureTemperature(self):
|
||||
self.enclosureSetTemperature = flask.request.values["enclosureSetTemp"]
|
||||
if self._settings.get(["debug"]) == True:
|
||||
self._logger.info("DEBUG -> Seting enclosure temperature: %s",self.enclosureSetTemperature)
|
||||
self.heaterHandler()
|
||||
self.handleTemperatureControl()
|
||||
return flask.jsonify(enclosureSetTemperature=self.enclosureSetTemperature,enclosureCurrentTemperature=self.enclosureCurrentTemperature)
|
||||
|
||||
@octoprint.plugin.BlueprintPlugin.route("/getEnclosureSetTemperature", methods=["GET"])
|
||||
def getEnclosureSetTemperature(self):
|
||||
return str(self.enclosureSetTemperature)
|
||||
|
||||
@octoprint.plugin.BlueprintPlugin.route("/clearGPIOMode", methods=["GET"])
|
||||
def clearGPIOMode(self):
|
||||
GPIO.cleanup()
|
||||
return flask.jsonify(success=True)
|
||||
|
||||
@octoprint.plugin.BlueprintPlugin.route("/getUpdateBtnStatus", methods=["GET"])
|
||||
def getUpdateBtnStatus(self):
|
||||
self.updateOutputUI()
|
||||
return flask.make_response("Ok.", 200)
|
||||
|
||||
@octoprint.plugin.BlueprintPlugin.route("/getEnclosureTemperature", methods=["GET"])
|
||||
def getEnclosureTemperature(self):
|
||||
return str(self.enclosureCurrentTemperature)
|
||||
@@ -223,116 +92,344 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin,
|
||||
def setIO(self):
|
||||
io = flask.request.values["io"]
|
||||
value = True if flask.request.values["status"] == "on" else False
|
||||
|
||||
if io == "io1":
|
||||
self.io1.write(value)
|
||||
elif io == "io2":
|
||||
self.io2.write(value)
|
||||
elif io == "io3":
|
||||
self.io3.write(value)
|
||||
elif io == "io4":
|
||||
self.io4.write(value)
|
||||
for rpi_output in self.rpi_outputs:
|
||||
if self.toInt(io) == self.toInt(rpi_output['gpioPin']):
|
||||
val = (not value) if rpi_output['activeLow'] else value
|
||||
self.writeGPIO(self.toInt(io), val)
|
||||
|
||||
return flask.jsonify(success=True)
|
||||
|
||||
#~~ Plugin Internal methods
|
||||
def checkEnclosureTemp(self):
|
||||
try:
|
||||
for temp_reader in self.temperature_reading:
|
||||
if temp_reader['isEnabled']:
|
||||
if temp_reader['sensorType'] in ["11", "22", "2303"]:
|
||||
self._logger.info("sensorType dht")
|
||||
self.enclosureCurrentTemperature,enclosureHumidity=self.enclosureCurrentHumidity = self.readDhtTemp(temp_reader['sensorType'],temp_reader['gpioPin'])
|
||||
elif temp_reader['sensorType'] == "18b20":
|
||||
self.enclosureCurrentTemperature = self.read18b20Temp()
|
||||
else:
|
||||
self._logger.info("sensorType no match")
|
||||
self.enclosureCurrentTemperature = 0
|
||||
|
||||
if temp_reader['useFahrenheit']:
|
||||
self.enclosureCurrentTemperature = self.enclosureCurrentTemperature*1.8 + 32
|
||||
|
||||
if self._settings.get(["debug"]) == True:
|
||||
self._logger.info("Temperature read was: %s", self.enclosureCurrentTemperature)
|
||||
|
||||
self._plugin_manager.send_plugin_message(self._identifier, dict(enclosuretemp=self.enclosureCurrentTemperature,enclosureHumidity=self.enclosureCurrentHumidity))
|
||||
self.handleTemperatureControl()
|
||||
self.handleTemperatureEvents()
|
||||
except Exception as ex:
|
||||
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
|
||||
message = template.format(type(ex).__name__, ex.args)
|
||||
self._logger.warn(message)
|
||||
pass
|
||||
|
||||
def handleTemperatureEvents(self):
|
||||
if self.toFloat(rpi_input['setTemp']) == 0:
|
||||
return
|
||||
for rpi_input in self.rpi_inputs:
|
||||
if rpi_input['eventType']=='temperature' and (self.toFloat(rpi_input['setTemp']) < self.toFloat(self.enclosureCurrentTemperature)):
|
||||
for rpi_output in self.rpi_outputs:
|
||||
if self.toInt(rpi_input['controlledIO']) == self.toInt(rpi_output['gpioPin']):
|
||||
val = GPIO.LOW if rpi_output['activeLow'] else GPIO.HIGH
|
||||
self.writeGPIO(self.toInt(rpi_output['gpioPin']), val)
|
||||
|
||||
def readDhtTemp(self,sensor,pin):
|
||||
try:
|
||||
import Adafruit_DHT
|
||||
return Adafruit_DHT.read_retry(sensor, pin,2,0.5)
|
||||
except:
|
||||
self._checkTempTimer.stop();
|
||||
self._plugin_manager.send_plugin_message(self._identifier, dict(isMsg=True,msg="Failed to import Adafruit_DHT. Please install the library and restart octoprint!."))
|
||||
pass
|
||||
return (0, 0)
|
||||
|
||||
def read18b20Temp(self):
|
||||
os.system('modprobe w1-gpio')
|
||||
os.system('modprobe w1-therm')
|
||||
|
||||
lines = self.readraw18b20Temp()
|
||||
while lines[0].strip()[-3:] != 'YES':
|
||||
time.sleep(0.2)
|
||||
lines = self.readraw18b20Temp()
|
||||
equals_pos = lines[1].find('t=')
|
||||
if equals_pos != -1:
|
||||
temp_string = lines[1][equals_pos+2:]
|
||||
temp_c = float(temp_string) / 1000.0
|
||||
return '{0:0.1f}'.format(temp_c)
|
||||
return 0
|
||||
|
||||
def readraw18b20Temp(self):
|
||||
base_dir = '/sys/bus/w1/devices/'
|
||||
device_folder = glob.glob(base_dir + '28*')[0]
|
||||
device_file = device_folder + '/w1_slave'
|
||||
f = open(device_file, 'r')
|
||||
lines = f.readlines()
|
||||
f.close()
|
||||
return lines
|
||||
|
||||
def handleTemperatureControl(self):
|
||||
if self.enclosureSetTemperature == 0:
|
||||
return
|
||||
for control in self.temperature_control:
|
||||
if control['isEnabled'] == True:
|
||||
if control['controlType'] == 'heater':
|
||||
self.currentTempControlStatus = self.toFloat(self.enclosureCurrentTemperature)<self.toFloat(self.enclosureSetTemperature)
|
||||
else:
|
||||
self.currentTempControlStatus = self.toFloat(self.enclosureCurrentTemperature)>self.toFloat(self.enclosureSetTemperature)
|
||||
if self.currentTempControlStatus != self.previousTempControlStatus:
|
||||
if self.currentTempControlStatus:
|
||||
self._logger.info("Turning gpio to control temperature on.")
|
||||
val = False if control['activeLow'] else True
|
||||
self.writeGPIO(self.toInt(control['gpioPin']),val)
|
||||
else:
|
||||
self._logger.info("Turning gpio to control temperature off.")
|
||||
val = True if control['activeLow'] else False
|
||||
self.writeGPIO(self.toInt(control['gpioPin']), val)
|
||||
self.previousTempControlStatus = self.currentTempControlStatus
|
||||
|
||||
def startGPIO(self):
|
||||
try:
|
||||
currentMode = GPIO.getmode()
|
||||
setMode = GPIO.BOARD if self._settings.get(["useBoardPinNumber"]) else GPIO.BCM
|
||||
if currentMode== None:
|
||||
currentMode = setMode
|
||||
if currentMode != setMode:
|
||||
GPIO.setmode(currentMode)
|
||||
tempstr = "BOARD" if currentMode == GPIO.BOARD else "BCM"
|
||||
self._settings.set(["useBoardPinNumber"],True if currentMode == GPIO.BOARD else False)
|
||||
self._plugin_manager.send_plugin_message(self._identifier,dict(isMsg=True,msg="GPIO mode was configured before, GPIO mode will be forced to use: " + tempstr + " as pin numbers. Please update GPIO accordingly!"))
|
||||
else:
|
||||
GPIO.setmode(setMode)
|
||||
GPIO.setwarnings(False)
|
||||
except Exception as ex:
|
||||
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
|
||||
message = template.format(type(ex).__name__, ex.args)
|
||||
self._logger.warn(message)
|
||||
pass
|
||||
|
||||
def clearGPIO(self):
|
||||
try:
|
||||
for control in self.temperature_control:
|
||||
GPIO.cleanup(self.toInt(control['gpioPin']))
|
||||
for rpi_output in self.rpi_outputs:
|
||||
GPIO.cleanup(self.toInt(rpi_output['gpioPin']))
|
||||
for rpi_input in self.rpi_inputs:
|
||||
try:
|
||||
GPIO.remove_event_detect(self.toInt(rpi_input['gpioPin']))
|
||||
except:
|
||||
pass
|
||||
GPIO.cleanup(self.toInt(rpi_input['gpioPin']))
|
||||
except Exception as ex:
|
||||
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
|
||||
message = template.format(type(ex).__name__, ex.args)
|
||||
self._logger.warn(message)
|
||||
pass
|
||||
|
||||
def configureGPIO(self):
|
||||
try:
|
||||
for control in self.temperature_control:
|
||||
GPIO.setup(self.toInt(control['gpioPin']), GPIO.OUT, initial=GPIO.HIGH if control['activeLow'] else GPIO.LOW)
|
||||
for rpi_output in self.rpi_outputs:
|
||||
GPIO.setup(self.toInt(rpi_output['gpioPin']), GPIO.OUT, initial=GPIO.HIGH if rpi_output['activeLow'] else GPIO.LOW)
|
||||
for rpi_input in self.rpi_inputs:
|
||||
GPIO.setup(self.toInt(rpi_input['gpioPin']), GPIO.IN, pull_up_down=GPIO.PUD_UP if rpi_input['inputPull'] == 'inputPullUp' else GPIO.PUD_DOWN)
|
||||
if rpi_input['eventType'] == 'gpio' and self.toInt(rpi_input['gpioPin']) != 0:
|
||||
edge = GPIO.RISING if rpi_input['edge'] == 'hise' else GPIO.FALLING
|
||||
GPIO.add_event_detect(self.toInt(rpi_input['gpioPin']), edge, callback= self.handleGPIOControl, bouncetime=200)
|
||||
if rpi_input['eventType'] == 'printer' and rpi_input['printerAction'] != 'filament' and self.toInt(rpi_input['gpioPin']) != 0:
|
||||
edge = GPIO.RISING if rpi_input['edge'] == 'hise' else GPIO.FALLING
|
||||
GPIO.add_event_detect(self.toInt(rpi_input['gpioPin']), edge, callback= self.handlePrinterAction, bouncetime=200)
|
||||
except Exception as ex:
|
||||
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
|
||||
message = template.format(type(ex).__name__, ex.args)
|
||||
self._logger.warn(message)
|
||||
pass
|
||||
|
||||
def handleFilammentDetection(self,channel):
|
||||
try:
|
||||
for rpi_input in self.rpi_inputs:
|
||||
if channel == self.toInt(rpi_input['gpioPin']) and rpi_input['eventType'] == 'printer' and rpi_input['printerAction'] == 'filament' \
|
||||
and ((rpi_input['edge']=='fall') ^ GPIO.input(self.toInt(rpi_input['gpioPin']))):
|
||||
if time.time() - self.lastFilamentEndDetected > self._settings.get(["filamentSensorTimeout"]):
|
||||
self._logger.info("Detected end of filament.")
|
||||
self.lastFilamentEndDetected = time.time()
|
||||
for line in self._settings.get(["filamentSensorGcode"]).split(';'):
|
||||
if line:
|
||||
self._printer.commands(line.strip().capitalize())
|
||||
self._logger.info("Sending GCODE command: %s",line.strip().capitalize())
|
||||
else:
|
||||
self._logger.info("Prevented end of filament detection, filament sensor timeout not elapsed.")
|
||||
except Exception as ex:
|
||||
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
|
||||
message = template.format(type(ex).__name__, ex.args)
|
||||
self._logger.warn(message)
|
||||
pass
|
||||
|
||||
def startFilamentDetection(self):
|
||||
self.stopFilamentDetection()
|
||||
try:
|
||||
for rpi_input in self.rpi_inputs:
|
||||
if rpi_input['eventType'] == 'printer' and rpi_input['printerAction'] == 'filament' and self.toInt(rpi_input['gpioPin']) != 0:
|
||||
edge = GPIO.RISING if rpi_input['edge'] == 'hise' else GPIO.FALLING
|
||||
if GPIO.input(self.toInt(rpi_input['gpioPin'])) == (edge == GPIO.RISING):
|
||||
self._printer.pause_print()
|
||||
self._logger.info("Started printing with no filament.")
|
||||
else:
|
||||
GPIO.add_event_detect(self.toInt(rpi_input['gpioPin']), edge, callback= self.handleFilammentDetection, bouncetime=200)
|
||||
except Exception as ex:
|
||||
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
|
||||
message = template.format(type(ex).__name__, ex.args)
|
||||
self._logger.warn(message)
|
||||
pass
|
||||
|
||||
def stopFilamentDetection(self):
|
||||
try:
|
||||
for rpi_input in self.rpi_inputs:
|
||||
if rpi_input['eventType'] == 'printer' and rpi_input['printerAction'] == 'filament':
|
||||
GPIO.remove_event_detect(self.toInt(rpi_input['gpioPin']))
|
||||
except Exception as ex:
|
||||
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
|
||||
message = template.format(type(ex).__name__, ex.args)
|
||||
self._logger.warn(message)
|
||||
pass
|
||||
|
||||
def handleGPIOControl(self,channel):
|
||||
try:
|
||||
for rpi_input in self.rpi_inputs:
|
||||
if channel == self.toInt(rpi_input['gpioPin']) and rpi_input['eventType']=='gpio' and \
|
||||
((rpi_input['edge']=='fall') ^ GPIO.input(self.toInt(rpi_input['gpioPin']))):
|
||||
for rpi_output in self.rpi_outputs:
|
||||
if self.toInt(rpi_input['controlledIO']) == self.toInt(rpi_output['gpioPin']):
|
||||
val = GPIO.LOW if rpi_input['setControlledIO']=='low' else GPIO.HIGH
|
||||
self.writeGPIO(self.toInt(rpi_output['gpioPin']),val)
|
||||
except Exception as ex:
|
||||
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
|
||||
message = template.format(type(ex).__name__, ex.args)
|
||||
self._logger.warn(message)
|
||||
pass
|
||||
|
||||
def handlePrinterAction(self,channel):
|
||||
try:
|
||||
for rpi_input in self.rpi_inputs:
|
||||
if channel == self.toInt(rpi_input['gpioPin']) and rpi_input['eventType']=='printer' and \
|
||||
((rpi_input['edge']=='fall') ^ GPIO.input(self.toInt(rpi_input['gpioPin']))):
|
||||
if rpi_input['printerAction'] == 'resume':
|
||||
self._logger.info("Printer action resume.")
|
||||
self._printer.resume_print()
|
||||
elif rpi_input['printerAction'] == 'pause':
|
||||
self._logger.info("Printer action pause.")
|
||||
self._printer.pause_print()
|
||||
except Exception as ex:
|
||||
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
|
||||
message = template.format(type(ex).__name__, ex.args)
|
||||
self._logger.warn(message)
|
||||
pass
|
||||
|
||||
def writeGPIO(self,gpio,value):
|
||||
try:
|
||||
GPIO.output(gpio, value)
|
||||
if self._settings.get(["debug"]) == True:
|
||||
self._logger.info("Writing on gpio: %s value %s", gpio,value)
|
||||
self.updateOutputUI()
|
||||
except Exception as ex:
|
||||
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
|
||||
message = template.format(type(ex).__name__, ex.args)
|
||||
self._logger.warn(message)
|
||||
pass
|
||||
|
||||
def updateOutputUI(self):
|
||||
result = []
|
||||
i=0
|
||||
for rpi_output in self.rpi_outputs:
|
||||
pin = self.toInt(rpi_output['gpioPin'])
|
||||
val = GPIO.input(pin) if not rpi_output['activeLow'] else (not GPIO.input(pin))
|
||||
result.append({pin:val})
|
||||
self._plugin_manager.send_plugin_message(self._identifier, dict(rpi_output=result))
|
||||
|
||||
#~~ EventPlugin mixin
|
||||
def on_event(self, event, payload):
|
||||
|
||||
if event == Events.CONNECTED:
|
||||
self.updateOutputUI()
|
||||
|
||||
if event == Events.PRINT_RESUMED:
|
||||
if self.filamentSensor.enable:
|
||||
self.startFilamentDetection()
|
||||
self.startFilamentDetection()
|
||||
|
||||
if event == Events.PRINT_STARTED:
|
||||
if self.filamentSensor.enable:
|
||||
self.startFilamentDetection()
|
||||
|
||||
if self.io1.autoStartup and self.io1.enable:
|
||||
scheduler.enter(self.toFloat(self.io1.timeDelay), 1, self.io1.write, (True,))
|
||||
if self.io2.autoStartup and self.io2.enable:
|
||||
scheduler.enter(self.toFloat(self.io2.timeDelay), 1, self.io2.write, (True,))
|
||||
if self.io3.autoStartup and self.io3.enable:
|
||||
scheduler.enter(self.toFloat(self.io3.timeDelay), 1, self.io3.write, (True,))
|
||||
if self.io4.autoStartup and self.io4.enable:
|
||||
scheduler.enter(self.toFloat(self.io4.timeDelay), 1, self.io4.write, (True,))
|
||||
map(scheduler.cancel, scheduler.queue)
|
||||
self.startFilamentDetection()
|
||||
for rpi_output in self.rpi_outputs:
|
||||
if rpi_output['autoStartup']:
|
||||
value = False if rpi_output['activeLow'] else True
|
||||
scheduler.enter(self.toFloat(rpi_output['startupTimeDelay']), 1, self.writeGPIO, (self.toInt(rpi_output['gpioPin']),value,))
|
||||
scheduler.run()
|
||||
for control in self.temperature_control:
|
||||
if control['autoStartup'] == True:
|
||||
self.enclosureSetTemperature = self.toInt(control['defaultTemp'])
|
||||
self._plugin_manager.send_plugin_message(self._identifier, dict(enclosureSetTemp=self.enclosureSetTemperature))
|
||||
|
||||
elif event in (Events.PRINT_DONE, Events.PRINT_FAILED, Events.PRINT_CANCELLED):
|
||||
if self.filamentSensor.enable:
|
||||
self.stopFilamentDetection()
|
||||
|
||||
if self.heater.enable:
|
||||
self.enclosureSetTemperature = 0
|
||||
|
||||
if self.io1.autoShutDown and self.io1.enable:
|
||||
scheduler.enter(self.toFloat(self.io1.timeOffDelay), 1, self.io1.write, (False,))
|
||||
if self.io2.autoShutDown and self.io2.enable:
|
||||
scheduler.enter(self.toFloat(self.io2.timeOffDelay), 1, self.io2.write, (False,))
|
||||
if self.io3.autoShutDown and self.io3.enable:
|
||||
scheduler.enter(self.toFloat(self.io3.timeOffDelay), 1, self.io3.write, (False,))
|
||||
if self.io4.autoShutDown and self.io4.enable:
|
||||
scheduler.enter(self.toFloat(self.io4.timeOffDelay), 1, self.io4.write, (False,))
|
||||
self.stopFilamentDetection()
|
||||
self.enclosureSetTemperature = 0
|
||||
self._plugin_manager.send_plugin_message(self._identifier, dict(enclosureSetTemp=self.enclosureSetTemperature))
|
||||
for rpi_output in self.rpi_outputs:
|
||||
if rpi_output['autoShutdown']:
|
||||
value = True if rpi_output['activeLow'] else False
|
||||
scheduler.enter(self.toFloat(rpi_output['shutdownTimeDelay']), 1, self.writeGPIO, (self.toInt(rpi_output['gpioPin']),value,))
|
||||
scheduler.run()
|
||||
|
||||
#~~ SettingsPlugin mixin
|
||||
def on_settings_save(self, data):
|
||||
self.clearGPIO()
|
||||
octoprint.plugin.SettingsPlugin.on_settings_save(self, data)
|
||||
self.temperature_reading = self._settings.get(["temperature_reading"])
|
||||
self.temperature_control = self._settings.get(["temperature_control"])
|
||||
self.rpi_outputs = self._settings.get(["rpi_outputs"])
|
||||
self.rpi_inputs = self._settings.get(["rpi_inputs"])
|
||||
if self._settings.get(["debug"]) == True:
|
||||
self._logger.info("temperature_reading: %s", self.temperature_reading)
|
||||
self._logger.info("temperature_control: %s", self.temperature_control)
|
||||
self._logger.info("rpi_outputs: %s", self.rpi_outputs)
|
||||
self._logger.info("rpi_inputs: %s", self.rpi_inputs)
|
||||
self.startGPIO()
|
||||
self.configureGPIO()
|
||||
|
||||
|
||||
def get_settings_defaults(self):
|
||||
return dict(
|
||||
debug=False,
|
||||
temperatureReadingEnable=False,
|
||||
heaterEnable=False,
|
||||
heaterPin=17,
|
||||
heaterActiveLow=True,
|
||||
dhtPin=4,
|
||||
useFahrenheit=False,
|
||||
useCelsius=True,
|
||||
temperature_reading = [{ 'isEnabled': False, 'gpioPin': 4, 'useFahrenheit':False, 'sensorType':''}],
|
||||
temperature_control = [{ 'isEnabled': False, 'controlType':'heater', 'gpioPin': 17, 'activeLow': True, 'autoStartup': False,'defaultTemp':0}],
|
||||
rpi_outputs = [],
|
||||
rpi_inputs = [],
|
||||
filamentSensorGcode = "G91 ;Set Relative Mode \n" +
|
||||
"G1 E-5.000000 F500 ;Retract 5mm\n" +
|
||||
"G1 Z15 F300 ;move Z up 15mm\n" +
|
||||
"G90 ;Set Absolute Mode\n " +
|
||||
"G1 X20 Y20 F9000 ;Move to hold position\n" +
|
||||
"G91 ;Set Relative Mode\n" +
|
||||
"G1 E-40 F500 ;Retract 40mm\n" +
|
||||
"M0 ;Idle Hold\n" +
|
||||
"G90 ;Set Absolute Mode\n" +
|
||||
"G1 F5000 ;Set speed limits\n" +
|
||||
"G28 X0 Y0 ;Home X Y\n" +
|
||||
"M82 ;Set extruder to Absolute Mode\n" +
|
||||
"G92 E0 ;Set Extruder to 0",
|
||||
debug=True,
|
||||
useBoardPinNumber=False,
|
||||
filamentSensorPin=24,
|
||||
filamentSensorEnable=True,
|
||||
filamentSensorActiveLow=True,
|
||||
filamentSensorGcode="M600;",
|
||||
filamentSensorTimeout=120,
|
||||
dhtModel=2302,
|
||||
io1Pin=18,
|
||||
io2Pin=23,
|
||||
io3Pin=22,
|
||||
io4Pin=27,
|
||||
io1Label="Light",
|
||||
io2Label="Fan",
|
||||
io3Label="IO3",
|
||||
io4Label="IO4",
|
||||
io1ActiveLow=True,
|
||||
io2ActiveLow=True,
|
||||
io3ActiveLow=True,
|
||||
io4ActiveLow=True,
|
||||
io1Enable=False,
|
||||
io2Enable=False,
|
||||
io3Enable=False,
|
||||
io4Enable=False,
|
||||
io1AutoShutDown=True,
|
||||
io2AutoShutDown=True,
|
||||
io3AutoShutDown=True,
|
||||
io4AutoShutDown=True,
|
||||
io1AutoStartup=False,
|
||||
io2AutoStartup=False,
|
||||
io3AutoStartup=False,
|
||||
io4AutoStartup=False,
|
||||
io1TimeDelay=0,
|
||||
io2TimeDelay=0,
|
||||
io3TimeDelay=0,
|
||||
io4TimeDelay=0,
|
||||
io1OffTimeDelay=0,
|
||||
io2OffTimeDelay=0,
|
||||
io3OffTimeDelay=0,
|
||||
io4OffTimeDelay=0,
|
||||
getTempScript="~/.octoprint/plugins/OctoPrint-Enclosure/extras/GetTemperature.py",
|
||||
getHumiScript="~/.octoprint/plugins/OctoPrint-Enclosure/extras/GetHumidity.py"
|
||||
filamentSensorTimeout=120
|
||||
)
|
||||
|
||||
#~~ TemplatePlugin
|
||||
def get_template_configs(self):
|
||||
return [dict(type="settings", custom_bindings=False)]
|
||||
return [
|
||||
dict(type="settings", custom_bindings=True),
|
||||
dict(type="tab", custom_bindings=True)
|
||||
]
|
||||
|
||||
##~~ AssetPlugin mixin
|
||||
def get_assets(self):
|
||||
|
||||
Reference in New Issue
Block a user