fix homeassistant
authormarcelveldt <marcelvanderveldt@MacBook-Silvia.local>
Sat, 12 Oct 2019 17:09:59 +0000 (19:09 +0200)
committermarcelveldt <marcelvanderveldt@MacBook-Silvia.local>
Sat, 12 Oct 2019 17:09:59 +0000 (19:09 +0200)
music_assistant/homeassistant.py
music_assistant/models/player.py
music_assistant/musicproviders/tunein.py
music_assistant/playerproviders/pylms.py

index 9f76f1cec0129eab0fe707601706f0579908f29c..925a7cf961260dffc3231633c26c56b3ccfecbfd 100644 (file)
@@ -77,10 +77,28 @@ class HomeAssistant():
         ''' perform async setup '''
         self.http_session = aiohttp.ClientSession(
                 loop=self.mass.event_loop, connector=aiohttp.TCPConnector(verify_ssl=False))
-        mass.event_loop.create_task(self.__hass_websocket())
+        self.mass.event_loop.create_task(self.__hass_websocket())
         await self.mass.add_event_listener(self.mass_event, "player updated")
-        mass.event_loop.create_task(self.__get_sources())
+        self.mass.event_loop.create_task(self.__get_sources())
 
+    def get_state_sync(self, entity_id, attribute='state', register_listener=None):
+        ''' get state of a hass entity'''
+        if entity_id in self._tracked_states:
+            state_obj = self._tracked_states.get(entity_id)
+            if not state_obj:
+                return None
+        else:
+            if register_listener:
+                # register state listener
+                self._state_listeners.append( (entity_id, register_listener) )
+            return None
+        if attribute == 'state':
+            return state_obj['state']
+        elif not attribute:
+            return state_obj
+        else:
+            return state_obj['attributes'].get(attribute)
+    
     async def get_state(self, entity_id, attribute='state', register_listener=None):
         ''' get state of a hass entity'''
         if entity_id in self._tracked_states:
@@ -111,7 +129,7 @@ class HomeAssistant():
                 self._tracked_states[event_data['entity_id']] = event_data['new_state']
                 for entity_id, handler in self._state_listeners:
                     if entity_id == event_data['entity_id']:
-                        asyncio.create_task(handler())
+                        self.mass.event_loop.create_task(handler())
         elif event_type == 'call_service' and event_data['domain'] == 'media_player':
             await self.__handle_player_command(event_data['service'], event_data['service_data'])
 
@@ -126,32 +144,32 @@ class HomeAssistant():
             if entity_id in self._published_players:
                 # call is for one of our players so handle it
                 player_id = self._published_players[entity_id]
+                player = await self.mass.player.get_player(player_id)
                 if service == 'turn_on':
-                    await self.mass.player.player_command(player_id, 'power', 'on')
+                    await player.power_on()
                 elif service == 'turn_off':
-                    await self.mass.player.player_command(player_id, 'power', 'off')
+                    await player.power_off()
                 elif service == 'toggle':
-                    await self.mass.player.player_command(player_id, 'power', 'toggle')
+                    await player.power_toggle()
                 elif service == 'volume_mute':
-                    args = 'on' if service_data['is_volume_muted'] else 'off'
-                    await self.mass.player.player_command(player_id, 'mute', args)
+                    await player.volume_mute(service_data['is_volume_muted'])
                 elif service == 'volume_up':
-                    await self.mass.player.player_command(player_id, 'volume', 'up')
+                    await player.volume_up()
                 elif service == 'volume_down':
-                    await self.mass.player.player_command(player_id, 'volume', 'down')
+                    await player.volume_down()
                 elif service == 'volume_set':
                     volume_level = service_data['volume_level']*100
-                    await self.mass.player.player_command(player_id, 'volume', volume_level)
+                    await player.volume_set(volume_level)
                 elif service == 'media_play':
-                    await self.mass.player.player_command(player_id, 'play')
+                    await player.play()
                 elif service == 'media_pause':
-                    await self.mass.player.player_command(player_id, 'pause')
+                    await player.pause()
                 elif service == 'media_stop':
-                    await self.mass.player.player_command(player_id, 'stop')
+                    await player.stop()
                 elif service == 'media_next_track':
