def __init__(self): # read config self.config = { 'remote': False, 'host': '127.0.0.1', 'actions': {}, 'pi.ir': True, 'arduino.ir': False, 'arduino.nmea.in': False, 'arduino.nmea.out': False, 'arduino.nmea.baud': 4800, 'lcd': {} } self.configfilename = os.getenv('HOME') + '/.pypilot/hat.conf' print('loading config file:', self.configfilename) try: file = open(self.configfilename) config = pyjson.loads(file.read()) file.close() for name in config: self.config[name] = config[name] except Exception as e: print('config failed:', e) try: configfile = '/proc/device-tree/hat/custom_0' f = open(configfile) hat_config = pyjson.loads(f.read()) f.close() print('loaded device tree hat config') if not 'hat' in self.config or hat_config != self.config['hat']: self.config['hat'] = hat_config print('writing device tree hat to hat.conf') self.write_config() except Exception as e: print('failed to load', configfile, ':', e) if not 'hat' in self.config: if os.path.exists('/dev/spidev0.0'): print( 'assuming original 26 pin tinypilot with nokia5110 display' ) self.config['hat'] = { 'lcd': { 'driver': 'nokia5110', 'port': '/dev/spidev0.0' }, 'lirc': 'gpio4' } self.write_config() self.servo_timeout = time.monotonic() + 1 self.last_msg = {} self.last_msg['ap.enabled'] = False self.last_msg['ap.heading_command'] = 0 if self.config['remote']: host = self.config['host'] else: host = 'localhost' self.client = pypilotClient(host) self.client.registered = False self.watchlist = ['ap.enabled', 'ap.heading_command'] for name in self.watchlist: self.client.watch(name) self.lcd = lcd.LCD(self) self.gpio = gpio.gpio() self.arduino = Arduino(self) self.poller = select.poll() self.poller.register(self.arduino.pipe, select.POLLIN) self.lirc = lircd.lirc(self.config) self.lirc.registered = False self.keytimes = {} self.keytimeouts = {} # keypad for lcd interface self.actions = [] keypadnames = [ 'auto', 'menu', 'port1', 'starboard1', 'select', 'port10', 'starboard10', 'tack', 'dodge_port', 'dodge_starboard' ] for i in range(len(keypadnames)): self.actions.append(ActionKeypad(self.lcd, i, keypadnames[i])) # stateless actions for autopilot control self.actions += [ ActionEngage(self), ActionPypilot(self, 'disengage', 'ap.enabled', False), ActionHeading(self, 1), ActionHeading(self, -1), ActionHeading(self, 2), ActionHeading(self, -2), ActionHeading(self, 5), ActionHeading(self, -5), ActionHeading(self, 10), ActionHeading(self, -10), ActionPypilot(self, 'compassmode', 'ap.mode', 'compass'), ActionPypilot(self, 'gpsmode', 'ap.mode', 'gps'), ActionPypilot(self, 'windmode', 'ap.mode', 'wind'), ActionPypilot(self, 'center', 'servo.position', 0), ActionTack(self, 'tackport', 'port'), ActionTack(self, 'tackstarboard', 'starboard'), ActionNone() ] for action in self.actions: if action.name in self.config['actions']: action.keys = self.config['actions'][action.name] self.web = Web(self) def cleanup(signal_number, frame=None): print('got signal', signal_number, 'cleaning up', os.getpid()) childpids = [] processes = [self.arduino, self.web] for process in processes: if process.process: childpids.append(process.process.pid) if signal_number == signal.SIGCHLD: pid = os.waitpid(-1, os.WNOHANG) if not pid[0] in childpids: print('subprocess returned', pid, childpids) # flask or system makes process at startup that dies return print('child process', pid, childpids) while childpids: pid = childpids.pop() #print('kill!', pid, childpids, os.getpid()) try: os.kill(pid, signal.SIGTERM) # get backtrace except ProcessLookupError: pass # ok, process is already terminated sys.stdout.flush() for process in processes: process.process = False if signal_number != 'atexit': raise KeyboardInterrupt # to get backtrace on all processes sys.stdout.flush() for s in range(1, 16): if s != 9 and s != 13: signal.signal(s, cleanup) signal.signal(signal.SIGCHLD, cleanup) import atexit atexit.register(lambda: cleanup('atexit'))
close_room, rooms, disconnect from pypilot.client import pypilotClient from pypilot import pyjson sys.path.append(os.path.dirname(os.path.abspath(__file__))) import tinypilot pypilot_web_port = 8000 if len(sys.argv) > 1: pypilot_web_port = int(sys.argv[1]) else: filename = os.getenv('HOME') + '/.pypilot/web.conf' try: file = open(filename, 'r') config = pyjson.loads(file.readline()) if 'port' in config: pypilot_web_port = config['port'] file.close() except: print('using default port of', pypilot_web_port) # Set this variable to 'threading', 'eventlet' or 'gevent' to test the # different async modes, or leave it set to None for the application to choose # the best option based on installed packages. async_mode = None app = Flask(__name__) app.config['SECRET_KEY'] = 'secret!' socketio = SocketIO(app, async_mode=async_mode)