def main(): handler = EventHandler() handler.add_threaded_function(gsheets_listener) handler.add_threaded_function(timer_listener) handler.register_action(GSheetsEvent, printer1) handler.register_action(TimerEvent, printer1) handler.register_action(TimerEvent, printer2) handler.start(modules_conf_filepath, user_conf_filepath, max_workers=3)
class MainWindow(QMainWindow, gui.Ui_MainWindow): def __init__(self): super(self.__class__, self).__init__() self.setupUi(self) self.setFixedSize(self.width(), self.height()) self.activeMenu = -1 # current active menu page number self.log = logging.getLogger('GUI') self.lamps = {} self.heater = None self.icons = { 'heat': QIcon(':i_heat.png'), 'cold': QIcon(':i_cold.png'), } link.addCommand("TER_READ", config_ex.getJson) self.linkThread = link.LinkThread() self.linkThread.start() config_ex.configWorkerInit(self.reinitButtons) if config_ex.isInitialized() == True: config_ex.initDevices() self.initButtons(config_ex.getButtonsConfig()) self.log.info("Device is initialized!") else: self.log.warning("Device NOT initialized!") self.showInitScreen() return self.menu = [self.btnManual, self.btnAuto, self.btnDiag] self.menu[0].clicked.connect(lambda: self.displayView(0)) self.menu[1].clicked.connect(lambda: self.displayView(1)) self.menu[2].clicked.connect(lambda: self.displayView(2)) self.displayView(0) self.initStyles() self.guiClicker = gui_clicker.GuiClicker() self.guiClicker.setUpdateSignal(self.updateButtonStyle) self.guiClicker.start() self.diagThread = DiagThread() self.diagThread.update.connect(self.updateDiagPage) self.diagThread.start() self.evt = EventHandler(config_ex.loadData(), self.guiClicker, self.diagThread) self.evt.start() if config.getPlatform() == 'rpi': self.showFullScreen() def initButtons(self, config): buttons = [self.btnMan1, self.btnMan2, self.btnMan4, self.btnMan5] for cfg in config: if cfg['type'] == 'LAMP': color = 'rgba' + str(cfg['color'])[:-1] + ', 30%)' self.lamps[cfg['name']] = { 'btn': buttons.pop(0), 'color': color } elif cfg['type'] == 'CABLE': self.heater = {'name': cfg['name'], 'btn': self.btnMan3} else: self.log.error('Skipping device "%s"' % cfg['type']) if self.heater: self.heater['btn'].clicked.connect(self.guiHeaterToggle) self.heater['btn'].setIcon(self.icons['cold']) for name, gui in self.lamps.items(): gui['btn'].clicked.connect(self.createLampButtonCallback(name)) def updateDiagPage(self, sensors): if 't1' in sensors: self.labTTemp1.setText('%.1f' % sensors['t1'].stats.lastVal) self.labTTemp1Avg.setText('%.1f' % sensors['t1'].stats.avg) self.labTTemp1Min.setText('%.1f' % sensors['t1'].stats.min) self.labTTemp1Max.setText('%.1f' % sensors['t1'].stats.max) if 't2' in sensors: self.labTTemp2.setText('%.1f' % sensors['t2'].stats.lastVal) self.labTTemp2Avg.setText('%.1f' % sensors['t2'].stats.avg) self.labTTemp2Min.setText('%.1f' % sensors['t2'].stats.min) self.labTTemp2Max.setText('%.1f' % sensors['t2'].stats.max) if 'cpu' in sensors: self.labTCpu.setText('%.1f' % sensors['cpu'].stats.lastVal) self.labTCpuAvg.setText('%.1f' % sensors['cpu'].stats.avg) self.labTCpuMin.setText('%.1f' % sensors['cpu'].stats.min) self.labTCpuMax.setText('%.1f' % sensors['cpu'].stats.max) def reinitButtons(self, data): self.log.debug('Updating GUI buttons with data') self.log.debug(data) # initialize gui variables self.lamps = {} self.heater = None buttons = [ self.btnMan1, self.btnMan2, self.btnMan3, self.btnMan4, self.btnMan5 ] # remove buttons callbacks for btn in buttons: try: btn.clicked.disconnect() except Exception: pass # create gui buttons self.initButtons(data) self.initStyles() def updateButtonStyle(self, data): for dev, state in data.items(): if dev in self.lamps: self.guiLampStyle(dev, state) elif dev == self.heater['name']: self.guiHeaterStyle(state) else: self.log.warning('Device "%s" is not available on GUI' % dev) def displayView(self, viewNum): if viewNum == self.activeMenu: return styles.removeStyle(self.menu[self.activeMenu], MENU_INDICATOR) styles.addStyle(self.menu[viewNum], MENU_INDICATOR) self.mainView.setCurrentIndex(viewNum) self.activeMenu = viewNum def createLampButtonCallback(self, color): return lambda: self.guiLampToggle(color) def initStyles(self): for lampName, props in self.lamps.items(): styles.addStyle(props['btn'], 'background-color: {};'.format(props['color'])) # self.menuFrame.setStyleSheet('border: 4px solid #ffe0b2') def guiHeaterStyle(self, state): if self.heater: self.log.debug('Updating heater to {}'.format(state)) if state in [True, 'on']: self.heater['btn'].setIcon(self.icons['heat']) else: self.heater['btn'].setIcon(self.icons['cold']) else: self.log.warning('Heater is not present!') def guiHeaterToggle(self): self.guiClicker.set(self.heater['name'], 'toggle') def guiLampStyle(self, lamp, state): self.log.debug('updating lamp "{}" to {}'.format(lamp, state)) if state in [True, 'on']: styles.setAlpha(self.lamps[lamp]['btn'], 100) else: styles.setAlpha(self.lamps[lamp]['btn'], 30) def guiLampToggle(self, lamp): self.guiClicker.set(lamp, 'toggle') def showInitScreen(self): self.verticalLayoutWidget.hide() # hides all controls self.initLabel = QLabel(self.centralwidget) self.initLabel.setObjectName("initLabel") self.initLabel.setText('ZAINICJALIZUJ\nURZĄDZENIE') self.initLabel.setStyleSheet('font-size: 80px; color: darkblue') self.initLabel.setAlignment(PyQt5.QtCore.Qt.AlignHCenter | PyQt5.QtCore.Qt.AlignVCenter) self.initLabel.setFixedSize(self.width(), self.height())
class MainApp(object): def __init__(self): self.native_mode = False node_name = os.uname()[1] if node_name == 'raspberrypi': self.native_mode = True logging.debug('MainApp.__init__: native_mode {}'.format(self.native_mode)) if self.native_mode is True: self.display = DisplayDriverPCF8574() else: self.display = DisplayDriver(2, 16, debug_mode=False) self.sound = SoundDriver() self.model = ModelContainer() self.controllers = {} self.state_machine = None self.event_handler = None def init_state_machine(self): states = ['idle', 'alarm', 'main_menu', 'alarms', 'stations', 'config', 'alarm_modify', 'alarm_config'] transitions = [ {'trigger': 'trigger_alarm', 'source': '*', 'dest': 'alarm'}, # {'trigger': 'button_right', 'source': 'idle', 'dest': 'main_menu'}, # {'trigger': 'button_left', 'source': 'idle', 'dest': 'main_menu'}, {'trigger': 'button_enter', 'source': 'idle', 'dest': 'main_menu'}, {'trigger': 'button_back', 'source': 'alarm', 'dest': 'idle'}, {'trigger': 'button_back', 'source': 'main_menu', 'dest': 'idle'}, {'trigger': 'select_alarms', 'source': 'main_menu', 'dest': 'alarms'}, {'trigger': 'select_stations', 'source': 'main_menu', 'dest': 'stations'}, {'trigger': 'select_config', 'source': 'main_menu', 'dest': 'config'}, {'trigger': 'button_back', 'source': 'alarms', 'dest': 'main_menu'}, {'trigger': 'edit_alarm', 'source': 'alarms', 'dest': 'alarm_modify'}, {'trigger': 'new_alarm', 'source': 'alarms', 'dest': 'alarm_config'}, {'trigger': 'button_back', 'source': 'alarm_modify', 'dest': 'alarms'}, {'trigger': 'edit_alarm', 'source': 'alarm_modify', 'dest': 'alarm_config'}, {'trigger': 'delete_alarm', 'source': 'alarm_modify', 'dest': 'alarms'}, {'trigger': 'button_back', 'source': 'alarm_config', 'dest': 'alarms'}, {'trigger': 'button_back', 'source': 'stations', 'dest': 'main_menu'}, {'trigger': 'button_back', 'source': 'config', 'dest': 'main_menu'} ] logging.getLogger('transitions').setLevel(logging.ERROR) self.state_machine = Machine(states=states, transitions=transitions, initial='idle', # before_state_change=self.before_state_change, after_state_change=self.after_state_change) def init_models(self): alarms = Alarms() self.model.add_model('alarms', alarms) stations = Stations() self.model.add_model('stations', stations) # self.add_default_stations(stations) def add_default_stations(self, stations): self.add_station(stations, 'NRK P13', 'http://lyd.nrk.no/nrk_radio_p13_mp3_h') self.add_station(stations, 'P5 Hits', 'http://stream.p4.no/p5oslo_mp3_hq') self.add_station(stations, 'P4 Lyden av Norge', 'http://stream.p4.no/p4_mp3_hq') self.add_station(stations, 'P7 Klem', 'http://stream.p4.no/p7_mp3_hq') self.add_station(stations, 'Radio Norge', 'http://tx-bauerno.sharp-stream.com/http_live.php?i=radionorge_no_hq') self.add_station(stations, 'Radio Topp 40', 'http://tx-bauerno.sharp-stream.com/http_live.php?i=top40_no_hq') def add_station(self, stations, name, uri): station = Station() station.init(name, uri) stations.add_station(station) def init_controllers(self): self.controllers['idle'] = IdleController('idle', self.state_machine, self.display, self.model) self.controllers['alarm'] = AlarmController('alarm', self.state_machine, self.display, self.model) self.controllers['main_menu'] = MainMenuController('main_menu', self.state_machine, self.display, self.model) self.controllers['alarms'] = AlarmsController('alarms', self.state_machine, self.display, self.model) self.controllers['stations'] = StationsController('stations', self.state_machine, self.display, self.model) self.controllers['config'] = ConfigController('config', self.state_machine, self.display, self.model) self.controllers['alarm_modify'] = AlarmModifyController('alarm_modify', self.state_machine, self.display, self.model) self.controllers['alarm_config'] = AlarmConfigController('alarm_config', self.state_machine, self.display, self.model) self.controllers['idle'].initialize(self.sound) self.controllers['alarm'].initialize(self.sound) self.controllers['stations'].initialize(self.sound) self.controllers['idle'].activate() def before_state_change(self): # logging.debug('MainApp.before_state_change: state {}'.format(self.state_machine.state)) pass def after_state_change(self): # logging.debug('MainApp.after_state_change: state - {}'.format(self.state_machine.state)) state_name = self.state_machine.state if state_name in self.controllers: controller = self.controllers[state_name] self.event_handler.set_receiver(controller) controller.activate() else: logging.error('unknown state controller - {}'.format(state_name)) def handle_event(self, event): # logging.debug('MainApp.handle_event: event - {}'.format(event)) if event == EventHandler.EVENT_KEY_LEFT: self.state_machine.button_left() elif event == EventHandler.EVENT_KEY_RIGHT: self.state_machine.button_right() elif event == EventHandler.EVENT_KEY_BACK: self.state_machine.button_back() elif event == EventHandler.EVENT_KEY_ENTER: self.state_machine.button_enter() def send_time_signal(self): seconds = time.time() for key in self.controllers: controller = self.controllers[key] controller.time_signal(seconds) def run(self): self.init_models() self.init_state_machine() self.init_controllers() self.event_handler = EventHandler(name='EventHandler', native_mode=self.native_mode) self.event_handler.initialize(self, self.controllers['idle']) self.event_handler.start() while True: # logging.debug('MainApp.run: state - {}'.format(self.state_machine.state)) time.sleep(1) self.send_time_signal()