From eff2f5f51b2591ed1fd6ce6d24e00b1d7706f5eb Mon Sep 17 00:00:00 2001 From: Rogerio Goncalves Date: Wed, 15 May 2024 18:31:48 +0100 Subject: [PATCH] sensors: rework temp_ignore_limits (#223) --- docs/Config_Changes.md | 4 +++ docs/Config_Reference.md | 50 ++++++++++++++++----------- klippy/extras/adc_temperature.py | 2 +- klippy/extras/aht10.py | 8 ++++- klippy/extras/bme280.py | 6 +++- klippy/extras/danger_options.py | 16 ++++++--- klippy/extras/ds18b20.py | 14 +++++--- klippy/extras/htu21d.py | 6 +++- klippy/extras/lm75.py | 6 +++- klippy/extras/sht3x.py | 6 +++- klippy/extras/spi_temperature.py | 9 ++++- klippy/extras/temperature_combined.py | 6 +++- klippy/extras/temperature_host.py | 21 ++++------- klippy/extras/temperature_mcu.py | 14 ++++++-- klippy/serialhdl.py | 2 +- src/linux/sensor_ds18b20.c | 14 +++++--- src/thermocouple.c | 16 +++++---- test/klippy/danger_options.cfg | 2 +- 18 files changed, 135 insertions(+), 67 deletions(-) diff --git a/docs/Config_Changes.md b/docs/Config_Changes.md index cdbfe1d8a..a98563aee 100644 --- a/docs/Config_Changes.md +++ b/docs/Config_Changes.md @@ -8,6 +8,10 @@ All dates in this document are approximate. ## Changes +20240430: The `adc_ignore_limits` parameter in the `[danger_options]` +config section has been renamed to `temp_ignore_limits` and it now +covers all possible temperature sensors. + 20240415: The `on_error_gcode` parameter in the `[virtual_sdcard]` config section now has a default. If this parameter is not specified it now defaults to `TURN_OFF_HEATERS`. If the previous behavior is diff --git a/docs/Config_Reference.md b/docs/Config_Reference.md index e6fad4789..0be95347f 100644 --- a/docs/Config_Reference.md +++ b/docs/Config_Reference.md @@ -84,22 +84,6 @@ A collection of DangerKlipper-specific system options # If an unused config option or section should cause an error # if False, will warn but allow klipper to still run. # The default is True. -#log_statistics: True -# If statistics should be logged -# (helpful for keeping the log clean during development) -# The default is True. -#log_config_file_at_startup: True -# If the config file should be logged at startup -# The default is True. -#log_bed_mesh_at_startup: True -# If the bed mesh should be logged on startup -# (helpful for keeping the log clean during development) -# The default is True. -#log_shutdown_info: True -# If we should log detailed crash info when an exception occurs -# Most of it is overly-verbose and fluff and we still get a stack trace -# for normal exceptions, so setting to False can help save time while developing -# The default is True. #allow_plugin_override: False # Allows modules in `plugins` to override modules of the same name in `extras` # The default is False. @@ -110,11 +94,11 @@ A collection of DangerKlipper-specific system options # Tolerance (in mm) for distance moved in the second homing. Ensures the # second homing distance closely matches the `min_home_dist` when using # sensorless homing. The default is 0.5mm. -#adc_ignore_limits: False +#temp_ignore_limits: False # When set to true, this parameter ignores the min_value and max_value -# limits for ADC temperature sensors. It prevents shutdowns due to -# 'ADC out of range' errors by allowing readings outside the specified -# range without triggering a shutdown. Default is False. +# limits for temperature sensors. It prevents shutdowns due to +# 'ADC out of range' and similar errors by allowing readings outside the +# specified range without triggering a shutdown. The default is False. #autosave_includes: False # When set to true, SAVE_CONFIG will recursively read [include ...] blocks # for conflicts to autosave data. Any configurations updated will be backed @@ -123,6 +107,30 @@ A collection of DangerKlipper-specific system options # This allows to set extra flush time (in seconds). Under certain conditions, # a low value will result in an error if message is not get flushed, a high value # (0.250) will result in homing/probing latency. The default is 0.250 + +# Logging options + +#minimal_logging: False +# Set all log parameters log options to False. The default is False. +#log_statistics: True +# If statistics should be logged +# (helpful for keeping the log clean during development) +# The default is True. +#log_config_file_at_startup: True +# If the config file should be logged at startup +# The default is True. +#log_bed_mesh_at_startup: True +# If the bed mesh should be logged at startup +# (helpful for keeping the log clean during development) +# The default is True. +#log_shutdown_info: True +# If we should log detailed crash info when an exception occurs +# Most of it is overly-verbose and fluff and we still get a stack trace +# for normal exceptions, so setting to False can help save time while developing +# The default is True. +#log_serial_reader_warnings: True +#log_startup_info: True +#log_webhook_method_register_messages: False ``` ## Common kinematic settings @@ -2237,7 +2245,7 @@ detach_position: 0,0,0 # the Z axis is not already homed the head is lifted by `z_hop`. # The default is to not implement Z hop. #restore_toolhead: True -# While True, the position of the toolhead is restored to the position prior +# While True, the position of the toolhead is restored to the position prior # to the attach/detach movements. # The default value is True. #dock_retries: diff --git a/klippy/extras/adc_temperature.py b/klippy/extras/adc_temperature.py index ef50415e8..2637c9d85 100644 --- a/klippy/extras/adc_temperature.py +++ b/klippy/extras/adc_temperature.py @@ -38,7 +38,7 @@ def adc_callback(self, read_time, read_value): self.temperature_callback(read_time + SAMPLE_COUNT * SAMPLE_TIME, temp) def setup_minmax(self, min_temp, max_temp): - if get_danger_options().adc_ignore_limits: + if get_danger_options().temp_ignore_limits: danger_check_count = 0 else: danger_check_count = RANGE_CHECK_COUNT diff --git a/klippy/extras/aht10.py b/klippy/extras/aht10.py index b4eecee4e..16d17a343 100644 --- a/klippy/extras/aht10.py +++ b/klippy/extras/aht10.py @@ -6,6 +6,8 @@ import logging from . import bus +from extras.danger_options import get_danger_options + ###################################################################### # Compatible Sensors: # AHT10 - Tested w/ BTT GTR 1.0 MCU on i2c3 @@ -150,7 +152,11 @@ def _sample_aht10(self, eventtime): self.temp = self.humidity = 0.0 return self.reactor.NEVER - if self.temp < self.min_temp or self.temp > self.max_temp: + if ( + self.temp < self.min_temp + or self.temp > self.max_temp + and not get_danger_options().temp_ignore_limits + ): self.printer.invoke_shutdown( "AHT10 temperature %0.1f outside range of %0.1f:%.01f" % (self.temp, self.min_temp, self.max_temp) diff --git a/klippy/extras/bme280.py b/klippy/extras/bme280.py index dbd071ee4..bfc88996d 100644 --- a/klippy/extras/bme280.py +++ b/klippy/extras/bme280.py @@ -6,6 +6,8 @@ import logging from . import bus +from extras.danger_options import get_danger_options + REPORT_TIME = 0.8 BME280_CHIP_ADDR = 0x76 @@ -431,7 +433,9 @@ def _sample_bme280(self, eventtime): if self.chip_type == "BME280": humid_raw = (data[6] << 8) | data[7] self.humidity = self._compensate_humidity_bme280(humid_raw) - if self.temp < self.min_temp or self.temp > self.max_temp: + if ( + self.temp < self.min_temp or self.temp > self.max_temp + ) and not get_danger_options().temp_ignore_limits: self.printer.invoke_shutdown( "BME280 temperature %0.1f outside range of %0.1f:%.01f" % (self.temp, self.min_temp, self.max_temp) diff --git a/klippy/extras/danger_options.py b/klippy/extras/danger_options.py index 8d6983b56..c5fcb65c4 100644 --- a/klippy/extras/danger_options.py +++ b/klippy/extras/danger_options.py @@ -19,20 +19,28 @@ def __init__(self, config): self.error_on_unused_config_options = config.getboolean( "error_on_unused_config_options", True ) - self.allow_plugin_override = config.getboolean( "allow_plugin_override", False ) - self.multi_mcu_trsync_timeout = config.getfloat( "multi_mcu_trsync_timeout", 0.025, minval=0.0 ) self.homing_elapsed_distance_tolerance = config.getfloat( "homing_elapsed_distance_tolerance", 0.5, minval=0.0 ) - self.adc_ignore_limits = config.getboolean("adc_ignore_limits", False) - self.autosave_includes = config.getboolean("autosave_includes", False) + temp_ignore_limits = False + if config.getboolean("temp_ignore_limits", None) is None: + adc_ignore_limits = config.getboolean("adc_ignore_limits", None) + if adc_ignore_limits is not None: + config.deprecate("adc_ignore_limits") + temp_ignore_limits = adc_ignore_limits + + self.temp_ignore_limits = config.getboolean( + "temp_ignore_limits", temp_ignore_limits + ) + + self.autosave_includes = config.getboolean("autosave_includes", False) self.bgflush_extra_time = config.getfloat( "bgflush_extra_time", 0.250, minval=0.0 ) diff --git a/klippy/extras/ds18b20.py b/klippy/extras/ds18b20.py index 1e584349b..64b002e2d 100644 --- a/klippy/extras/ds18b20.py +++ b/klippy/extras/ds18b20.py @@ -3,8 +3,9 @@ # Copyright (C) 2020 Alan Lord # # This file may be distributed under the terms of the GNU GPLv3 license. -import logging -import mcu +import logging, mcu + +from extras.danger_options import get_danger_options DS18_REPORT_TIME = 3.0 # Temperature can be sampled at any time but conversion time is ~750ms, so @@ -33,8 +34,13 @@ def __init__(self, config): def _build_config(self): sid = "".join(["%02x" % (x,) for x in self.sensor_id]) self._mcu.add_config_cmd( - "config_ds18b20 oid=%d serial=%s max_error_count=%d" - % (self.oid, sid, DS18_MAX_CONSECUTIVE_ERRORS) + "config_ds18b20 oid=%d serial=%s max_error_count=%d ignore_limits=%d" + % ( + self.oid, + sid, + DS18_MAX_CONSECUTIVE_ERRORS, + int(get_danger_options().temp_ignore_limits), + ) ) clock = self._mcu.get_query_slot(self.oid) diff --git a/klippy/extras/htu21d.py b/klippy/extras/htu21d.py index c1d6ca3d4..33252ce80 100644 --- a/klippy/extras/htu21d.py +++ b/klippy/extras/htu21d.py @@ -6,6 +6,8 @@ import logging from . import bus +from extras.danger_options import get_danger_options + ###################################################################### # NOTE: The implementation requires write support of length 0 # before reading on the i2c bus of the mcu. @@ -242,7 +244,9 @@ def _sample_htu21d(self, eventtime): self.temp = self.humidity = 0.0 return self.reactor.NEVER - if self.temp < self.min_temp or self.temp > self.max_temp: + if ( + self.temp < self.min_temp or self.temp > self.max_temp + ) and not get_danger_options().temp_ignore_limits: self.printer.invoke_shutdown( "HTU21D temperature %0.1f outside range of %0.1f:%.01f" % (self.temp, self.min_temp, self.max_temp) diff --git a/klippy/extras/lm75.py b/klippy/extras/lm75.py index 9aa5da083..de0eab70f 100644 --- a/klippy/extras/lm75.py +++ b/klippy/extras/lm75.py @@ -6,6 +6,8 @@ import logging from . import bus +from extras.danger_options import get_danger_options + LM75_CHIP_ADDR = 0x48 LM75_I2C_SPEED = 100000 LM75_REGS = { @@ -78,7 +80,9 @@ def _sample_lm75(self, eventtime): self.temp = 0.0 return self.reactor.NEVER - if self.temp < self.min_temp or self.temp > self.max_temp: + if ( + self.temp < self.min_temp or self.temp > self.max_temp + ) and not get_danger_options().temp_ignore_limits: self.printer.invoke_shutdown( "LM75 temperature %0.1f outside range of %0.1f:%.01f" % (self.temp, self.min_temp, self.max_temp) diff --git a/klippy/extras/sht3x.py b/klippy/extras/sht3x.py index 52fc7c845..6bbc9301c 100644 --- a/klippy/extras/sht3x.py +++ b/klippy/extras/sht3x.py @@ -7,6 +7,8 @@ import logging from . import bus +from extras.danger_options import get_danger_options + ###################################################################### # Compatible Sensors: # SHT31 - Tested on octopus pro and Linux MCU @@ -123,7 +125,9 @@ def _sample_sht3x(self, eventtime): self.temp = self.humidity = 0.0 return self.reactor.NEVER - if self.temp < self.min_temp or self.temp > self.max_temp: + if ( + self.temp < self.min_temp or self.temp > self.max_temp + ) and not get_danger_options().temp_ignore_limits: self.printer.invoke_shutdown( "sht3x: temperature %0.1f outside range of %0.1f:%.01f" % (self.temp, self.min_temp, self.max_temp) diff --git a/klippy/extras/spi_temperature.py b/klippy/extras/spi_temperature.py index ff981d9da..b63c160ff 100644 --- a/klippy/extras/spi_temperature.py +++ b/klippy/extras/spi_temperature.py @@ -7,6 +7,7 @@ import math, logging from . import bus +from extras.danger_options import get_danger_options ###################################################################### # SensorBase @@ -54,6 +55,12 @@ def _build_config(self): ) clock = self.mcu.get_query_slot(self.oid) self._report_clock = self.mcu.seconds_to_clock(REPORT_TIME) + + if get_danger_options().temp_ignore_limits: + danger_check_count = 0 + else: + danger_check_count = MAX_INVALID_COUNT + self.mcu.add_config_cmd( "query_thermocouple oid=%u clock=%u rest_ticks=%u" " min_value=%u max_value=%u max_invalid_count=%u" @@ -63,7 +70,7 @@ def _build_config(self): self._report_clock, self.min_sample_value, self.max_sample_value, - MAX_INVALID_COUNT, + danger_check_count, ), is_init=True, ) diff --git a/klippy/extras/temperature_combined.py b/klippy/extras/temperature_combined.py index 2ff347d04..3d9549751 100644 --- a/klippy/extras/temperature_combined.py +++ b/klippy/extras/temperature_combined.py @@ -5,6 +5,8 @@ # # This file may be distributed under the terms of the GNU GPLv3 license. +from extras.danger_options import get_danger_options + REPORT_TIME = 0.300 @@ -75,7 +77,9 @@ def update_temp(self, eventtime): values.append(sensor_temperature) # check if values are out of max_deviation range - if (max(values) - min(values)) > self.max_deviation: + if ( + max(values) - min(values) + ) > self.max_deviation and not get_danger_options().temp_ignore_limits: self.printer.invoke_shutdown( "COMBINED SENSOR maximum deviation exceeded limit of %0.1f, " "max sensor value %0.1f, min sensor value %0.1f." diff --git a/klippy/extras/temperature_host.py b/klippy/extras/temperature_host.py index e704755b9..93c3359eb 100644 --- a/klippy/extras/temperature_host.py +++ b/klippy/extras/temperature_host.py @@ -6,6 +6,8 @@ import logging +from extras.danger_options import get_danger_options + HOST_REPORT_TIME = 1.0 RPI_PROC_TEMP_FILE = "/sys/class/thermal/thermal_zone0/temp" @@ -58,21 +60,12 @@ def _sample_pi_temperature(self, eventtime): self.temp = 0.0 return self.reactor.NEVER - if self.temp < self.min_temp: - self.printer.invoke_shutdown( - "HOST temperature %0.1f below minimum temperature of %0.1f." - % ( - self.temp, - self.min_temp, - ) - ) - if self.temp > self.max_temp: + if ( + self.temp < self.min_temp or self.temp > self.max_temp + ) and not get_danger_options().temp_ignore_limits: self.printer.invoke_shutdown( - "HOST temperature %0.1f above maximum temperature of %0.1f." - % ( - self.temp, - self.max_temp, - ) + "HOST temperature %0.1f outside range of %0.1f:%.01f" + % (self.temp, self.min_temp, self.max_temp) ) mcu = self.printer.lookup_object("mcu") diff --git a/klippy/extras/temperature_mcu.py b/klippy/extras/temperature_mcu.py index 349c248e4..c1c893b26 100644 --- a/klippy/extras/temperature_mcu.py +++ b/klippy/extras/temperature_mcu.py @@ -5,6 +5,8 @@ # This file may be distributed under the terms of the GNU GPLv3 license. import logging +from extras.danger_options import get_danger_options + SAMPLE_TIME = 0.001 SAMPLE_COUNT = 8 REPORT_TIME = 0.300 @@ -39,10 +41,18 @@ def __init__(self, config): self.mcu_adc.setup_adc_callback(REPORT_TIME, self.adc_callback) query_adc = config.get_printer().load_object(config, "query_adc") query_adc.register_adc(config.get_name(), self.mcu_adc) + + if get_danger_options().temp_ignore_limits: + self._danger_check_count = 0 + else: + self._danger_check_count = RANGE_CHECK_COUNT + # Register callbacks if self.printer.get_start_args().get("debugoutput") is not None: self.mcu_adc.setup_minmax( - SAMPLE_TIME, SAMPLE_COUNT, range_check_count=RANGE_CHECK_COUNT + SAMPLE_TIME, + SAMPLE_COUNT, + range_check_count=self._danger_check_count, ) return self.printer.register_event_handler( @@ -120,7 +130,7 @@ def _mcu_identify(self): SAMPLE_COUNT, minval=min(adc_range), maxval=max(adc_range), - range_check_count=RANGE_CHECK_COUNT, + range_check_count=self._danger_check_count, ) def config_unknown(self): diff --git a/klippy/serialhdl.py b/klippy/serialhdl.py index 775e4cbd9..fa051cd94 100644 --- a/klippy/serialhdl.py +++ b/klippy/serialhdl.py @@ -371,7 +371,7 @@ def handle_output(self, params): def handle_default(self, params): if get_danger_options().log_serial_reader_warnings: - logging.warning("%sgot %s", self.warn_prefix, params) + logging.warning("%s got %s", self.warn_prefix, params) # Class to send a query command and return the received response diff --git a/src/linux/sensor_ds18b20.c b/src/linux/sensor_ds18b20.c index 2e9151ae1..f58a1f3a1 100644 --- a/src/linux/sensor_ds18b20.c +++ b/src/linux/sensor_ds18b20.c @@ -52,6 +52,7 @@ struct ds18_s { uint8_t status; uint8_t error_count; uint8_t max_error_count; + uint8_t ignore_limits; }; // Lock ds18_s mutex, set error status, unlock mutex. @@ -157,6 +158,7 @@ command_config_ds18b20(uint32_t *args) struct ds18_s *d = oid_alloc(args[0], command_config_ds18b20, sizeof(*d)); d->max_error_count = args[3]; d->error_count = 0; + d->ignore_limits = args[4]; d->timer.func = ds18_event; d->fd = fd; d->status = W1_IDLE; @@ -188,7 +190,7 @@ command_config_ds18b20(uint32_t *args) shutdown("Could not start DS18B20 reader thread"); } DECL_COMMAND(command_config_ds18b20, - "config_ds18b20 oid=%c serial=%*s max_error_count=%c"); + "config_ds18b20 oid=%c serial=%*s max_error_count=%c ignore_limits=%c"); void command_query_ds18b20(uint32_t *args) @@ -240,10 +242,12 @@ ds18_send_and_request(struct ds18_s *d, uint32_t next_begin_time, uint8_t oid) // Report the previous temperature and request a new one. sendf("ds18b20_result oid=%c next_clock=%u value=%i fault=%u" , oid, next_begin_time, d->temperature, 0); - if (d->temperature < d->min_value || d->temperature > d->max_value) { - pthread_mutex_unlock(&d->lock); - try_shutdown("DS18B20 out of range"); - return; + if (d->ignore_limits == 0) { + if (d->temperature < d->min_value || d->temperature > d->max_value) { + pthread_mutex_unlock(&d->lock); + try_shutdown("DS18B20 out of range"); + return; + } } d->request_time = request_time; d->status = W1_READ_REQUESTED; diff --git a/src/thermocouple.c b/src/thermocouple.c index 0a06d2a4c..09400e655 100644 --- a/src/thermocouple.c +++ b/src/thermocouple.c @@ -90,14 +90,16 @@ thermocouple_respond(struct thermocouple_spi *spi, uint32_t next_begin_time { sendf("thermocouple_result oid=%c next_clock=%u value=%u fault=%c", oid, next_begin_time, value, fault); - /* check the result and stop if below or above allowed range */ - if (fault || value < spi->min_value || value > spi->max_value) { - spi->invalid_count++; - if (spi->invalid_count < spi->max_invalid) - return; - try_shutdown("Thermocouple reader fault"); + if (spi->max_invalid > 0) { + /* check the result and stop if below or above allowed range */ + if (fault || value < spi->min_value || value > spi->max_value) { + spi->invalid_count++; + if (spi->invalid_count < spi->max_invalid) + return; + try_shutdown("Thermocouple reader fault"); + } + spi->invalid_count = 0; } - spi->invalid_count = 0; } static void diff --git a/test/klippy/danger_options.cfg b/test/klippy/danger_options.cfg index fdc6b5cc2..26b0982e2 100644 --- a/test/klippy/danger_options.cfg +++ b/test/klippy/danger_options.cfg @@ -8,7 +8,7 @@ log_bed_mesh_at_startup: False log_shutdown_info: False allow_plugin_override: True multi_mcu_trsync_timeout: 0.05 -adc_ignore_limits: True +temp_ignore_limits: True autosave_includes: True bgflush_extra_time: 0.250