-                    await self.mass.player.player_command(player_id, 'next')
+                    await player.next()
                 elif service == 'media_play_pause':
-                    await self.mass.player.player_command(player_id, 'pause', 'toggle')
+                    await player.play_pause()
                 elif service == 'play_media':
                     return await self.__handle_play_media(player_id, service_data)
 
index e7d1b3b2cd3a6c23968048c8ba6621754b9b256d..49e0cd758520a601e3c0517a97e9b13b11d2cb8f 100755 (executable)
@@ -178,18 +178,16 @@ class Player():
         ''' [PROTECTED] return power state for this player '''
         # homeassistant integration
         if self.mass.hass and self.settings.get('hass_power_entity') and self.settings.get('hass_power_entity_source'):
-            hass_state = self.mass.bg_executor.submit(asyncio.run, 
-                self.mass.hass.get_state(
+            hass_state = self.mass.hass.get_state_sync(
                     self.settings['hass_power_entity'],
                     attribute='source',
-                    register_listener=self.update())).result()
+                    register_listener=self.update)
             return hass_state == self.settings['hass_power_entity_source']
-        elif self.settings.get('hass_power_entity'):
-            hass_state = self.mass.bg_executor.submit(asyncio.run, 
-                self.mass.hass.get_state(
+        elif self.mass.hass and self.settings.get('hass_power_entity'):
+            hass_state = self.mass.hass.get_state_sync(
                     self.settings['hass_power_entity'],
                     attribute='state',
-                    register_listener=self.update())).result()
+                    register_listener=self.update)
             return hass_state != 'off'
         # mute as power
         elif self.settings.get('mute_as_power'):
@@ -254,11 +252,10 @@ class Player():
             return group_volume
         # handle hass integration
         elif self.mass.hass and self.settings.get('hass_volume_entity'):
-            hass_state = self.mass.bg_executor.submit(asyncio.run, 
-                self.mass.hass.get_state(
+            hass_state = self.mass.hass.get_state_sync(
                     self.settings['hass_volume_entity'],
                     attribute='volume_level',
-                    register_listener=self.update())).result()
+                    register_listener=self.update)
             return int(try_parse_float(hass_state)*100)
         else:
             return self._volume_level
@@ -355,6 +352,13 @@ class Player():
         else:
             return await self.cmd_pause()
     
+    async def play_pause(self):
+        ''' toggle play/pause'''
+        if self.state == PlayerState.Playing:
+            return await self.pause()
+        else:
+            return await self.play()
+    
     async def next(self):
         ''' [PROTECTED] send next command to player '''
         if self.group_parent:
index cd9c7ba195ee504320b1da189f8d8a3d0785fd0b..71a46cce280c9b92262b32807468b51d5b7d1f37 100644 (file)
@@ -42,10 +42,15 @@ class TuneInProvider(MusicProvider):
         self.prov_id = 'tunein'
         self.mass = mass
         self.cache = mass.cache
-        self.http_session = aiohttp.ClientSession(loop=mass.event_loop, connector=aiohttp.TCPConnector(verify_ssl=False))
-        self.throttler = Throttler(rate_limit=1, period=1)
         self._username = username
         self._password = password
+        self.mass.event_loop.create_task(self.setup())
+
+    async def setup(self):
+        ''' perform async setup '''
+        self.http_session = aiohttp.ClientSession(
+                loop=self.mass.event_loop, connector=aiohttp.TCPConnector(verify_ssl=False))
+        self.throttler = Throttler(rate_limit=1, period=1)
 
     async def search(self, searchstring, media_types=List[MediaType], limit=5):
         ''' perform search on the provider '''
index 78ad61a7bd7a7bddbe01814d74dd63ac637f3c59..99cfb5906ba303aa2f531751eaeccda9d8d6c3eb 100644 (file)
@@ -49,7 +49,6 @@ class PyLMSServer(PlayerProvider):
 
      ### Provider specific implementation #####
 
-    
     async def start_discovery(self):
         transport, protocol = await self.mass.event_loop.create_datagram_endpoint(
             lambda: DiscoveryProtocol(self.mass.web._http_port),