-
Notifications
You must be signed in to change notification settings - Fork 2
/
run.py
executable file
·127 lines (100 loc) · 4.24 KB
/
run.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/env python3
import argparse
import logging
import os
import sys
import socket
import time
import yaml
from apscheduler.schedulers.background import BackgroundScheduler
from datetime import datetime
from ioctlgw import build, version
from ioctlgw.boards import get_board
from ioctlgw.mqttconnector import MqttConnector
# from ioctlgw.web import WebService
from multiprocessing import Queue
LOG = logging.getLogger(__name__)
class Service(object):
def __init__(self, config):
self.config = config
self.startup = datetime.now()
self.instance = self.config["service"]["instance"]
self.timezone = self.config["service"]["timezone"]
self.scheduler = BackgroundScheduler(timezone=self.timezone)
self.controllers = {}
self.mqtt = MqttConnector(service=self)
self.queue_boards_connection = Queue()
self.queue_boards_io_status = Queue()
self.queue_boards_status = Queue()
def start(self, daemon):
#w = WebService(controllers=self.controllers)
#w.start()
LOG.info("Initialising boards")
for name, controller in self.config["controllers"].items():
address = controller["address"].strip().lower()
identifier = controller["board"].strip().lower()
LOG.info("Initialising '%s' using '%s' at '%s'", name, identifier, address)
board = get_board(identifier=identifier)
LOG.info("Found interface %s", board)
# TODO: handle a miss identified board
self.controllers[name] = board(name=name, address=address, service=self)
if daemon:
LOG.info("Daemon mode, starting services")
LOG.info("Starting primary scheduler")
self.scheduler.start()
LOG.info("Starting MQTT")
self.mqtt.start()
LOG.info("Starting boards")
for name, controller in self.controllers.items():
LOG.info("Starting %s", name)
self.controllers[name].start()
# TODO: handle being unable to start a board
while True:
if self.queue_boards_status.empty() is False:
msg = self.queue_boards_status.get()
self.mqtt.board_status(name=msg["name"], raw_msg=msg)
elif self.queue_boards_io_status.empty() is False:
msg = self.queue_boards_io_status.get()
self.mqtt.board_io_event(name=msg["name"], state=msg["state"])
elif self.queue_boards_connection.empty() is False:
event = self.queue_boards_connection.get()
self.mqtt.board_connection_event( name=event["name"], event=event["event"])
else:
time.sleep(0.05)
else:
LOG.info("Exiting, non-daemon mode")
sys.exit(0)
@property
def uptime(self):
return int((datetime.now()-self.startup).total_seconds()/60)
def main():
logging.basicConfig(level=logging.INFO)
logging.getLogger('apscheduler.executors.default').propagate = False
parser = argparse.ArgumentParser(description=f"IO Controller Gateway v{version()}")
parser.add_argument("-c", "--config", help="Config file", required=True)
parser.add_argument("-v", "--verbose", help="Increase verbosity", action="store_true")
parser.add_argument("-d", "--daemon", help="Daemon mode", action="store_true")
args = parser.parse_args()
LOG.info("IO Controller Gateway v%s %s on Python v%d.%d.%d", version(), build(),
sys.version_info.major, sys.version_info.minor, sys.version_info.micro)
# check config exists
cfgpath = args.config.strip()
if os.path.isfile(cfgpath) is False:
LOG.fatal("Specified config file does not exist: %s", cfgpath)
sys.exit(1)
daemon = False
if args.daemon:
daemon = True
# load the config
with open(cfgpath, 'r') as stream:
try:
config = yaml.load(stream, Loader=yaml.FullLoader)
except yaml.YAMLError as exc:
print(exc)
sys.exit(1)
s = Service(config=config)
LOG.info("Service instance %s ready", s.instance)
s.start(daemon=daemon)
sys.exit(0)
if __name__ == "__main__":
main()