mirror of
https://github.com/joBr99/nspanel-lovelace-ui.git
synced 2026-02-22 14:08:37 +01:00
fix loglevel
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user