Exemple #1
0
 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')
Exemple #2
0
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)