Skip to content

Commit

Permalink
Danger Options interface rework + new logging flags (DangerKlippers#197)
Browse files Browse the repository at this point in the history
* switch danger options to a directly-imported singleton

* no relative import

* fix import again

* add not loaded yet exception
  • Loading branch information
bwnance authored Apr 6, 2024
1 parent 6b94dfe commit 3a1a98b
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 40 deletions.
4 changes: 2 additions & 2 deletions klippy/configfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import sys, os, glob, re, time, logging, configparser, io
from extras.danger_options import get_danger_options

error = configparser.Error

Expand Down Expand Up @@ -684,8 +685,7 @@ def cmd_SAVE_CONFIG(self, gcmd):
raise gcode.error(msg)
regular_data = self._strip_duplicates(regular_data, self.autosave)

self.danger_options = self.printer.lookup_object("danger_options")
if self.danger_options.autosave_includes:
if get_danger_options().autosave_includes:
self._save_includes(cfgname, data, set(), gcode)

# NOW we're safe to check for conflicts
Expand Down
6 changes: 2 additions & 4 deletions klippy/extras/adc_temperature.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# This file may be distributed under the terms of the GNU GPLv3 license.
import logging, bisect

from extras.danger_options import get_danger_options

######################################################################
# Interface between MCU adc and heater temperature callbacks
Expand All @@ -25,9 +26,6 @@ def __init__(self, config, adc_convert):
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)
self.danger_options = config.get_printer().lookup_object(
"danger_options"
)

def setup_callback(self, temperature_callback):
self.temperature_callback = temperature_callback
Expand All @@ -40,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 self.danger_options.adc_ignore_limits:
if get_danger_options().adc_ignore_limits:
danger_check_count = 0
else:
danger_check_count = RANGE_CHECK_COUNT
Expand Down
22 changes: 13 additions & 9 deletions klippy/extras/bed_mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# This file may be distributed under the terms of the GNU GPLv3 license.
import logging, math, json, collections
from . import probe
from extras.danger_options import get_danger_options

