configfile: Add printer.configfile.settings command template parameter

Make available the parsed value (or default value) for config options
to command templates and to the api server.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2021-01-14 22:22:33 -05:00
parent 023a985bfc
commit 8cc1d84180
2 changed files with 24 additions and 13 deletions

View File

@ -214,12 +214,14 @@ The following are common printer attributes:
as "triggered" during the last QUERY_PROBE command. Note, due to the as "triggered" during the last QUERY_PROBE command. Note, due to the
order of template expansion (see above), the QUERY_PROBE command order of template expansion (see above), the QUERY_PROBE command
must be run prior to the macro containing this reference. must be run prior to the macro containing this reference.
- `printer.configfile.config["<section>"]["<option>"]`: Returns the - `printer.configfile.settings.<section>.<option>`: Returns the given
given config file setting as read by Klipper during the last config file setting (or default value) during the last software
software start or restart. (Any settings changed at run-time will start or restart. (Any settings changed at run-time will not be
not be reflected here.) All values are returned as strings (if math reflected here.)
is to be performed on the value then it must be converted to a - `printer.configfile.config.<section>.<option>`: Returns the given
Python number). raw config file setting as read by Klipper during the last software
start or restart. (Any settings changed at run-time will not be
reflected here.) All values are returned as strings.
- `printer["gcode_macro <macro_name>"].<variable>`: The current value - `printer["gcode_macro <macro_name>"].<variable>`: The current value
of a [gcode_macro variable](#variables). of a [gcode_macro variable](#variables).
- `printer.webhooks.state`: Returns a string indicating the current - `printer.webhooks.state`: Returns a string indicating the current

View File

@ -1,6 +1,6 @@
# Code for reading and writing the Klipper config file # Code for reading and writing the Klipper config file
# #
# Copyright (C) 2016-2018 Kevin O'Connor <kevin@koconnor.net> # Copyright (C) 2016-2021 Kevin O'Connor <kevin@koconnor.net>
# #
# This file may be distributed under the terms of the GNU GPLv3 license. # This file may be distributed under the terms of the GNU GPLv3 license.
import os, glob, re, time, logging, ConfigParser as configparser, StringIO import os, glob, re, time, logging, ConfigParser as configparser, StringIO
@ -25,11 +25,12 @@ class ConfigWrapper:
above=None, below=None, note_valid=True): above=None, below=None, note_valid=True):
if not self.fileconfig.has_option(self.section, option): if not self.fileconfig.has_option(self.section, option):
if default is not sentinel: if default is not sentinel:
if note_valid and default is not None:
acc_id = (self.section.lower(), option.lower())
self.access_tracking[acc_id] = default
return default return default
raise error("Option '%s' in section '%s' must be specified" raise error("Option '%s' in section '%s' must be specified"
% (option, self.section)) % (option, self.section))
if note_valid:
self.access_tracking[(self.section.lower(), option.lower())] = 1
try: try:
v = parser(self.section, option) v = parser(self.section, option)
except self.error as e: except self.error as e:
@ -37,6 +38,8 @@ class ConfigWrapper:
except: except:
raise error("Unable to parse option '%s' in section '%s'" raise error("Unable to parse option '%s' in section '%s'"
% (option, self.section)) % (option, self.section))
if note_valid:
self.access_tracking[(self.section.lower(), option.lower())] = v
if minval is not None and v < minval: if minval is not None and v < minval:
raise error("Option '%s' in section '%s' must have minimum of %s" raise error("Option '%s' in section '%s' must have minimum of %s"
% (option, self.section, minval)) % (option, self.section, minval))
@ -93,7 +96,8 @@ class PrinterConfig:
def __init__(self, printer): def __init__(self, printer):
self.printer = printer self.printer = printer
self.autosave = None self.autosave = None
self.status_info = {} self.status_raw_config = {}
self.status_settings = {}
self.save_config_pending = False self.save_config_pending = False
gcode = self.printer.lookup_object('gcode') gcode = self.printer.lookup_object('gcode')
gcode.register_command("SAVE_CONFIG", self.cmd_SAVE_CONFIG, gcode.register_command("SAVE_CONFIG", self.cmd_SAVE_CONFIG,
@ -247,6 +251,10 @@ class PrinterConfig:
if (section, option) not in access_tracking: if (section, option) not in access_tracking:
raise error("Option '%s' is not valid in section '%s'" raise error("Option '%s' is not valid in section '%s'"
% (option, section)) % (option, section))
# Setup self.status_settings
self.status_settings = {}
for (section, option), value in config.access_tracking.items():
self.status_settings.setdefault(section, {})[option] = value
def log_config(self, config): def log_config(self, config):
lines = ["===== Config file =====", lines = ["===== Config file =====",
self._build_config_string(config), self._build_config_string(config),
@ -254,13 +262,14 @@ class PrinterConfig:
self.printer.set_rollover_info("config", "\n".join(lines)) self.printer.set_rollover_info("config", "\n".join(lines))
# Status reporting # Status reporting
def _build_status(self, config): def _build_status(self, config):
self.status_info.clear() self.status_raw_config.clear()
for section in config.get_prefix_sections(''): for section in config.get_prefix_sections(''):
self.status_info[section.get_name()] = section_status = {} self.status_raw_config[section.get_name()] = section_status = {}
for option in section.get_prefix_options(''): for option in section.get_prefix_options(''):
section_status[option] = section.get(option, note_valid=False) section_status[option] = section.get(option, note_valid=False)
def get_status(self, eventtime): def get_status(self, eventtime):
return {'config': self.status_info, return {'config': self.status_raw_config,
'settings': self.status_settings,
'save_config_pending': self.save_config_pending} 'save_config_pending': self.save_config_pending}
# Autosave functions # Autosave functions
def set(self, section, option, value): def set(self, section, option, value):