def onClickLamp(self): # Ensure leds are enabled if not Hyperion().ledState: Hyperion().setLedState(True) self._btn_br[self._curr_i].setStyleSheet(self._btn_style + self._active_br_color) # Ensure screen capture is off Hyperion().setUsbCaptureState(False) # Toggle mood lamp effect if not Hyperion().moodLamp: Hyperion().setEffect('Mood Lamp', 50, -1) else: Hyperion().clear(50) Hyperion().moodLamp = not Hyperion().moodLamp
def onClickMonitor(self): # Ensure leds are enabled if not Hyperion().ledState: Hyperion().setLedState(True) self._btn_br[self._curr_i].setStyleSheet(self._btn_style + self._active_br_color) # Enable or disable screen capture if not Hyperion().usbState: Hyperion().clear(50) Hyperion().setUsbCaptureState(True) Hyperion().moodLamp = False else: Hyperion().setUsbCaptureState(False)
def createUI(self, path, pos=[0,0]): # Settings window_gap = 25 v_gap = 10 title_h = 25 img_size = [100, 100] img_gap = [25, 25] slider_h = 20 w_size = [ img_size[0] * 3 + window_gap * 2 + img_gap[0] * 2, img_size[1] + window_gap * 3 + v_gap * 5 + slider_h * 2 + title_h * 2 ] # General setup self._path = path self.setGeometry( pos[0] - w_size[0] / 2, pos[1] - w_size[1] / 2, w_size[0], w_size[1] ) y = window_gap # Hyperion Control Title title_stylesheet = "font-size: 18pt;border: 0;" title = QLabel("Hyperion", self) title.setGeometry(window_gap, y, w_size[0] - window_gap * 2, title_h) title.setAlignment(Qt.AlignCenter) title.setStyleSheet(title_stylesheet) title.show() y += title_h + v_gap # Screen Capture Button self._monitor = QPushButton('', self) self._monitor.setIcon(QIcon(path + '/Resources/Hyperion/Monitor.png')) self._monitor.setIconSize(QSize(img_size[0], img_size[1])) self._monitor.setGeometry(window_gap, y, img_size[0], img_size[1]) self._monitor.setStyleSheet('border: none;') self._monitor.clicked.connect(lambda:self.onClickMonitor()) self._monitor.show() # Notifcations Button self._notifications = QPushButton('', self) self._notifications.setIconSize(QSize(img_size[0], img_size[1])) self._notifications.setGeometry(img_size[0] + window_gap + img_gap[0], y, img_size[0], img_size[1]) self._notifications.setStyleSheet('border: none;') self._notifications.clicked.connect(lambda:self.onClickNotifications()) if Hyperion().notifications: self._notifications.setIcon(QIcon(self._path + '/Resources/Hyperion/Bell.png')) else: self._notifications.setIcon(QIcon(self._path + '/Resources/Hyperion/Bell-crossed.png')) self._notifications.show() # Mood Lamp Button self._lamp = QPushButton('', self) self._lamp.setIcon(QIcon(path + '/Resources/Hyperion/Lamp.png')) self._lamp.setIconSize(QSize(img_size[0], img_size[1])) self._lamp.setGeometry(img_size[0] * 2 + window_gap + img_gap[0] * 2, y, img_size[0], img_size[1]) self._lamp.setStyleSheet('border: none;') self._lamp.clicked.connect(lambda:self.onClickLamp()) self._lamp.show() y+= img_size[1] + v_gap # Hyperion Brightness Control sliderStylesheet = ( "QSlider{" "background-color: transparent;" "border-style: outset;" "border-radius: 15px;" "border: transparent;" "}" "QSlider::groove:horizontal{" "height: 24px;" "background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c4c4);" "margin: 2px 0;" "border-radius:10px;" "}" "QSlider::handle:horizontal {" "width: 32px;" "height: 32px;" "margin: -5px 0px -5px 0px;" "border-radius:15px;" "background-color:#0043a1;" "border: 3px solid #0043a1;" "}" ) self.lights_brightness_slider = QSlider(Qt.Horizontal, self) self.lights_brightness_slider.setFocusPolicy(Qt.NoFocus) self.lights_brightness_slider.setTickPosition(QSlider.NoTicks) self.lights_brightness_slider.setGeometry( window_gap, y, w_size[0] - window_gap * 2, window_gap ) self.lights_brightness_slider.setStyleSheet(sliderStylesheet) self.lights_brightness_slider.setMinimum(0); self.lights_brightness_slider.setMaximum(100); self.lights_brightness_slider.valueChanged.connect(self.onClickSetLightsBrightness) self.lights_brightness_slider.setTracking(False) self.lights_brightness_slider.show() y += slider_h + window_gap # Monitor Control Title title_stylesheet = "font-size: 18pt;border: 0;" title = QLabel("Monitor", self) title.setGeometry(window_gap, y, w_size[0] - window_gap * 2, title_h) title.setAlignment(Qt.AlignCenter) title.setStyleSheet(title_stylesheet) title.show() y += title_h + v_gap # Monitor Brightness Control self.monitor_brightness_slider = QSlider(Qt.Horizontal, self) self.monitor_brightness_slider.setFocusPolicy(Qt.NoFocus) self.monitor_brightness_slider.setTickPosition(QSlider.NoTicks) self.monitor_brightness_slider.setGeometry( window_gap, y, w_size[0] - window_gap * 2, window_gap ) self.monitor_brightness_slider.setStyleSheet(sliderStylesheet) self.monitor_brightness_slider.setMinimum(0); self.monitor_brightness_slider.setMaximum(100); self.monitor_brightness_slider.valueChanged.connect(self.onClickSetMonitorBrightness) self.monitor_brightness_slider.setTracking(False) self.monitor_brightness_slider.show()
def onClickNotifications(self): Hyperion().notifications = not Hyperion().notifications if Hyperion().notifications: self._notifications.setIcon(QIcon(self._path + '/Resources/Hyperion/Bell.png')) else: self._notifications.setIcon(QIcon(self._path + '/Resources/Hyperion/Bell-crossed.png'))
def onClickSetLightsBrightness(self): print("Set lights brightness: " + str(self.lights_brightness_slider.value())) Hyperion().setBrightness(self.lights_brightness_slider.value())
def show(self): super().show() self.lights_brightness_slider.setValue(Hyperion().brightness) self.monitor_brightness_slider.setValue(Monitor().brightness)
def prepare(path: str, ui_file: str = None, preloadedSettings=None): # Open settings and ui files if preloadedSettings == None: file = open(path + '/settings.json', 'r') settings = json.loads(file.read()) file.close() else: settings = preloadedSettings if ui_file == None: ui_file = settings['ui'][ 'initial_page'] if 'initial_page' in settings[ 'ui'] else 'ui.json' file = open(path + '/' + ui_file, 'r') ui = json.loads(file.read()) file.close() # Fill in variables in ui file ## UI section pos = ui['ui'][0]['geometry'][0:2].copy() new_pos = pos.copy() for entry in ui['ui']: # Positioning if 'geometry' in entry: update_pos = [True, True] for i in range(2): if isinstance(entry['geometry'][i], str): if entry['geometry'][i][0] != "d": new_pos[i] = pos[i] + int(entry['geometry'][i]) else: update_pos[i] = False if len(entry['geometry'][i]) > 1: new_pos[i] = pos[i] + int( entry['geometry'][i][1:]) else: new_pos[i] = pos[i] else: new_pos[i] = entry['geometry'][i] entry['geometry'][0:2] = new_pos.copy() if update_pos[0]: pos[0] = new_pos[0] if update_pos[1]: pos[1] = new_pos[1] # Fill in variables if entry['type'] == 'StaticLabel': # Check if label message is tied to variable in settings entry['text'] = ConfigurationParser._concatTextWithVariables( entry['text'], settings['ui']['variables']) elif (entry['type'] == 'DynamicLabel' or entry['type'] == 'ProgressBar' or entry['type'] == 'RoundProgressBar' or entry['type'] == 'CornerProgressBar'): # Ensure element has bounds entry (This is optional for DynamicLabel) if 'bounds' in entry['metric']: for i in range(2): entry['metric']['bounds'][ i] = ConfigurationParser._fillFieldFormula( entry['metric']['bounds'][i], settings['ui']['variables']) elif entry['type'] == 'Graph': if 'bounds' in entry['metric']: for i in range(2): # Check if bound is a list (if it is it means we have a dynamic bound with a limit) if isinstance(entry['metric']['bounds'][i], list): entry['metric']['bounds'][i][ 1] = ConfigurationParser._fillFieldFormula( entry['metric']['bounds'][i][1], settings['ui']['variables']) # Check if bound is a formula elif isinstance(entry['metric']['bounds'][i], str): # Ensure we are looking at a formula and not dynamic bound without a limit if entry['metric']['bounds'][i] != 'dynamic': entry['metric']['bounds'][ i] = ConfigurationParser._fillFieldFormula( entry['metric']['bounds'][i], settings['ui']['variables']) ## Unit converters section if 'unit_converters' in ui: for entry in ui['unit_converters']: entry = ui['unit_converters'][entry] entry['divisor'] = ConfigurationParser._fillFieldFormula( entry['divisor'], settings['ui']['variables']) if isinstance(entry['unit'], list): for index in range(len(entry['unit'])): entry['unit'][ index] = ConfigurationParser._concatTextWithVariables( entry['unit'][index], settings['ui']['variables']) else: entry[ 'unit'] = ConfigurationParser._concatTextWithVariables( entry['unit'], settings['ui']['variables']) # Initialization if preloadedSettings == None: if 'additional_metrics' in settings['services']['data_provider']: InternalMetrics().setSettings( settings['services']['data_provider'] ['additional_metrics'], settings['services']['data_provider']['log_n_samples']) RyderClient().setup( settings['services']['data_provider']['ip'], settings['services']['data_provider']['port'], settings['services']['data_provider']['password']) if 'hyperion' in settings['services']: Hyperion().setUrl(settings['services']['hyperion']['ip'], settings['services']['hyperion']['port']) Hyperion().getState() Monitor() return settings['ui']['fps'], ui, settings, ui_file
def update(self, status=None): # Ensure updates are done only if component has been initialized if self._mutexUpdate != None: self._mutexUpdate.acquire() # Process transitioner updates for item in self._live_queue: # Perform update if necessary if not item['transitioner'].isDone(): item['notification'].moveY(item['transitioner'].update()) item['notification'].update() # Process current live notifications i = 0 timeout_frames = (self._min_timeout_frames if (len(self._queue) > 0 and len(self._free_notifications) == 0) else self._max_timeout_frames) while i < len(self._live_queue): item = self._live_queue[i] if item['slot'] != i and item['transitioner'].isDone(): item['transitioner'] = Transitioner( item['notification']._pos[1], self._transition_frames) item['transitioner'].transitionFromStart( -self._ofst, self._transition_frames) item['slot'] = i item['notification']._background.raise_() elif self._timer - item[ 'timeOfCreation'] >= timeout_frames and item[ 'slot'] == 0 and item['transitioner'].isDone(): # Delete notification item['notification'].hide() self._free_notifications.append( self._live_queue.pop(0)['notification']) self._slot = self._slot - 1 continue i = i + 1 # Check if there are new notifications to display while len(self._queue) > 0 and len(self._free_notifications) > 0: slot = self._slot self._slot = self._slot + 1 # Transition from the right side of the screen if slot > 0: self._live_queue[len(self._live_queue) - 1]['notification'].bringToFront() startPosY = self._live_queue[len(self._live_queue) - 1]['notification']._pos[1] delta = self._ofst * slot - startPosY else: startPosY = self._init_pos[1] - self._ofst delta = self._ofst * (slot + 1) notification_t = Transitioner(startPosY, self._transition_frames) notification_t.transitionFromStart(delta, self._transition_frames) # Initialize notification self._mutex.acquire() data = self._queue.pop(0) self._mutex.release() notification = self._free_notifications.pop(0) notification.setText(data[0], data[1], data[2]) notification.move(self._init_pos[0], startPosY) notification.update() notification.show() if slot == 0: notification.bringToFront() # Add to live queue Notification, Notification Transitioner, position in stack, creation time self._live_queue.append({ 'notification': notification, 'transitioner': notification_t, 'slot': slot, 'timeOfCreation': self._timer }) # Hyperion Notification if Hyperion().ledState and Hyperion().notifications: if data[0] == 'Steam' and self._steam_hyperion_effect != False: Hyperion().setEffect(self._steam_hyperion_effect, 1, 0) elif data[ 0] == 'Discord' and self._discord_hyperion_effect != False: Hyperion().setEffect(self._discord_hyperion_effect, 1, 0) self._timer = self._timer + 1 self._mutexUpdate.release()