PROFILE_VERSION = 1
PROFILE_OPTIONS = {
Expand Down Expand Up @@ -140,7 +141,7 @@ def __init__(self, config):
else:
config_file.warn(
"config",
f"Selected default bed mesh profile '{self.default_mesh_name}' not found in available profiles.",
f"Selected default bed mesh profile '{self.default_mesh_name}' not in available profiles.",
"Invalid profile name",
)
# register gcodes
Expand Down Expand Up @@ -172,8 +173,7 @@ def __init__(self, config):

def handle_connect(self):
self.toolhead = self.printer.lookup_object("toolhead")
self.danger_options = self.printer.lookup_object("danger_options")
if self.danger_options.log_bed_mesh_at_startup:
if get_danger_options().log_bed_mesh_at_startup:
self.bmc.print_generated_points(logging.info)

def set_mesh(self, mesh):
Expand Down Expand Up @@ -1313,9 +1313,11 @@ def _sample_lagrange(self, z_matrix):
y_mult = self.y_mult
self.mesh_matrix = [
[
0.0
if ((i % x_mult) or (j % y_mult))
else z_matrix[j // y_mult][i // x_mult]
(
0.0
if ((i % x_mult) or (j % y_mult))
else z_matrix[j // y_mult][i // x_mult]
)
for i in range(self.mesh_x_count)
]
for j in range(self.mesh_y_count)
Expand Down Expand Up @@ -1375,9 +1377,11 @@ def _sample_bicubic(self, z_matrix):
c = self.mesh_params["tension"]
self.mesh_matrix = [
[
0.0
if ((i % x_mult) or (j % y_mult))
else z_matrix[j // y_mult][i // x_mult]
(
0.0
if ((i % x_mult) or (j % y_mult))
else z_matrix[j // y_mult][i // x_mult]
)
for i in range(self.mesh_x_count)
]
for j in range(self.mesh_y_count)
Expand Down
31 changes: 30 additions & 1 deletion klippy/extras/danger_options.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class DangerOptions:
def __init__(self, config):
self.minimal_logging = config.getboolean("minimal_logging", False)
self.log_statistics = config.getboolean("log_statistics", True)
self.log_config_file_at_startup = config.getboolean(
"log_config_file_at_startup", True
Expand All @@ -8,6 +9,13 @@ def __init__(self, config):
"log_bed_mesh_at_startup", True
)
self.log_shutdown_info = config.getboolean("log_shutdown_info", True)
self.log_serial_reader_warnings = config.getboolean(
"log_serial_reader_warnings", True
)
self.log_startup_info = config.getboolean("log_startup_info", True)
self.log_webhook_method_register_messages = config.getboolean(
"log_webhook_method_register_messages", False
)
self.error_on_unused_config_options = config.getboolean(
"error_on_unused_config_options", True
)
Expand All @@ -29,6 +37,27 @@ def __init__(self, config):
"bgflush_extra_time", 0.250, minval=0.0
)

if self.minimal_logging:
self.log_statistics = False
self.log_config_file_at_startup = False
self.log_bed_mesh_at_startup = False
self.log_shutdown_info = False
self.log_serial_reader_warnings = False
self.log_startup_info = False
self.log_webhook_method_register_messages = False


DANGER_OPTIONS: DangerOptions = None


def get_danger_options():
global DANGER_OPTIONS
if DANGER_OPTIONS is None:
raise Exception("DangerOptions has not been loaded yet!")
return DANGER_OPTIONS


def load_config(config):
return DangerOptions(config)
global DANGER_OPTIONS
DANGER_OPTIONS = DangerOptions(config)
return DANGER_OPTIONS
4 changes: 2 additions & 2 deletions klippy/extras/homing.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# This file may be distributed under the terms of the GNU GPLv3 license.
import math
import logging
from extras.danger_options import get_danger_options

HOMING_START_DELAY = 0.001
ENDSTOP_SAMPLE_TIME = 0.000015
Expand Down Expand Up @@ -50,7 +51,6 @@ def __init__(self, printer, endstops, toolhead=None):
self.toolhead = toolhead
self.stepper_positions = []
self.distance_elapsed = []
self.danger_options = printer.lookup_object("danger_options")

def get_mcu_endstops(self):
return [es for es, name in self.endstops]
Expand Down Expand Up @@ -205,7 +205,7 @@ def moved_less_than_dist(self, min_dist, homing_axes):
if i in homing_axes
]
distance_tolerance = (
self.danger_options.homing_elapsed_distance_tolerance
get_danger_options().homing_elapsed_distance_tolerance
)
if any(
[
Expand Down
4 changes: 2 additions & 2 deletions klippy/extras/statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import os, time, logging
from extras.danger_options import get_danger_options


class PrinterSysStats:
Expand Down Expand Up @@ -61,7 +62,6 @@ def get_status(self, eventtime):
class PrinterStats:
def __init__(self, config):
self.printer = config.get_printer()
self.danger_options = self.printer.lookup_object("danger_options")
reactor = self.printer.get_reactor()
self.stats_timer = reactor.register_timer(self.generate_stats)
self.stats_cb = []
Expand All @@ -79,7 +79,7 @@ def handle_ready(self):

def generate_stats(self, eventtime):
stats = [cb(eventtime) for cb in self.stats_cb]
if max([s[0] for s in stats]) and self.danger_options.log_statistics:
if max([s[0] for s in stats]) and get_danger_options().log_statistics:
logging.info(
"Stats %.1f: %s", eventtime, " ".join([s[1] for s in stats])
)
Expand Down
10 changes: 5 additions & 5 deletions klippy/klippy.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import sys, os, gc, optparse, logging, time, collections, importlib, importlib.util
import util, reactor, queuelogger, msgproto
import gcode, configfile, pins, mcu, toolhead, webhooks
from extras.danger_options import get_danger_options

message_ready = "Printer is ready"

Expand Down Expand Up @@ -68,7 +69,6 @@ def __init__(self, main_reactor, bglogger, start_args):
self.run_result = None
self.event_handlers = {}
self.objects = collections.OrderedDict()
self.danger_options = None
# Init printer components that must be setup prior to config
for m in [gcode, webhooks]:
m.add_early_printer_objects(self)
Expand Down Expand Up @@ -158,7 +158,7 @@ def load_object(self, config, section, default=configfile.sentinel):
if (
found_in_extras
and found_in_plugins
and not self.danger_options.allow_plugin_override
and not get_danger_options().allow_plugin_override
):
raise self.config_error(
"Module '%s' found in both extras and plugins!" % (section,)
Expand Down Expand Up @@ -187,10 +187,10 @@ def load_object(self, config, section, default=configfile.sentinel):
def _read_config(self):
self.objects["configfile"] = pconfig = configfile.PrinterConfig(self)
config = pconfig.read_main_config()
self.danger_options = self.load_object(config, "danger_options")
self.load_object(config, "danger_options", None)
if (
self.bglogger is not None
and self.danger_options.log_config_file_at_startup
and get_danger_options().log_config_file_at_startup
):
pconfig.log_config(config)
# Create printer components
Expand All @@ -204,7 +204,7 @@ def _read_config(self):
for m in [toolhead]:
m.add_printer_objects(config)
# Validate that there are no undefined parameters in the config file
error_on_unused = self.danger_options.error_on_unused_config_options
error_on_unused = get_danger_options().error_on_unused_config_options
pconfig.check_unused_options(config, error_on_unused)

def _build_protocol_error_message(self, e):
Expand Down
15 changes: 7 additions & 8 deletions klippy/mcu.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import os
import zlib
import serialhdl, msgproto, pins, chelper, clocksync
from extras.danger_options import get_danger_options


class error(Exception):
Expand Down Expand Up @@ -312,9 +313,6 @@ def __init__(self, mcu, pin_params):
ffi_main, ffi_lib = chelper.get_ffi()
self._trdispatch = ffi_main.gc(ffi_lib.trdispatch_alloc(), ffi_lib.free)
self._trsyncs = [MCU_trsync(mcu, self._trdispatch)]
self.danger_options = self._mcu.get_printer().lookup_object(
"danger_options"
)

def get_mcu(self):
return self._mcu
Expand Down Expand Up @@ -377,7 +375,7 @@ def home_start(
self._rest_ticks = rest_ticks
reactor = self._mcu.get_printer().get_reactor()
self._trigger_completion = reactor.completion()
expire_timeout = self.danger_options.multi_mcu_trsync_timeout
expire_timeout = get_danger_options().multi_mcu_trsync_timeout
if len(self._trsyncs) == 1:
expire_timeout = TRSYNC_SINGLE_MCU_TIMEOUT
for i, trsync in enumerate(self._trsyncs):
Expand Down Expand Up @@ -707,7 +705,7 @@ class MCU:

def __init__(self, config, clocksync):
self._printer = printer = config.get_printer()
self.danger_options = printer.lookup_object("danger_options")
self.gcode = printer.lookup_object("gcode")
self._clocksync = clocksync
self._reactor = printer.get_reactor()
self._name = config.get_name()
Expand Down Expand Up @@ -799,7 +797,7 @@ def _handle_shutdown(self, params):
if clock is not None:
self._shutdown_clock = self.clock32_to_clock64(clock)
self._shutdown_msg = msg = params["static_string_id"]
if self.danger_options.log_shutdown_info:
if get_danger_options().log_shutdown_info:
logging.info(
"MCU '%s' %s: %s\n%s\n%s",
self._name,
Expand All @@ -815,7 +813,7 @@ def _handle_shutdown(self, params):
append_msgs = []
if (
msg.startswith("ADC out of range")
and not self.danger_options.adc_ignore_limits
and not get_danger_options.adc_ignore_limits
):
pheaters = self._printer.lookup_object("heaters")
heaters = [
Expand Down Expand Up @@ -1025,7 +1023,8 @@ def _mcu_identify(self):
self._clocksync.connect(self._serial)
except serialhdl.error as e:
raise error(str(e))
logging.info(self._log_info())
if get_danger_options().log_startup_info:
logging.info(self._log_info())
ppins = self._printer.lookup_object("pins")
pin_resolver = ppins.get_pin_resolver(self._name)
for cname, value in self.get_constants().items():
Expand Down
4 changes: 3 additions & 1 deletion klippy/serialhdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import serial

import msgproto, chelper, util
from extras.danger_options import get_danger_options


class error(Exception):
Expand Down Expand Up @@ -367,7 +368,8 @@ def handle_output(self, params):
)

def handle_default(self, params):
logging.warn("%sgot %s", self.warn_prefix, params)
if get_danger_options().log_serial_reader_warnings:
logging.warn("%sgot %s", self.warn_prefix, params)


# Class to send a query command and return the received response
Expand Down
4 changes: 2 additions & 2 deletions klippy/toolhead.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import math, logging, importlib
import chelper
import kinematics.extruder
from extras.danger_options import get_danger_options

# Common suffixes: _d is distance (in mm), _v is velocity (in
# mm/second), _v2 is velocity squared (mm^2/s^2), _t is time (in
Expand Down Expand Up @@ -248,7 +249,6 @@ class DripModeEndSignal(Exception):
class ToolHead:
def __init__(self, config):
self.printer = config.get_printer()
self.danger_options = self.printer.lookup_object("danger_options")
self.reactor = self.printer.get_reactor()
self.all_mcus = [
m for n, m in self.printer.lookup_objects(module="mcu")
Expand Down Expand Up @@ -545,7 +545,7 @@ def _flush_handler(self, eventtime):
while 1:
end_flush = (
self.need_flush_time
+ self.danger_options.bgflush_extra_time
+ get_danger_options().bgflush_extra_time
)
if self.last_flush_time >= end_flush:
self.do_kick_flush_timer = True
Expand Down
10 changes: 6 additions & 4 deletions klippy/webhooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# This file may be distributed under the terms of the GNU GPLv3 license
import logging, socket, os, sys, errno, json, collections
import gcode
from extras.danger_options import get_danger_options

REQUEST_LOG_SIZE = 20

Expand Down Expand Up @@ -407,10 +408,11 @@ def _handle_rpc_registration(self, web_request):
template = web_request.get_dict("response_template")
method = web_request.get_str("remote_method")
new_conn = web_request.get_client_connection()
logging.info(
"webhooks: registering remote method '%s' "
"for connection id: %d" % (method, id(new_conn))
)
if get_danger_options().log_webhook_method_register_messages:
logging.info(
"webhooks: registering remote method '%s' "
"for connection id: %d" % (method, id(new_conn))
)
self._remote_methods.setdefault(method, {})[new_conn] = template

def get_connection(self):
Expand Down

0 comments on commit 3a1a98b

Please sign in to comment.