heater: Add PrinterHeaters class that stores all sensors and heaters

Add a PrinterHeaters class that can stores references to available
temperature sensors and stores references to instantiated heaters.

Add a extras/heater_bed.py file and delay instantiation of the
heater_bed object.  This allows the heater.py module to be imported
earlier during the setup phase, and allows the PrinterHeaters class to
be available for registering sensors and heaters.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2018-04-03 17:01:10 -04:00
parent 4eeb43b191
commit aed958eb5c
7 changed files with 67 additions and 31 deletions

View File

@ -0,0 +1,8 @@
# Support for a heated bed
#
# Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
def load_config(config):
return config.get_printer().lookup_object('heater').setup_heater(config)

View File

@ -3,7 +3,7 @@
# Copyright (C) 2016-2018 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import fan, extruder
import fan
PIN_MIN_TIME = 0.100
@ -20,8 +20,8 @@ class PrinterHeaterFan:
self.fan.mcu_fan.setup_start_value(0., max_power)
def printer_state(self, state):
if state == 'ready':
self.heater = extruder.get_printer_heater(
self.printer, self.heater_name)
pheater = self.printer.lookup_object('heater')
self.heater = pheater.lookup_heater(self.heater_name)
reactor = self.printer.get_reactor()
reactor.register_timer(self.callback, reactor.NOW)
def callback(self, eventtime):

View File

@ -4,7 +4,7 @@
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import math, logging
import extruder, heater
import heater
class PIDCalibrate:
def __init__(self, config):
@ -18,8 +18,9 @@ class PIDCalibrate:
heater_name = self.gcode.get_str('HEATER', params)
target = self.gcode.get_float('TARGET', params)
write_file = self.gcode.get_int('WRITE_FILE', params, 0)
pheater = self.printer.lookup_object('heater')
try:
heater = extruder.get_printer_heater(self.printer, heater_name)
heater = pheater.lookup_heater(heater_name)
except self.printer.config_error as e:
raise self.gcode.error(str(e))
print_time = self.printer.lookup_object('toolhead').get_last_move_time()

View File

@ -4,7 +4,6 @@
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import logging
import extruder
HINT_THERMAL = """
See the 'verify_heater' section in config/example-extras.cfg
@ -29,8 +28,8 @@ class HeaterCheck:
self.fault_systime = self.printer.get_reactor().NEVER
def printer_state(self, state):
if state == 'connect':
self.heater = extruder.get_printer_heater(
self.printer, self.heater_name)
pheater = self.printer.lookup_object('heater')
self.heater = pheater.lookup_heater(self.heater_name)
logging.info("Starting heater checks for %s", self.heater_name)
reactor = self.printer.get_reactor()
reactor.register_timer(self.check_event, reactor.NOW)

View File

@ -4,7 +4,7 @@
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import math, logging
import stepper, heater, homing
import stepper, homing
EXTRUDE_DIFF_IGNORE = 1.02
@ -13,10 +13,11 @@ class PrinterExtruder:
self.printer = printer
self.name = config.get_name()
shared_heater = config.get('shared_heater', None)
pheater = printer.lookup_object('heater')
if shared_heater is None:
self.heater = heater.PrinterHeater(printer, config)
self.heater = pheater.setup_heater(config)
else:
self.heater = get_printer_heater(printer, shared_heater)
self.heater = pheater.lookup_heater(shared_heater)
self.stepper = stepper.PrinterStepper(printer, config)
self.nozzle_diameter = config.getfloat('nozzle_diameter', above=0.)
filament_diameter = config.getfloat(
@ -274,12 +275,3 @@ def get_printer_extruders(printer):
break
out.append(extruder)
return out
def get_printer_heater(printer, name):
if name == 'heater_bed':
return printer.lookup_object(name)
if name == 'extruder':
name = 'extruder0'
if name.startswith('extruder'):
return printer.lookup_object(name).get_heater()
raise printer.config_error("Unknown heater '%s'" % (name,))

View File

@ -104,13 +104,14 @@ PWM_DELAY = REPORT_TIME + SAMPLE_TIME*SAMPLE_COUNT
class error(Exception):
pass
class PrinterHeater:
class Heater:
error = error
def __init__(self, printer, config):
self.printer = printer
def __init__(self, config):
printer = config.get_printer()
self.name = config.get_name()
sensor_params = config.getchoice('sensor_type', Sensors)
self.sensor = sensor_params['class'](config, sensor_params)
sensor_type = config.get('sensor_type')
pheater = printer.lookup_object('heater')
self.sensor = pheater.setup_sensor(sensor_type, config)
self.min_temp = config.getfloat('min_temp', minval=KELVIN_TO_CELCIUS)
self.max_temp = config.getfloat('max_temp', above=self.min_temp)
self.min_extrude_temp = config.getfloat(
@ -278,7 +279,42 @@ class ControlPID:
return (abs(temp_diff) > PID_SETTLE_DELTA
or abs(self.prev_temp_deriv) > PID_SETTLE_SLOPE)
######################################################################
# Sensor and heater lookup
######################################################################
class PrinterHeaters:
def __init__(self, printer, config):
self.printer = printer
self.sensors = {}
self.heaters = {}
def add_sensor(self, sensor_type, params):
self.sensors[sensor_type] = params
def setup_sensor(self, sensor_type, config):
if sensor_type not in self.sensors:
raise self.printer.config_error("Unknown temperature sensor '%s'" % (
sensor_type,))
params = self.sensors[sensor_type]
return params['class'](config, params)
def setup_heater(self, config):
heater_name = config.get_name()
if heater_name == 'extruder':
heater_name = 'extruder0'
if heater_name in self.heaters:
raise config.error("Heater %s already registered" % (heater_name,))
self.heaters[heater_name] = heater = Heater(config)
return heater
def lookup_heater(self, heater_name):
if heater_name == 'extruder':
heater_name = 'extruder0'
if heater_name not in self.heaters:
raise self.printer.config_error(
"Unknown heater '%s'" % (heater_name,))
return self.heaters[heater_name]
def add_printer_objects(printer, config):
if config.has_section('heater_bed'):
printer.add_object('heater_bed', PrinterHeater(
printer, config.getsection('heater_bed')))
ph = PrinterHeaters(printer, config)
printer.add_object('heater', ph)
for sensor_type, params in Sensors.items():
ph.add_sensor(sensor_type, params)

View File

@ -7,7 +7,7 @@
import sys, os, optparse, logging, time, threading
import collections, ConfigParser, importlib
import util, reactor, queuelogger, msgproto
import gcode, pins, mcu, toolhead, extruder, heater
import gcode, pins, heater, mcu, toolhead, extruder
message_ready = "Printer is ready"
@ -204,11 +204,11 @@ class Printer:
ConfigLogger(fileconfig, self.bglogger)
# Create printer components
config = ConfigWrapper(self, fileconfig, 'printer')
for m in [pins, mcu]:
for m in [pins, heater, mcu]:
m.add_printer_objects(self, config)
for section in fileconfig.sections():
self.try_load_module(config, section)
for m in [toolhead, extruder, heater]:
for m in [toolhead, extruder]:
m.add_printer_objects(self, config)
# Validate that there are no undefined parameters in the config file
valid_sections = { s: 1 for s, o in self.all_config_options }