def __init__(self, app, **kwargs): self.app = app super(Controller, self).__init__(**kwargs) self.controller = Oc( self, searchables=[('upnp:rootdevice', self.on_device), ('schemas-upnp-org:device:', self.on_device)], network='cloud', cloud_user=('@'.join((self.app.cred['xmpp_user'], self.app.cred['xmpp_server'])), self.app.cred['xmpp_pwd']), logger=Logger, uid=self.app.uuid) self.controller.startService() for room, value in self.app.rooms.iteritems(): if room != 'New': self.rooms.update({room: {'devices': [], 'pic': value['pic']}}) for item in self.menu_items: setattr( self, item.lower(), globals()[item](name=item, controller=self.controller, main_ui=self)) self.sm.add_widget(getattr(self, item.lower())) getattr(self, item.lower()).realparent = self self.sm.current = 'Home' self.add_widget(self.sm) self.set_room('Home')
class Controller(BoxLayout): ''' Create a controller that receives a custom widget from the kv lang file. Add an action to be called from the kv lang file. ''' menu_items = ['Home', 'HVAC', 'Shutters', 'MediaPlayer', 'Scenarios'] sm = ScreenManager() ssdp = '' rooms = DictProperty() light_list = ListProperty([]) menu = ObjectProperty() mediaservers = {} activity = StringProperty('Home') devices = DictProperty() current_device = None active_room = StringProperty() def __init__(self, app, **kwargs): self.app = app super(Controller, self).__init__(**kwargs) self.controller = Oc( self, searchables=[('upnp:rootdevice', self.on_device), ('schemas-upnp-org:device:', self.on_device)], network='cloud', cloud_user=('@'.join((self.app.cred['xmpp_user'], self.app.cred['xmpp_server'])), self.app.cred['xmpp_pwd']), logger=Logger, uid=self.app.uuid) self.controller.startService() for room, value in self.app.rooms.iteritems(): if room != 'New': self.rooms.update({room: {'devices': [], 'pic': value['pic']}}) for item in self.menu_items: setattr( self, item.lower(), globals()[item](name=item, controller=self.controller, main_ui=self)) self.sm.add_widget(getattr(self, item.lower())) getattr(self, item.lower()).realparent = self self.sm.current = 'Home' self.add_widget(self.sm) self.set_room('Home') def on_rooms(self, instance, value): self.ids.active_room.values = value def resume(self): self.set_room(self.active_room, force=True) def on_device(self, device): def on_product(product, device, typ): if 'Source' in typ or 'MediaRenderer' in typ: devtype = 'MediaPlayer' elif 'BinaryLight' in typ: devtype = 'Lights' else: Logger.debug('unknown type: %s' % typ) return try: room = product.Room name = device[device.keys()[0]]['name'] if name in self.app.devices: pos = self.app.devices[name]['pos'] else: pos = '50*50' # name = product.Name except AttributeError: Logger.info( 'Device %s does not have room property' % device.keys()[0]) else: device[device.keys()[0]].update({'room': room, 'pos': pos}) self.devices.update(device) if room in self.rooms: self.rooms[room]['devices'].append( {'name': name, 'type': devtype, 'uid': device.keys()[0], 'pos': pos}) else: self.rooms.update( {room: {'devices': [{'name': name, 'type': devtype, 'uid': device.keys()[0], 'pos': pos}], 'pic': 'data/living.png'}}) if room not in self.app.config.sections(): self.app.config.set('New', 'name', room) if name not in self.app.config.sections(): self.app.config.adddefaultsection(name) self.app.config.set(name, 'cat', 'device') self.app.config.set(name, 'name', name) self.app.config.set(name, 'room', room) self.app.config.set(name, 'position', pos) if self.sm.current == 'Home': if room == self.active_room: self.set_room(room) if self.active_room == 'Home': if len(self.home.children) > 0: self.home.children[0].roomlist = self.rooms self.home.children[0].devices = self.devices for name, infos in device.iteritems(): Logger.debug(name) room = False for service in infos['services']: Logger.debug(service) if service == u'urn:av-openhome-org:service:Product:1' or \ service == 'urn:av-openhome-org:service:Product:1': room = True d = self.controller.call(device, service, 'Product') d.addCallback(on_product, device, infos['devtype']) if not room: if name not in self.devices: if 'Source' in infos['devtype']\ or 'MediaRenderer' in infos['devtype']: devtype = 'MediaPlayer' elif 'BinaryLight' in infos['devtype']: devtype = 'Lights' elif 'MediaServer' in infos['devtype']: self.mediaservers.update( {infos['name']: {'uid': name}}) # self.devices.update(device) return else: Logger.debug('unknown type: %s' % infos['devtype']) return if infos['name'] in self.app.devices: room = self.app.devices[infos['name']]['room'] pos = self.app.devices[infos['name']]['pos'] else: room = 'unknown' pos = '50*50' device[device.keys()[0]].update({'room': room, 'pos': pos}) if room in self.rooms: self.rooms[room]['devices'].append( {'name': infos['name'], 'type': devtype, 'uid': name, 'pos': pos}) else: self.rooms.update( {room: {'devices': [{'name': infos['name'], 'type': devtype, 'uid': name, 'pos': pos}], 'pic': 'data/living.png'}}) if room not in self.app.config.sections(): self.app.config.set('New', 'name', room) self.devices.update(device) if self.sm.current == 'Home': if self.active_room == room: self.set_room(room) try: room = device[device.keys()[0]]['room'] pos = device[device.keys()[0]]['pos'] if infos['name'] not in self.app.config.sections(): self.app.config.adddefaultsection(infos['name']) self.app.config.set(infos['name'], 'cat', 'device') self.app.config.set(infos['name'], 'name', infos['name']) self.app.config.set(infos['name'], 'room', room) self.app.config.set(infos['name'], 'position', pos) except KeyError: del self.devices[name] Logger.info('recreate device: %s' % str(device)) self.on_device(device) if self.active_room == 'Home': if len(self.home.children) > 0: self.home.children[0].roomlist = self.rooms self.home.children[0].devices = self.devices def set_room(self, room, force=False): print('room: %s' % room) if room in self.app.rooms: self.home.background = self.app.rooms[room]['pic'] # print(self.app.rooms[room]['pic']) # print(s.ids) if self.active_room == room and not force: print('1') s = self.home.children[0] nids = [] for device in self.rooms[room]['devices']: nids.append(device['uid']) if device['uid'] not in s.ids: if device['type'] == 'Lights': b = LightButton( name=device['name'], size=(self.height / 10, self.height / 10), size_hint=(None, None), play=self.set_light, config=self.app.config) else: b = PlayerButton( name=device['name'], size=(self.height / 10, self.height / 10), size_hint=(None, None), play=self.set_player, config=self.app.config, open=lambda: self.set_device(device)) b.id = device['uid'] b.device = {device['uid']: self.devices[device['uid']]} b.name = device['name'] pos = [float(c) for c in device['pos'].split('*')] # print(s.to_local(*pos)) b.pos = pos # print(pos) s.add_widget(b) s.ids.update({b.id: b}) if 'state' in self.devices[device['uid']]: print('ooo') s.ids[device['uid']].state = self.devices[ device['uid']]['state'] else: print('iiii') if device['type'] == 'Lights': d = self.controller.call( {device['uid']: self.devices[device['uid']]}, 'urn:schemas-upnp-org:service:SwitchPower:1', 'GetTarget') d.addCallback(self.update_light, device['uid']) else: d = self.controller.call( {device['uid']: self.devices[device['uid']]}, 'urn:av-openhome-org:service:Playlist:1', 'TransportState') d.addCallback(self.update_player, device['uid']) if device['type'] == 'Lights': self.controller.subscribe( {device['uid']: self.devices[device['uid']]}, 'urn:schemas-upnp-org:service:SwitchPower:1', 'Status', self.update_light, device['uid']) else: self.controller.subscribe( {device['uid']: self.devices[device['uid']]}, 'urn:av-openhome-org:service:Playlist:1', 'TransportState', self.update_player, device['uid']) if len(s.ids) > len(self.rooms[room]['devices']): for w in s.children: if w.id not in nids: s.remove_widget(w) del(s.ids[w.id]) else: print('2') # s.clear_widgets() self.home.clear_widgets() # s = None self.active_room = room if room == 'Home': s = StartPage( roomlist=self.rooms, do_scroll_x=False) self.sm.current = 'Home' self.home.add_widget(s) return else: s = FloatLayout(id='icons') s.ids = {} self.home.add_widget(s) for device in self.rooms[room]['devices']: if device['type'] == 'Lights': # b = NewLightButton(play=self.set_light) b = LightButton( name=device['name'], size=(self.height / 10, self.height / 10), size_hint=(None, None), play=self.set_light, config=self.app.config) # b.ids.light_name.text = device['name'] else: b = PlayerButton( name=device['name'], size=(self.height / 10, self.height / 10), size_hint=(None, None), play=self.set_player, config=self.app.config, open=lambda: self.set_device(device)) b.id = device['uid'] b.device = {device['uid']: self.devices[device['uid']]} if device['type'] == 'Lights': self.controller.subscribe( b.device, 'urn:schemas-upnp-org:service:SwitchPower:1', 'Status', self.update_light, b.id) else: self.controller.subscribe( b.device, 'urn:av-openhome-org:service:Playlist:1', 'TransportState', self.update_player, b.id) # b.bind(on_press=lambda x: self.set_device(device)) if 'state' in self.devices[b.id]: b.state = self.devices[b.id]['state'] else: print('iiii') if device['type'] == 'Lights': d = self.controller.call( {device['uid']: self.devices[device['uid']]}, 'urn:schemas-upnp-org:service:SwitchPower:1', 'GetTarget') d.addCallback(self.update_light, device['uid']) else: d = self.controller.call( {device['uid']: self.devices[device['uid']]}, 'urn:av-openhome-org:service:Playlist:1', 'TransportState') d.addCallback(self.update_player, device['uid']) pos = [float(c) for c in device['pos'].split('*')] # print(pos) b.pos = pos b.name = device['name'] # print(pos) s.add_widget(b) # print(s.ids) s.ids.update({b.id: b}) sensors = SensorPad(size=((self.width / 7, self.height / 5) if self.width > self.height else (self.width / 3, self.height / 3)), size_hint=(None, None), pos=([self.width * .85, self.height * .7] if self.width > self.height else [self.width * .6, self.height * .7])) sensors.sensors = [FakeSensor('temp', '°C', '32'), FakeSensor('Presence', None, True), FakeSensor('Luminosity', '%', '60'), FakeSensor('Humidity', '%', '40')] s.add_widget(sensors) self.sm.current = 'Home' def update_light(self, new_stat, objid): Logger.debug('Light :%s ----> %s' % (str(objid), str(new_stat))) # state = ('down' if new_stat else 'normal') state = bool(int(new_stat)) if 'state' in self.devices[objid]: self.devices[objid]['state'] = state else: self.devices[objid].update({'state': state}) childs = self.home.children if len(childs) > 0: for child in childs[0].children: if child.id == objid: # child.state = new_stat child.state = state def all_lights_off(self): print("all off") def set_light(self, btn): new = btn.state # new = (btn.state == 'down') self.controller.call( btn.device, 'urn:schemas-upnp-org:service:SwitchPower:1', 'SetTarget', new) def update_player(self, new_stat, objid): Logger.debug('Player :%s ----> %s' % (str(objid), str(new_stat))) state = (True if new_stat == 'Playing' else False) # state = new_stat if 'state' in self.devices[objid]: self.devices[objid]['state'] = state else: self.devices[objid].update({'state': state}) childs = self.home.children if len(childs) > 0: for child in childs[0].children: if child.id == objid: # child.state = new_stat child.state = state def set_player(self, btn): new = btn.state # new = (btn.state == 'down') if new: self.controller.call( btn.device, 'urn:av-openhome-org:service:Playlist:1', 'Play') else: self.controller.call( btn.device, 'urn:av-openhome-org:service:Playlist:1', 'Pause') def set_device(self, device): try: self.sm.current = device['type'] self.controller.current_device = device except: return def remove_device(self, uid): for room, values in self.rooms.iteritems(): for device in values['devices']: if device['uid'] == uid: self.rooms[room]['devices'].remove(device) if len(self.rooms[room]['devices']) > 0: if self.controller.current_device and\ uid == self.controller.current_device['uid']: self.set_room(room) else: del self.rooms[room] self.set_room(self.rooms.keys()[0]) self.ids.active_room.text = self.rooms.keys()[0] # print(self.devices) del self.devices[uid] self.controller.devices.remove(uid) def test(self, x): print(x.text)