Skip to content

Commit

Permalink
Adding GUI notifications for important events.
Browse files Browse the repository at this point in the history
  • Loading branch information
SasaKaranovic committed Feb 8, 2024
1 parent 2b1cc19 commit fb2dabc
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 6 deletions.
19 changes: 14 additions & 5 deletions server.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from dial_driver import DialSerialDriver
from server_config import ServerConfig
from server_dial_handler import ServerDialHandler
from vu_notifications import show_error_msg, show_info_msg

BASEDIR_NAME = os.path.dirname(__file__)
BASEDIR_PATH = os.path.abspath(BASEDIR_NAME)
Expand Down Expand Up @@ -517,7 +518,11 @@ def __init__(self):
self.serialPort = DialSerialDriver.find_gauge_hub()
if self.serialPort is None:
logger.error("Could not find VU1 Dials Hub. Please make sure it's plugged in and (if necessary) drivers are installed.")
raise Exception("Could not find VU1 Dials Hub. Please make sure it's plugged in and (if necessary) drivers are installed.")
show_error_msg("Hub not found", "Could not find VU1 Hub on the USB bus.\r\n"\
"Please make sure it is plugged in and (if necessary) drivers are installed.\r\n"\
"Then restart the VU Server application.\r\nVU server application will close now.")
sys.exit(0)
# raise Exception("Could not find VU1 Dials Hub. Please make sure it's plugged in and (if necessary) drivers are installed.")

logger.info("VU1 HUB port: {}".format(self.serialPort))
self.dial_driver = DialSerialDriver(self.serialPort)
Expand Down Expand Up @@ -572,13 +577,15 @@ def run_forever(self):
logger.info(f"VU1 API server is listening on http://localhost:{port}")
app.listen(port)

if master_key:
logger.info("Master Key is present in config.yaml")
if master_key is not None:
logger.info("Master Key is present in config.yaml (or using default)")
logger.info(f"Provide '{master_key}' to your main application.")
logger.info("to allow it to manage this server and the VU dials.")
else:
show_error_msg(title='Key missing from config', message='Entry "master_key" is missing from the "config.yaml"!')
logger.error("Master Key is MISSING from config.yaml")
logger.error("Check your 'config.yaml' or add it manually under 'server' section.")
sys.exit(0)

pc = PeriodicCallback(self.dial_handler.periodic_dial_update, dial_update_period)
pc.start()
Expand All @@ -590,6 +597,7 @@ def signal_handler(signal, frame):
pid_lock('server', False)
IOLoop.current().add_callback_from_signal(shutdown)
print('\r\nYou pressed Ctrl+C!')
show_info_msg("CTRL+C", "CTRL+C pressed.\r\nVU Server app will exit now.") # Remove if becomes annoying
sys.exit(0)

def shutdown():
Expand Down Expand Up @@ -619,11 +627,12 @@ def main(cmd_args=None):
try:
Dial_API_Service().run_forever()
except Exception:
logger.exception("Dials API service crashed during setup.")
logger.exception("VU Dials API service crashed during setup.")
show_error_msg("Crashed", "VU Server has crashed unexpectedly!\r\nPlease check log files for more information.")
os._exit(0)

if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Karanovic Research - Dials API service')
parser = argparse.ArgumentParser(description='Karanovic Research - VU Dials API service')
parser.add_argument('-l', '--logging', type=str, default='info', help='Set logging level. Default is `info`')
args = parser.parse_args()
main(args)
54 changes: 53 additions & 1 deletion server_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
from ruamel.yaml import YAML
# import yaml
from dials.base_logger import logger
from vu_notifications import show_error_msg, show_warning_msg
import database as db

