fix loglevel

This commit is contained in:
Johannes
2026-02-22 00:04:34 +01:00
committed by GitHub
parent 05d9ff52ca
commit 2cf7bcb63e

View File

@@ -15,94 +15,94 @@ import sys
from queue import Queue from queue import Queue
from mqtt import MqttManager from mqtt import MqttManager
logging.getLogger("watchdog").propagate = False logging.getLogger("watchdog").propagate = False
settings = {} settings = {}
panels = {} panels = {}
panel_in_queues = {} panel_in_queues = {}
panel_out_queue = Queue(maxsize=20) panel_out_queue = Queue(maxsize=20)
last_settings_file_mtime = 0 last_settings_file_mtime = 0
mqtt_connect_time = 0 mqtt_connect_time = 0
has_sent_reload_command = False has_sent_reload_command = False
log_level_name = os.getenv("loglevel", "DEBUG").upper()
log_level = getattr(logging, log_level_name, None)
invalid_log_level = not isinstance(log_level, int)
if invalid_log_level:
log_level = logging.DEBUG
logging.basicConfig(
level=log_level,
format="%(asctime)s %(levelname)s [%(threadName)s] %(name)s: %(message)s",
)
if invalid_log_level:
logging.warning("Invalid loglevel '%s', defaulting to DEBUG", log_level_name)
def on_ha_update(entity_id): log_level_name = os.getenv("LOGLEVEL", "DEBUG").upper()
global panel_in_queues log_level = getattr(logging, log_level_name, None)
# send HA updates to all panels invalid_log_level = not isinstance(log_level, int)
for queue in panel_in_queues.values(): if invalid_log_level:
try: log_level = logging.DEBUG
queue.put(("HA:", entity_id))
except Exception:
logging.exception("Failed to enqueue HA update for entity '%s'", entity_id)
def on_ha_panel_event(device_id, msg): logging.basicConfig(
global panel_in_queues level=log_level,
format="%(asctime)s %(levelname)s [%(threadName)s] %(name)s: %(message)s",
if device_id in panel_in_queues.keys(): )
queue = panel_in_queues[device_id] if invalid_log_level:
try: logging.warning("Invalid loglevel '%s', defaulting to DEBUG", log_level_name)
queue.put(("MQTT:", msg))
except Exception:
logging.exception("Failed to enqueue panel event for device '%s'", device_id)
def process_output_to_panel(): def on_ha_update(entity_id):
while True: global panel_in_queues
try: # send HA updates to all panels
msg = panel_out_queue.get() for queue in panel_in_queues.values():
service = msg[0] + "_nspanelui_api_call" try:
service_data = { queue.put(("HA:", entity_id))
"data": msg[1], except Exception:
"command": 2 logging.exception("Failed to enqueue HA update for entity '%s'", entity_id)
}
libs.home_assistant.send_msg_to_panel( def on_ha_panel_event(device_id, msg):
service=service, global panel_in_queues
service_data=service_data
) if device_id in panel_in_queues.keys():
except Exception: queue = panel_in_queues[device_id]
logging.exception("Failed to process outgoing panel message") try:
queue.put(("MQTT:", msg))
except Exception:
logging.exception("Failed to enqueue panel event for device '%s'", device_id)
def process_output_to_panel():
while True:
try:
msg = panel_out_queue.get()
service = msg[0] + "_nspanelui_api_call"
service_data = {
"data": msg[1],
"command": 2
}
libs.home_assistant.send_msg_to_panel(
service=service,
service_data=service_data
)
except Exception:
logging.exception("Failed to process outgoing panel message")
def connect(): def connect():
global settings, panel_out_queue global settings, panel_out_queue
ha_is_configured = settings["home_assistant_address"] != "" and settings["home_assistant_token"] != "" ha_is_configured = settings["home_assistant_address"] != "" and settings["home_assistant_token"] != ""
if "mqtt_server" in settings and not "use_ha_api" in settings: if "mqtt_server" in settings and not "use_ha_api" in settings:
MqttManager(settings, panel_out_queue, panel_in_queues) MqttManager(settings, panel_out_queue, panel_in_queues)
else: else:
logging.info("MQTT values not configured, will not connect.") logging.info("MQTT values not configured, will not connect.")
# MQTT Connected, start APIs if configured # MQTT Connected, start APIs if configured
if ha_is_configured: if ha_is_configured:
libs.home_assistant.init(settings, on_ha_update) libs.home_assistant.init(settings, on_ha_update)
libs.home_assistant.connect() libs.home_assistant.connect()
else: else:
logging.info("Home Assistant values not configured, will not connect.") logging.info("Home Assistant values not configured, will not connect.")
return return
wait_seconds = 0 wait_seconds = 0
while not libs.home_assistant.ws_connected: while not libs.home_assistant.ws_connected:
wait_seconds += 1 wait_seconds += 1
if wait_seconds % 10 == 0: if wait_seconds % 10 == 0:
logging.info("Waiting for Home Assistant websocket connection... (%ss)", wait_seconds) logging.info("Waiting for Home Assistant websocket connection... (%ss)", wait_seconds)
time.sleep(1) time.sleep(1)
if settings.get("use_ha_api"): if settings.get("use_ha_api"):
libs.home_assistant.subscribe_to_nspanel_events(on_ha_panel_event) libs.home_assistant.subscribe_to_nspanel_events(on_ha_panel_event)
send_to_panel_thread = threading.Thread(target=process_output_to_panel, args=()) send_to_panel_thread = threading.Thread(target=process_output_to_panel, args=())
send_to_panel_thread.daemon = True send_to_panel_thread.daemon = True
send_to_panel_thread.start() send_to_panel_thread.start()
def setup_panels(): def setup_panels():
global settings, panel_in_queues global settings, panel_in_queues
# Create NsPanel object # Create NsPanel object
for name, settings_panel in settings["nspanels"].items(): for name, settings_panel in settings["nspanels"].items():
@@ -115,25 +115,25 @@ def setup_panels():
msg_in_queue = Queue(maxsize=20) msg_in_queue = Queue(maxsize=20)
panel_in_queues[settings_panel["panelRecvTopic"]] = msg_in_queue panel_in_queues[settings_panel["panelRecvTopic"]] = msg_in_queue
panel_thread = threading.Thread(target=panel_thread_target, args=(msg_in_queue, name, settings_panel, panel_out_queue)) panel_thread = threading.Thread(target=panel_thread_target, args=(msg_in_queue, name, settings_panel, panel_out_queue))
panel_thread.daemon = True panel_thread.daemon = True
panel_thread.start() panel_thread.start()
def panel_thread_target(queue_in, name, settings_panel, queue_out): def panel_thread_target(queue_in, name, settings_panel, queue_out):
try: try:
panel = LovelaceUIPanel(name, settings_panel, queue_out) panel = LovelaceUIPanel(name, settings_panel, queue_out)
except Exception: except Exception:
logging.exception("Failed to initialize panel thread for '%s'", name) logging.exception("Failed to initialize panel thread for '%s'", name)
return return
while True: while True:
try: try:
msg = queue_in.get() msg = queue_in.get()
if msg[0] == "MQTT:": if msg[0] == "MQTT:":
panel.customrecv_event_callback(msg[1]) panel.customrecv_event_callback(msg[1])
elif msg[0] == "HA:": elif msg[0] == "HA:":
panel.ha_event_callback(msg[1]) panel.ha_event_callback(msg[1])
except Exception: except Exception:
logging.exception("Panel thread '%s' failed while handling queue message", name) logging.exception("Panel thread '%s' failed while handling queue message", name)
def get_config_file(): def get_config_file():
CONFIG_FILE = os.getenv('CONFIG_FILE') CONFIG_FILE = os.getenv('CONFIG_FILE')
@@ -141,34 +141,34 @@ def get_config_file():
CONFIG_FILE = './panels.yaml' CONFIG_FILE = './panels.yaml'
return CONFIG_FILE return CONFIG_FILE
def get_config(file): def get_config(file):
global settings global settings
try: try:
with open(file, 'r', encoding="utf8") as file: with open(file, 'r', encoding="utf8") as file:
settings = yaml.safe_load(file) settings = yaml.safe_load(file)
except FileNotFoundError: except FileNotFoundError:
logging.error("Config file not found: %s", file) logging.error("Config file not found: %s", file)
return False return False
except OSError: except OSError:
logging.exception("Failed reading config file: %s", file) logging.exception("Failed reading config file: %s", file)
return False return False
except yaml.YAMLError as exc: except yaml.YAMLError as exc:
logging.error("Error while parsing YAML file: %s", file) logging.error("Error while parsing YAML file: %s", file)
if hasattr(exc, 'problem_mark'): if hasattr(exc, 'problem_mark'):
if exc.context != None: if exc.context != None:
logging.error( logging.error(
"Parser says\n%s\n%s %s\nPlease correct data and retry.", "Parser says\n%s\n%s %s\nPlease correct data and retry.",
str(exc.problem_mark), str(exc.problem), str(exc.context) str(exc.problem_mark), str(exc.problem), str(exc.context)
) )
else: else:
logging.error( logging.error(
"Parser says\n%s\n%s\nPlease correct data and retry.", "Parser says\n%s\n%s\nPlease correct data and retry.",
str(exc.problem_mark), str(exc.problem) str(exc.problem_mark), str(exc.problem)
) )
else: else:
logging.exception("Something went wrong while parsing yaml file") logging.exception("Something went wrong while parsing yaml file")
return False return False
if not settings.get("mqtt_username"): if not settings.get("mqtt_username"):
settings["mqtt_username"] = os.getenv('MQTT_USER') settings["mqtt_username"] = os.getenv('MQTT_USER')
@@ -190,7 +190,7 @@ def get_config(file):
settings["is_addon"] = True settings["is_addon"] = True
return True return True
def config_watch(): def config_watch():
class ConfigChangeEventHandler(FileSystemEventHandler): class ConfigChangeEventHandler(FileSystemEventHandler):
def __init__(self, base_paths): def __init__(self, base_paths):
self.base_paths = base_paths self.base_paths = base_paths
@@ -201,24 +201,24 @@ def config_watch():
super(ConfigChangeEventHandler, self).dispatch(event) super(ConfigChangeEventHandler, self).dispatch(event)
return return
def on_modified(self, event): def on_modified(self, event):
logging.info('Modification detected. Reloading panels.') logging.info('Modification detected. Reloading panels.')
pid = os.getpid() pid = os.getpid()
os.kill(pid, signal.SIGTERM) os.kill(pid, signal.SIGTERM)
logging.info('Watching for changes in config file') logging.info('Watching for changes in config file')
project_files = [] project_files = []
project_files.append(get_config_file()) project_files.append(get_config_file())
handler = ConfigChangeEventHandler(project_files) handler = ConfigChangeEventHandler(project_files)
observer = Observer() observer = Observer()
watch_path = os.path.dirname(get_config_file()) or "." watch_path = os.path.dirname(get_config_file()) or "."
observer.schedule(handler, path=watch_path, recursive=True) observer.schedule(handler, path=watch_path, recursive=True)
observer.start() observer.start()
while True: while True:
try: try:
time.sleep(1) time.sleep(1)
except Exception: except Exception:
logging.exception("Config watch loop failed") logging.exception("Config watch loop failed")
def signal_handler(signum, frame): def signal_handler(signum, frame):
logging.info(f"Received signal {signum}. Initiating restart...") logging.info(f"Received signal {signum}. Initiating restart...")
@@ -237,4 +237,5 @@ if __name__ == '__main__':
time.sleep(100) time.sleep(100)
else: else:
while True: while True:
time.sleep(100)
time.sleep(100)