|
1 | 1 | import os |
2 | 2 | import time |
3 | 3 | import wifi |
| 4 | + |
4 | 5 | import toml |
| 6 | +import adafruit_logging as logging |
| 7 | +from .printers import Printer, NullPrinter |
| 8 | +from .services import Service |
| 9 | +from .util.log import Log |
5 | 10 |
|
6 | 11 |
|
7 | | -class Server: |
8 | | - debug: bool = False |
| 12 | +class Server(object): |
9 | 13 | runtime: dict |
10 | | - config: toml.Dotty |
| 14 | + settings: toml.Dotty |
| 15 | + logger: logging.Logger |
| 16 | + |
| 17 | + def __new__(cls): |
| 18 | + if hasattr(cls, 'singleton') is False: |
| 19 | + cls.singleton = super(Server, cls).__new__(cls) |
| 20 | + cls.singleton.logger = Log().getLogger("root") |
| 21 | + cls.singleton.settings = None |
| 22 | + cls.singleton.runtime = { 'printers': {}, 'services': {} } |
| 23 | + return cls.singleton |
11 | 24 |
|
12 | | - def __init__(self, debug): |
13 | | - self.debug = debug |
14 | | - self.runtime = { 'printers': {}, 'services': {} } |
15 | | - self.config = toml.load('settings.toml') |
16 | | - self.config.setdefault('SYSTEM', {}) |
17 | | - self.config.setdefault('ESCPOS', {'PRINTERS': {}, 'SERVICES': {}}) |
18 | | - self.config.setdefault('PRINTER:DEBUG', {'DRIVER': 'DEBUG'}) |
| 25 | + def getLogger(self) -> logging.Logger: |
| 26 | + return self.logger |
| 27 | + |
| 28 | + def getPrinter(self, name: str) -> Printer: |
| 29 | + if len(self.runtime['printers']) == 0: |
| 30 | + return None |
| 31 | + if name not in self.runtime['printers']: |
| 32 | + return NullPrinter() |
| 33 | + return self.runtime['printers'][name] |
19 | 34 |
|
| 35 | + def getService(self, name: str) -> Service: |
| 36 | + if name in self.runtime['services']: |
| 37 | + return self.runtime['services'][name] |
| 38 | + return None |
20 | 39 |
|
21 | 40 | def setup(self): |
22 | | - print(f"Configuring printers...") |
23 | | - for printer_name in self.config['ESCPOS']['PRINTERS']: |
24 | | - print(f" Configuring printer '{printer_name}'...") |
| 41 | + self.settings = toml.load('settings.toml') |
| 42 | + self.settings.setdefault('SYSTEM', {}) |
| 43 | + self.settings.setdefault('ESCPOS', {'PRINTERS': {}, 'SERVICES': {}}) |
| 44 | + self.settings.setdefault('PRINTER:DEBUG', {'DRIVER': 'DEBUG'}) |
| 45 | + Log().setup(self, self.settings) |
| 46 | + self.logger.info(f"Configuring printers...") |
| 47 | + printers = dict() |
| 48 | + for printer_name in self.settings['ESCPOS']['PRINTERS']: |
| 49 | + self.logger.info(f" Configuring printer '{printer_name}'...") |
25 | 50 | printer_section = f"PRINTER:{printer_name}" |
26 | | - if printer_section in self.config and 'DRIVER' in self.config[printer_section]: |
| 51 | + if printer_section in self.settings and 'DRIVER' in self.settings[printer_section]: |
27 | 52 | printer = None |
28 | | - printer_driver = self.config[printer_section]['DRIVER'].upper() |
| 53 | + printer_driver = self.settings[printer_section]['DRIVER'].upper() |
29 | 54 | if printer_driver == 'DEBUG': |
30 | 55 | from .printers.debug import PrinterDEBUG |
31 | 56 | printer = PrinterDEBUG() |
32 | 57 | elif printer_driver == 'SERIAL': |
33 | 58 | from .printers.serial import PrinterSerial |
34 | | - printer = PrinterSerial(self.debug) |
| 59 | + printer = PrinterSerial() |
35 | 60 | elif printer_driver == 'USB': |
36 | 61 | from .printers.usb import PrinterUSB |
37 | | - usb_host_pin_dp = self.config['SYSTEM'].get('USB_HOST_PIN_DP') |
38 | | - usb_host_pin_dm = self.config['SYSTEM'].get('USB_HOST_PIN_DM') |
| 62 | + usb_host_pin_dp = self.settings['SYSTEM'].get('USB_HOST_PIN_DP') |
| 63 | + usb_host_pin_dm = self.settings['SYSTEM'].get('USB_HOST_PIN_DM') |
39 | 64 | if usb_host_pin_dp is not None and usb_host_pin_dm is not None: |
40 | | - printer = PrinterUSB(usb_host_pin_dp, usb_host_pin_dm, self.debug) |
| 65 | + printer = PrinterUSB(printer_name, usb_host_pin_dp, usb_host_pin_dm) |
41 | 66 | else: |
42 | | - print(f" ERROR: in configuration for printer '{printer_name}': missing pin definition in table/section SYSTEM (USB_HOST_PIN_DP & USB_HOST_PIN_DM), skipping printer") |
| 67 | + self.logger.error(f" Missing USB pin definition in table/section SYSTEM (USB_HOST_PIN_DP & USB_HOST_PIN_DM), skipping printer '{printer_name}'") |
43 | 68 | else: |
44 | | - print(f" ERROR: in configuration for printer '{printer_name}': unknown driver type '{printer_driver}', skipping printer") |
| 69 | + self.logger.error(f" DRIVER='{printer_driver}' is invalid in configuration table/section 'PRINTER:{printer_name}' (in settings.toml), skipping printer") |
45 | 70 | if printer is not None: |
46 | | - if printer.setup(self.config[printer_section]) is True: |
47 | | - self.runtime['printers'][printer_name] = printer |
| 71 | + if printer.setup(self.settings[printer_section]) is True: |
| 72 | + printers[printer_name] = printer |
48 | 73 | else: |
49 | | - print(f" WARNING: Printer{printer_driver}.setup() failed for printer '{printer_name}', skipping printer") |
50 | | - print(f" ...configuration for printer '{printer_name}' finished") |
51 | | - print(f"...printers configured ({len(self.runtime['printers'])} active printers)") |
| 74 | + self.logger.warning(f" Printer{printer_driver}.setup() failed for printer '{printer_name}', skipping printer") |
| 75 | + self.logger.info(f" ...configuration for printer '{printer_name}' finished") |
| 76 | + self.runtime['printers'] = printers |
| 77 | + self.logger.info(f"...printers configured ({len(self.runtime['printers'])} active printers)") |
52 | 78 |
|
53 | | - print(f"Configuring services...") |
| 79 | + self.logger.info(f"Configuring services...") |
| 80 | + services = dict() |
54 | 81 | if len(self.runtime['printers']) == 0: |
55 | | - print(f" ERROR: no active printers, not activating any services") |
56 | | - self.config['ESCPOS']['SERVICES'] = [] |
57 | | - for service_name in self.config['ESCPOS']['SERVICES']: |
58 | | - print(f" Configuring service '{service_name}'...") |
| 82 | + self.logger.critical(f" No (active) printers, not activating any services") |
| 83 | + self.settings['ESCPOS']['SERVICES'] = [] |
| 84 | + for service_name in self.settings['ESCPOS']['SERVICES']: |
| 85 | + self.logger.info(f" Configuring service '{service_name}'...") |
59 | 86 | service_section = f"SERVICE:{service_name}" |
60 | | - if service_section not in self.config: |
61 | | - print(f" ERROR: configuration table/section 'SERVICE:{service_name}' not found, skipping service") |
62 | | - if 'DRIVER' not in self.config[service_section]: |
63 | | - print(f" ERROR: missing 'DRIVER' config in table/section 'SERVICE:{service_name}', skipping service") |
64 | | - if service_section in self.config and 'DRIVER' in self.config[service_section]: |
| 87 | + if service_section not in self.settings: |
| 88 | + self.logger.error(f" Configuration table/section 'SERVICE:{service_name}' (in settings.toml) not found, skipping service") |
| 89 | + if 'DRIVER' not in self.settings[service_section]: |
| 90 | + self.logger.error(f" Missing 'DRIVER' config in table/section 'SERVICE:{service_name}' (in settings.toml), skipping service") |
| 91 | + if service_section in self.settings and 'DRIVER' in self.settings[service_section]: |
65 | 92 | service = None |
66 | | - service_driver = self.config[service_section]['DRIVER'].upper() |
| 93 | + service_driver = self.settings[service_section]['DRIVER'].upper() |
67 | 94 | if service_driver == 'HTTP': |
68 | | - self.config[service_section].setdefault('SERVER_IPV4', str(wifi.radio.ipv4_address)) |
69 | | - self.config[service_section].setdefault('SERVER_PORT', 8080) |
70 | | - self.config[service_section].setdefault('SERVER_PATH', '/') |
| 95 | + self.settings[service_section].setdefault('SERVER_IPV4', str(wifi.radio.ipv4_address)) |
| 96 | + self.settings[service_section].setdefault('SERVER_PORT', 8080) |
| 97 | + self.settings[service_section].setdefault('SERVER_PATH', '/') |
71 | 98 | from .services.http import ServiceHTTP |
72 | | - service = ServiceHTTP(self.debug) |
| 99 | + service = ServiceHTTP(service_name) |
73 | 100 | elif service_driver == 'MQTT': |
74 | | - self.config[service_section].setdefault('BROKER_USER', None) |
75 | | - self.config[service_section].setdefault('BROKER_PASS', None) |
| 101 | + self.settings[service_section].setdefault('BROKER_USER', None) |
| 102 | + self.settings[service_section].setdefault('BROKER_PASS', None) |
76 | 103 | from .services.mqtt import ServiceMQTT |
77 | | - service = ServiceMQTT(self.debug) |
| 104 | + service = ServiceMQTT(service_name) |
78 | 105 | elif service_driver == 'TCP': |
79 | | - self.config[service_section].setdefault('SERVER_IPV4', str(wifi.radio.ipv4_address)) |
80 | | - self.config[service_section].setdefault('SERVER_PORT', 9100) |
81 | | - self.config[service_section].setdefault('CLIENT_TIMEOUT', 1) |
| 106 | + self.settings[service_section].setdefault('SERVER_IPV4', str(wifi.radio.ipv4_address)) |
| 107 | + self.settings[service_section].setdefault('SERVER_PORT', 9100) |
| 108 | + self.settings[service_section].setdefault('CLIENT_TIMEOUT', 1) |
82 | 109 | from .services.tcp import ServiceTCP |
83 | | - service = ServiceTCP(self.debug) |
| 110 | + service = ServiceTCP(service_name) |
84 | 111 | else: |
85 | | - print(f" ERROR: unknown driver type '{service_driver}' in configuration table/section 'SERVICE:{service_name}', skipping service") |
| 112 | + self.logger.error(f" DRIVER='{service_driver}' is invalid in configuration table/section 'SERVICE:{service_name}' (in settings.toml), skipping service") |
86 | 113 | if service is not None: |
87 | | - self.config[service_section].setdefault('PRINTERS', self.runtime['printers'].keys()) |
| 114 | + self.settings[service_section].setdefault('PRINTERS', self.runtime['printers'].keys()) |
88 | 115 | service2printers = {} |
89 | | - for printer_name in self.config[service_section]['PRINTERS']: |
| 116 | + for printer_name in self.settings[service_section]['PRINTERS']: |
90 | 117 | if printer_name in self.runtime['printers']: |
91 | 118 | service2printers[printer_name] = self.runtime['printers'][printer_name] |
92 | 119 | if len(service2printers) == 0: |
93 | | - print(f" WARNING: No printers assigned to service, skipping service") |
| 120 | + self.logger.warning(f" No printers assigned to service, skipping service") |
94 | 121 | else: |
95 | | - if service.setup(self.config[service_section], service2printers) is True: |
96 | | - self.runtime['services'][service_name] = service |
97 | | - print(f" INFO: Assigned printers = ['{'\',\''.join(service2printers.keys())}']") |
| 122 | + if service.setup(self.settings[service_section], service2printers) is True: |
| 123 | + services[service_name] = service |
| 124 | + self.logger.info(f" Assigned printers = ['{'\',\''.join(service2printers.keys())}']") |
98 | 125 | else: |
99 | | - print(f" WARNING: Service{service_driver}.setup() failed for service '{service_name}', skipping service") |
100 | | - print(f" ...configuration for service '{service_name}' finished") |
101 | | - print(f"...services configured ({len(self.runtime['services'])} active services)") |
| 126 | + self.logger.warning(f" Service{service_driver}.setup() failed for service '{service_name}', skipping service") |
| 127 | + self.logger.info(f" ...configuration for service '{service_name}' finished") |
| 128 | + self.runtime['services'] = services |
| 129 | + self.logger.info(f"...services configured ({len(self.runtime['services'])} active services)") |
102 | 130 |
|
103 | 131 |
|
104 | 132 | def loop(self) -> bool: |
|
0 commit comments