class ServerConfig:
config_path = None
server = None
server_default = {'hostname': 'localhost', 'port': 3000, 'master_key': 'cTpAWYuRpA2zx75Yh961Cg' }
hardware = None
server_default = {'hostname': 'localhost', 'port': 3000, 'communication_timeout': 10, 'master_key': 'cTpAWYuRpA2zx75Yh961Cg' }
hardware_default = {'port': None }
dials = {}
api_keys = {}
Expand Down Expand Up @@ -51,6 +53,9 @@ def _save_config(self):
def _load_config(self):
if not os.path.exists(self.config_path):
logger.error(f"Can not load config. Config file '{self.config_path}' does not exist!")
show_error_msg("Can not find config.yaml", f"Config file '{self.config_path}' is missing!\r\n"\
"Please fix this issue by creating a default config.yaml file in the VU Server directory.\r\n"\
"Using default values for this session.")
self._create_default_config()
return False

Expand All @@ -59,18 +64,65 @@ def _load_config(self):
cfg = yaml.load(file) # pylint: disable=assignment-from-no-return

if cfg is None:
show_error_msg("Empty/corrupt config file!", "Config file exists but it is empty or corrupt!\r\n"\
"Using defaul values for this session.")
self._create_default_config()
return False

# Check that config file meets the minimum requirements
if not isinstance(cfg, dict) or 'server' not in cfg or 'hardware' not in cfg:
show_warning_msg("Missing Key", f"Config file '{self.config_path}' \r\n"\
"Must have valid entries for 'server' and 'hardware' configuration!\r\n"\
"Using defaul values for this session.")
cfg = {}
cfg['server'] = self.server_default
cfg['hardware'] = self.hardware_default

elif not isinstance(cfg['server'], dict):
show_warning_msg("Invalid server config", f"Config file '{self.config_path}' \r\n"\
"Has invalid `server` config entry.\r\n"\
"Using defaul values for this session.")
self._force_default_config()
return False

elif not isinstance(cfg['hardware'], dict):
show_warning_msg("Invalid server config", f"Config file '{self.config_path}' \r\n"\
"Has invalid `hardware` config entry.\r\n"\
"Using defaul values for this session.")
self._force_default_config()
return False

elif ('hostname' not in cfg['server'] or
'port' not in cfg['server'] or
'communication_timeout' not in cfg['server'] or
'master_key' not in cfg['server']):
show_warning_msg("Missing Key", f"Config file '{self.config_path}' \r\n"\
"must have `hostname`, `port`, `communication_timeout` and `master_key` entries!\r\n"\
"Using defaul values for this session.")
self._force_default_config()
return False

elif 'port' not in cfg['hardware']:
show_warning_msg("Missing Key", f"Config file '{self.config_path}' \r\n"\
"must have hardware `port` entry! (it can be left empty)\r\n"\
"Using defaul values for this session.")
self._force_default_config()
return False

# Load yaml values
self.server = cfg.get('server', self.server_default)
self.hardware = cfg.get('hardware', self.hardware_default)

return True

def _force_default_config(self):
self.server = self.server_default
self.hardware = self.hardware_default

def _create_default_config(self):
logger.info("Using default config values")
self.server = self.server_default
self.hardware = self.hardware_default

# Load API keys from config file
def _load_API_keys(self):
Expand Down
24 changes: 24 additions & 0 deletions vu_notifications.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# pylint: disable=import-outside-toplevel
import sys

# TODO: Add support for Linux and Mac OS

if sys.platform.lower() == "win32":
import ctypes

def show_error_msg(title, message):
ctypes.windll.user32.MessageBoxW(0, message, f"VU Server - {title}", 16)

def show_warning_msg(title, message):
ctypes.windll.user32.MessageBoxW(0, message, f"VU Server - {title}", 48)

def show_info_msg(title, message):
ctypes.windll.user32.MessageBoxW(0, message, f"VU Server - {title}", 64)

else:
def show_error_msg(title, message):
pass
def show_warning_msg(title, message):
pass
def show_info_msg(title, message):
pass

0 comments on commit fb2dabc

Please sign in to comment.