From bc4404e9b1793cb5f6dd8506a12bc55e7291a7d5 Mon Sep 17 00:00:00 2001 From: guirem Date: Wed, 29 Jan 2020 15:08:05 +0100 Subject: [PATCH] pylint cleaning --- .flake8 | 4 + .vscode/settings.json | 5 + resources/globals.py | 18 +- resources/googlecast.py | 1940 +++++++++++++++------------- resources/jeedom/jeedom.py | 179 +-- tests/tools/.pylintrc | 4 - tests/tools/.pylintrctest | 6 - tests/tools/lintAllPythonFiles.sh | 4 +- tests/tools/setCustomMDWarnings.sh | 2 - 9 files changed, 1201 insertions(+), 961 deletions(-) create mode 100644 .flake8 create mode 100644 .vscode/settings.json delete mode 100644 tests/tools/.pylintrc delete mode 100644 tests/tools/.pylintrctest delete mode 100644 tests/tools/setCustomMDWarnings.sh diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..de2de86 --- /dev/null +++ b/.flake8 @@ -0,0 +1,4 @@ +[flake8] +per-file-ignores = + resources/googlecast.py: E501 + resources/jeedom/jeedom.py: E501 \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9fadd3a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "python.linting.pylintEnabled": false, + "python.linting.flake8Enabled": true, + "python.linting.enabled": true +} \ No newline at end of file diff --git a/resources/globals.py b/resources/globals.py index 3843435..ba118ee 100644 --- a/resources/globals.py +++ b/resources/globals.py @@ -15,7 +15,8 @@ # import time -import os, os.path +import os +import os.path JEEDOM_COM = '' JEEDOM_WEB = '' @@ -52,7 +53,8 @@ DISCOVERY_FREQUENCY = 14400 # every 4 hours DISCOVERY_LAST = int(time.time()) # when last started -LOSTDEVICE_RESENDNOTIFDELAY = 60*15 # Resent offline msg after 15 minutes +# Resent offline msg after 15 minutes +LOSTDEVICE_RESENDNOTIFDELAY = 60*15 DEFAULT_NOSTATUS = "" DEFAULT_NODISPLAY = "" @@ -67,7 +69,8 @@ tts_engine = 'picotts' tts_cacheenabled = True tts_speed = 1.2 -tts_cachefolderweb = os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'tmp')) +tts_cachefolderweb = os.path.abspath(os.path.join( + os.path.dirname(os.path.dirname(__file__)), 'tmp')) tts_cachefoldertmp = os.path.join('/tmp/jeedom/', 'googlecast_tts') tts_gapi_url = 'https://www.google.com/speech-api/' tts_gapi_key = 'none' @@ -75,12 +78,13 @@ tts_gapi_haskey = False localmedia_folder = 'localmedia' -localmedia_fullpath = os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(__file__)), localmedia_folder)) +localmedia_fullpath = os.path.abspath(os.path.join( + os.path.dirname(os.path.dirname(__file__)), localmedia_folder)) log_level = "info" pidfile = '/tmp/googlecast.pid' apikey = '' callback = '' -daemonname='' -socketport=55012 -sockethost='127.0.0.1' +daemonname = '' +socketport = 55012 +sockethost = '127.0.0.1' diff --git a/resources/googlecast.py b/resources/googlecast.py index c0f41f8..ae7bd8b 100644 --- a/resources/googlecast.py +++ b/resources/googlecast.py @@ -18,7 +18,8 @@ # pylint: disable=W # pylint: disable=E -import os,re +import os +import re import os.path import shutil import logging @@ -36,7 +37,6 @@ import hashlib from gtts import gTTS from gcloudtts import gcloudTTS, gcloudTTSError -import urllib.parse import globals @@ -52,7 +52,8 @@ import pychromecast.pychromecast.controllers.dashcast as dashcast import pychromecast.pychromecast.controllers.spotify as spotify except ImportError: - logging.error("ERROR: One or several pychromecast controllers are not loaded !") + logging.error( + "ERROR: One or several pychromecast controllers are not loaded !") print(traceback.format_exc()) sys.exit(1) pass @@ -82,7 +83,7 @@ pass try: - from jeedom.jeedom import * + from jeedom.jeedom import jeedom_com, jeedom_socket, jeedom_utils except ImportError: print("Error: importing module from jeedom folder") sys.exit(1) @@ -90,24 +91,26 @@ # ------------------------ # class JeedomChromeCast -class JeedomChromeCast : + + +class JeedomChromeCast: def __init__(self, gcast, options=None, scan_mode=False): self.uuid = str(gcast.device.uuid) self.friendly_name = gcast.device.friendly_name self.gcast = gcast - self.previous_status = {"uuid" : self.uuid, "online" : False} + self.previous_status = {"uuid": self.uuid, "online": False} self.now_playing = False self.online = True self.scan_mode = scan_mode self.error_count = 0 - if scan_mode == False : + if scan_mode is False: self.gcast.wait(timeout=globals.SCAN_TIMEOUT) self.being_shutdown = False self.is_recovering = False self.disable_notif = False self.customplayer = None self.customplayername = "" - self.previous_playercmd = {} + self.previous_playercmd = {} self.sessionid_storenext = False self.sessionid_current = '' self.previous_nowplaying = {} @@ -121,15 +124,17 @@ def __init__(self, gcast, options=None, scan_mode=False): self.gcast.register_connection_listener(self) self.options = options # manage CEC exception - if options and 'ignore_CEC' in options : - if options['ignore_CEC'] == "1" and self.friendly_name not in pychromecast.IGNORE_CEC : - pychromecast.IGNORE_CEC.append(self.gcast.device.friendly_name) + if options and 'ignore_CEC' in options: + if options['ignore_CEC'] == "1" and self.friendly_name not in pychromecast.IGNORE_CEC: + pychromecast.IGNORE_CEC.append( + self.gcast.device.friendly_name) # CEC always disable for audio chromecast if self.gcast.device.cast_type != 'cast' and self.friendly_name not in pychromecast.IGNORE_CEC: pychromecast.IGNORE_CEC.append(self.gcast.device.friendly_name) - if self.gcast.socket_client : - self.gcast.socket_client.tries = int(round(globals.SCAN_FREQUENCY)/10/2) + if self.gcast.socket_client: + self.gcast.socket_client.tries = int( + round(globals.SCAN_FREQUENCY)/10/2) self.gcast.socket_client.retry_wait = 5 self.gcast.socket_client.timeout = 5 @@ -139,31 +144,31 @@ def device(self): @property def is_connected(self): - try : - if self.gcast.socket_client is not None or self.gcast.status is not None or self.online==True or self.is_recovering==True : + try: + if self.gcast.socket_client is not None or self.gcast.status is not None or self.online is True or self.is_recovering is True: return True - except Exception : + except Exception: return False @property def is_castgroup(self): - if self.gcast.device.cast_type != 'group' : + if self.gcast.device.cast_type != 'group': return False return True @property def support_video(self): - if self.gcast.device.cast_type == 'cast' : + if self.gcast.device.cast_type == 'cast': return True return False @property def media_current_time(self): ret = 0 - try : + try: ret = self.gcast.media_controller.status.adjusted_current_time ret = 0 if ret is None else float(ret) - except Exception : + except Exception: pass return ret @@ -172,14 +177,17 @@ def reset_exceptioncount(self): def manage_exceptions(self, message_string=''): self.error_count = self.error_count + 1 - if self.error_count >= 3 : - logging.debug("JEEDOMCHROMECAST------ Forced disconnection after 3 exceptions for " + self.uuid) + if self.error_count >= 3: + logging.debug( + "JEEDOMCHROMECAST------ Forced disconnection after 3 exceptions for " + self.uuid) self.disconnect() - elif 'Chromecast is connecting...' in message_string : - logging.debug("JEEDOMCHROMECAST------ Forced disconnection due to connection fatal error for " + self.uuid) + elif 'Chromecast is connecting...' in message_string: + logging.debug( + "JEEDOMCHROMECAST------ Forced disconnection due to connection fatal error for " + self.uuid) self.disconnect() - else : - logging.debug("JEEDOMCHROMECAST------ Managed exception but no forced disconnection for " + self.uuid) + else: + logging.debug( + "JEEDOMCHROMECAST------ Managed exception but no forced disconnection for " + self.uuid) def applaunch_callback_reset(self): self.has_apperror = False @@ -195,37 +203,40 @@ def getCurrentVolume(self): return int(self.gcast.status.volume_level*100) def startNowPlaying(self): - if self.now_playing == False and self.online == True : - logging.debug("JEEDOMCHROMECAST------ Starting monitoring of " + self.uuid) + if self.now_playing is False and self.online is True: + logging.debug( + "JEEDOMCHROMECAST------ Starting monitoring of " + self.uuid) self.now_playing = True self.sendNowPlaying(force=True) def stopNowPlaying(self): - logging.debug("JEEDOMCHROMECAST------ Stopping monitoring of " + self.uuid) + logging.debug( + "JEEDOMCHROMECAST------ Stopping monitoring of " + self.uuid) self.now_playing = False def new_cast_status(self, new_status): - #logging.debug("JEEDOMCHROMECAST------ Status " + str(new_status)) + # logging.debug("JEEDOMCHROMECAST------ Status " + str(new_status)) self._manage_previous_status(new_status) - if not self.disable_notif : + if not self.disable_notif: self._internal_refresh_status(False) self.sendNowPlaying(force=True) def new_media_status(self, new_mediastatus): - #logging.debug("JEEDOMCHROMECAST------ New media status " + str(new_mediastatus)) - if new_mediastatus.player_state!="BUFFERING" and not self.disable_notif : - if not globals.disable_mediastatus : + # logging.debug("JEEDOMCHROMECAST------ New media status " + str(new_mediastatus)) + if new_mediastatus.player_state != "BUFFERING" and not self.disable_notif: + if not globals.disable_mediastatus: self._internal_send_now_playing_statusupdate(new_mediastatus) - if self.now_playing==True : + if self.now_playing is True: self._internal_send_now_playing() def new_launch_error(self, launch_failure): - logging.debug("JEEDOMCHROMECAST------ New launch error " + str(launch_failure)) - if launch_failure.reason=="CANCELLED" : - #self.manage_exceptions('Launch error : CANCELLED') - try : + logging.debug( + "JEEDOMCHROMECAST------ New launch error " + str(launch_failure)) + if launch_failure.reason == "CANCELLED": + # self.manage_exceptions('Launch error : CANCELLED') + try: self.gcast.quit_app() - except Exception : + except Exception: self.manage_exceptions('Launch error : CANCELLED') pass self.has_apperror = True @@ -234,41 +245,45 @@ def new_launch_error(self, launch_failure): def new_connection_status(self, new_status): # CONNECTING / CONNECTED / DISCONNECTED / FAILED / LOST - logging.debug("JEEDOMCHROMECAST------ Connexion change event " + str(new_status.status)) + logging.debug( + "JEEDOMCHROMECAST------ Connexion change event " + str(new_status.status)) self.online = False - if new_status.status == "DISCONNECTED" and self.being_shutdown==False: + if new_status.status == "DISCONNECTED" and self.being_shutdown is False: self.disconnect() - logging.info("JEEDOMCHROMECAST------ Chromecast has beend disconnected : " + self.friendly_name) - if new_status.status == "LOST" : + logging.info( + "JEEDOMCHROMECAST------ Chromecast has beend disconnected : " + self.friendly_name) + if new_status.status == "LOST": self.is_recovering = True self._internal_refresh_status(True) - if new_status.status == "CONNECTING" or new_status.status == "FAILED" : + if new_status.status == "CONNECTING" or new_status.status == "FAILED": self.is_recovering = True - if new_status.status == "CONNECTED" : # is reborn... + if new_status.status == "CONNECTED": # is reborn... self.online = True self.error_count = 0 self.is_recovering = False - if self.uuid not in globals.GCAST_DEVICES : + if self.uuid not in globals.GCAST_DEVICES: globals.GCAST_DEVICES[self.uuid] = self self._internal_refresh_status(True) - if self.now_playing == True : + if self.now_playing is True: self._internal_trigger_now_playing_update() def _manage_previous_status(self, new_status): - #logging.debug("JEEDOMCHROMECAST------ Manage previous status " + str(new_status)) - if self.sessionid_storenext and new_status.session_id is not None : + # logging.debug("JEEDOMCHROMECAST------ Manage previous status " + str(new_status)) + if self.sessionid_storenext and new_status.session_id is not None: self.sessionid_current = new_status.session_id self.sessionid_storenext = False appid = new_status.app_id - if appid is not None and new_status.status_text not in ['Casting: TTS', 'Default Media Receiver'] and self.sessionid_current != new_status.session_id : + if appid is not None and new_status.status_text not in ['Casting: TTS', 'Default Media Receiver'] and self.sessionid_current != new_status.session_id: self.previous_playercmd = {} - logging.debug("JEEDOMCHROMECAST------ Manage previous status : Removing previous playercmd!") + logging.debug( + "JEEDOMCHROMECAST------ Manage previous status : Removing previous playercmd!") def savePreviousPlayerCmd(self, params): - #logging.debug("JEEDOMCHROMECAST------ Manage previous player cmd " + str(params)) + # logging.debug("JEEDOMCHROMECAST------ Manage previous player cmd " + str(params)) self.previous_playercmd['params'] = params self.previous_playercmd['time'] = int(time.time()) - self.previous_playercmd['appid'] = self.getAppId(params['app'] if 'app' in params else None) + self.previous_playercmd['appid'] = self.getAppId( + params['app'] if 'app' in params else None) self.previous_playercmd['appname'] = params['app'] if 'app' in params else None self.sessionid_storenext = True self.previous_usewarmup = False @@ -280,82 +295,85 @@ def resetPreviousPlayerCmd(self): self.sessionid_current = '' def getPreviousPlayerCmd(self, forceapplaunch=False, notifMode=True): - logging.debug("JEEDOMCHROMECAST------ getPreviousPlayerCmd " + str(self.previous_playercmd)) + logging.debug( + "JEEDOMCHROMECAST------ getPreviousPlayerCmd " + str(self.previous_playercmd)) ret = None - beforeTTSappid = (self.previous_playercmd['current_appid'] if 'current_appid' in self.previous_playercmd else None) - if 'params' in self.previous_playercmd : - if self.previous_playercmd['appid']==beforeTTSappid or notifMode==False : + beforeTTSappid = (self.previous_playercmd['current_appid'] + if 'current_appid' in self.previous_playercmd else None) + if 'params' in self.previous_playercmd: + if self.previous_playercmd['appid'] == beforeTTSappid or notifMode is False: self.previous_playercmd['params'] - if 'current_time' in self.previous_playercmd and self.previous_playercmd['current_time'] > 0 : - if 'current_stream_type' in self.previous_playercmd and self.previous_playercmd['current_stream_type'] != 'LIVE' : + if 'current_time' in self.previous_playercmd and self.previous_playercmd['current_time'] > 0: + if 'current_stream_type' in self.previous_playercmd and self.previous_playercmd['current_stream_type'] != 'LIVE': self.previous_playercmd['params']['offset'] = self.previous_playercmd['current_time'] - if 'live' in self.previous_playercmd['params'] : + if 'live' in self.previous_playercmd['params']: self.previous_playercmd['params']['offset'] = 0 - playerstate = self.previous_playercmd['current_player_state'] if 'current_player_state' in self.previous_playercmd else 'PLAYING' - if playerstate == 'PAUSED' : - ret = [self.previous_playercmd['params'], {'cmd':'pause'}] - elif playerstate == 'IDLE' : - ret = [self.previous_playercmd['params'], {'cmd':'stop'}] - else : - ret = [self.previous_playercmd['params'], {'cmd':'play'}] - - elif beforeTTSappid is not None and forceapplaunch : - ret = {'cmd': 'start_app', 'appid' : beforeTTSappid} + playerstate = self.previous_playercmd[ + 'current_player_state'] if 'current_player_state' in self.previous_playercmd else 'PLAYING' + if playerstate == 'PAUSED': + ret = [self.previous_playercmd['params'], {'cmd': 'pause'}] + elif playerstate == 'IDLE': + ret = [self.previous_playercmd['params'], {'cmd': 'stop'}] + else: + ret = [self.previous_playercmd['params'], {'cmd': 'play'}] + + elif beforeTTSappid is not None and forceapplaunch: + ret = {'cmd': 'start_app', 'appid': beforeTTSappid} return ret def prepareTTSplay(self): retval = 0 - if self.previous_usewarmup == False : - try : + if self.previous_usewarmup is False: + try: self.previous_playercmd['current_appid'] = self.gcast.status.app_id self.previous_playercmd['current_sessionid'] = self.gcast.status.session_id self.previous_playercmd['current_player_state'] = self.gcast.media_controller.status.player_state self.previous_playercmd['current_stream_type'] = self.gcast.media_controller.status.stream_type retval = self.media_current_time - except Exception : + except Exception: pass self.previous_playercmd['current_time'] = retval - else : + else: self.previous_usewarmup = False return retval def prepareForceResume(self, player_state, current_time): - if player_state is not None : + if player_state is not None: self.previous_playercmd['current_player_state'] = player_state - if current_time is not None : + if current_time is not None: self.previous_playercmd['current_time'] = current_time def prepareWarumplay(self): retval = 0 - try : + try: self.previous_usewarmup = True self.previous_playercmd['current_appid'] = self.gcast.status.app_id self.previous_playercmd['current_sessionid'] = self.gcast.status.session_id self.previous_playercmd['current_player_state'] = self.gcast.media_controller.status.player_state self.previous_playercmd['current_stream_type'] = self.gcast.media_controller.status.stream_type retval = self.media_current_time - except Exception : + except Exception: pass self.previous_playercmd['current_time'] = retval return retval def getAppId(self, appname): retval = None - if appname=='plex' : + if appname == 'plex': retval = '9AC194DC' - elif appname=='media' : - retval = 'CC1AD845'; - elif appname=='backdrop' : - retval = 'E8C28D3C'; - elif appname=='web' : - retval = '84912283'; + elif appname == 'media': + retval = 'CC1AD845' + elif appname == 'backdrop': + retval = 'E8C28D3C' + elif appname == 'web': + retval = '84912283' return retval def sendDeviceStatus(self, _force=True): - try : + try: self.gcast.media_controller.update_status() time.sleep(0.2) - except Exception : + except Exception: pass self._internal_refresh_status(_force) @@ -363,274 +381,288 @@ def sendDeviceStatusIfNew(self): self.sendDeviceStatus(False) def disconnect(self): - if self.scan_mode==False : + if self.scan_mode is False: self.is_recovering = False self.being_shutdown = True self._internal_refresh_status(True) - if self.now_playing == True : + if self.now_playing is True: self._internal_send_now_playing() self.now_playing = False - if self.uuid in globals.GCAST_DEVICES : + if self.uuid in globals.GCAST_DEVICES: del globals.GCAST_DEVICES[self.uuid] - logging.debug("JEEDOMCHROMECAST------ Chromecast disconnected : " + self.friendly_name) - try : + logging.debug( + "JEEDOMCHROMECAST------ Chromecast disconnected : " + self.friendly_name) + try: self.gcast.disconnect() - except Exception : + except Exception: pass self.free_memory() def free_memory(self): - try : + try: self.gcast.socket_client.socket.shutdown(socket.SHUT_RDWR) self.gcast.socket_client.socket.close() del self.gcast - except Exception : + except Exception: pass del self - def loadPlayer(self, playername, params=None) : - if self.gcast.socket_client : + def loadPlayer(self, playername, params=None): + if self.gcast.socket_client: forceReload = False - if params and 'forcereload' in params : + if params and 'forcereload' in params: forceReload = True - if not self.customplayer or self.customplayername != playername or forceReload==True : + if not self.customplayer or self.customplayername != playername or forceReload is True: try: - if playername == 'web' : + if playername == 'web': player = dashcast.DashCastController() self.gcast.register_handler(player) - elif playername == 'youtube' : + elif playername == 'youtube': player = youtube.YouTubeController() self.gcast.register_handler(player) time.sleep(5) - elif playername == 'spotify' : + elif playername == 'spotify': player = spotify.SpotifyController() self.gcast.register_handler(player) time.sleep(2) - elif playername == 'plex' : + elif playername == 'plex': player = plex.PlexController() self.gcast.register_handler(player) time.sleep(2) - else : + else: player = self.gcast.media_controller - logging.debug("JEEDOMCHROMECAST------ Initiating player " + str(player.namespace)) + logging.debug( + "JEEDOMCHROMECAST------ Initiating player " + str(player.namespace)) self.customplayer = player self.customplayername = playername - if params and 'waitbeforequit' in params : + if params and 'waitbeforequit' in params: time.sleep(params['waitbeforequit']) - if params and 'quitapp' in params : + if params and 'quitapp' in params: self.gcast.quit_app() - if params and 'wait' in params : + if params and 'wait' in params: time.sleep(params['wait']) except Exception as e: - logging.error("JEEDOMCHROMECAST------ Error while initiating player " +playername+ " on low level commands : %s" % str(e)) + logging.error("JEEDOMCHROMECAST------ Error while initiating player " + + playername + " on low level commands : %s" % str(e)) logging.debug(traceback.format_exc()) player = None pass - #else: + # else: # time.sleep(0.2) - if not self.disable_notif : + if not self.disable_notif: self.sendNowPlaying(force=True) return self.customplayer return None - def resetPlayer(self) : + def resetPlayer(self): self.resetPreviousPlayerCmd() - if self.customplayer is not None and self.customplayername != 'media' : - if self.gcast.socket_client and self.customplayer.namespace in self.gcast.socket_client._handlers : + if self.customplayer is not None and self.customplayername != 'media': + if self.gcast.socket_client and self.customplayer.namespace in self.gcast.socket_client._handlers: del self.gcast.socket_client._handlers[self.customplayer.namespace] self.customplayer = None self.sendNowPlaying(force=True) - def _internal_refresh_status(self,_force = False): + def _internal_refresh_status(self, _force=False): uuid = self.uuid status = self._internal_get_status() - if _force or self._internal_status_different(status) : - logging.debug("JEEDOMCHROMECAST------ Detected changes in status of " +self.device.friendly_name) + if _force or self._internal_status_different(status): + logging.debug( + "JEEDOMCHROMECAST------ Detected changes in status of " + self.device.friendly_name) globals.KNOWN_DEVICES[uuid]['status'] = status self.previous_status = status globals.KNOWN_DEVICES[uuid]['online'] = self.online - if self.online == False : - globals.KNOWN_DEVICES[uuid]['lastOfflineSent'] = int(time.time()) - globals.JEEDOM_COM.add_changes('devices::'+uuid,globals.KNOWN_DEVICES[uuid]) + if self.online is False: + globals.KNOWN_DEVICES[uuid]['lastOfflineSent'] = int( + time.time()) + globals.JEEDOM_COM.add_changes( + 'devices::'+uuid, globals.KNOWN_DEVICES[uuid]) globals.KNOWN_DEVICES[uuid]['lastSent'] = int(time.time()) - def _internal_get_status(self): - if self.gcast.status is not None and self.online == True: + if self.gcast.status is not None and self.online is True: uuid = self.uuid playStatus = self.gcast.media_controller.status status = { - "uuid" : uuid, "uri" : self.gcast.uri, "friendly_name" : self.gcast.device.friendly_name, - "friendly_name" : self.gcast.device.friendly_name, - "is_active_input" : True if self.gcast.status.is_active_input else False, - "is_stand_by" : True if self.gcast.status.is_stand_by else False, - "volume_level" : int(self.gcast.status.volume_level*100), - "volume_muted" : self.gcast.status.volume_muted, - "app_id" : self.gcast.status.app_id, - "icon_url" : self.gcast.status.icon_url, - "display_name" : self.gcast.status.display_name if self.gcast.status.display_name is not None else globals.DEFAULT_NODISPLAY, - "status_text" : self.gcast.status.status_text if self.gcast.status.status_text!="" else globals.DEFAULT_NOSTATUS, - "is_busy" : not self.gcast.is_idle, - "title" : "" if playStatus.title is None else playStatus.title, - "artist" : "" if playStatus.artist is None else playStatus.artist, + "uuid": uuid, "uri": self.gcast.uri, + "friendly_name": self.gcast.device.friendly_name, + "is_active_input": True if self.gcast.status.is_active_input else False, + "is_stand_by": True if self.gcast.status.is_stand_by else False, + "volume_level": int(self.gcast.status.volume_level*100), + "volume_muted": self.gcast.status.volume_muted, + "app_id": self.gcast.status.app_id, + "icon_url": self.gcast.status.icon_url, + "display_name": self.gcast.status.display_name if self.gcast.status.display_name is not None else globals.DEFAULT_NODISPLAY, + "status_text": self.gcast.status.status_text if self.gcast.status.status_text != "" else globals.DEFAULT_NOSTATUS, + "is_busy": not self.gcast.is_idle, + "title": "" if playStatus.title is None else playStatus.title, + "artist": "" if playStatus.artist is None else playStatus.artist, "series_title": "" if playStatus.series_title is None else playStatus.series_title, - "stream_type" : "" if playStatus.stream_type is None else playStatus.stream_type, - "player_state" : "" if playStatus.player_state is None else playStatus.player_state, + "stream_type": "" if playStatus.stream_type is None else playStatus.stream_type, + "player_state": "" if playStatus.player_state is None else playStatus.player_state, } return status - else : + else: return { - "uuid" : self.uuid, - "is_stand_by" : False, "is_active_input" : False, - "display_name" : globals.DEFAULT_NODISPLAY, "status_text" : globals.DEFAULT_NOSTATUS, - "app_id" : "", "icon_url" : "", "is_busy" : False, - "title" : "", "artist" : "", 'series_title': "", "stream_type" : "", "player_state" : "", + "uuid": self.uuid, + "is_stand_by": False, "is_active_input": False, + "display_name": globals.DEFAULT_NODISPLAY, "status_text": globals.DEFAULT_NOSTATUS, + "app_id": "", "icon_url": "", "is_busy": False, + "title": "", "artist": "", 'series_title': "", "stream_type": "", "player_state": "", } - def _internal_status_different(self, new_status): prev_status = self.previous_status - if len(prev_status) != len(new_status) or len(prev_status)==2 or 'volume_level' not in new_status : + if len(prev_status) != len(new_status) or len(prev_status) == 2 or 'volume_level' not in new_status: return True - if prev_status['status_text'] != new_status['status_text'] : + if prev_status['status_text'] != new_status['status_text']: return True - if prev_status['volume_level'] != new_status['volume_level'] : + if prev_status['volume_level'] != new_status['volume_level']: return True - if prev_status['is_busy'] != new_status['is_busy'] : + if prev_status['is_busy'] != new_status['is_busy']: return True - if prev_status['volume_muted'] != new_status['volume_muted'] : + if prev_status['volume_muted'] != new_status['volume_muted']: return True - if prev_status['is_stand_by'] != new_status['is_stand_by'] : + if prev_status['is_stand_by'] != new_status['is_stand_by']: return True - if prev_status['app_id'] != new_status['app_id'] : + if prev_status['app_id'] != new_status['app_id']: return True - if prev_status['player_state'] != new_status['player_state'] : + if prev_status['player_state'] != new_status['player_state']: return True return False def _internal_send_now_playing_statusupdate(self, new_nowplaying): prev_nowplaying = self.previous_nowplaying test_dif = False - if 'title' not in prev_nowplaying : + if 'title' not in prev_nowplaying: test_dif = True - elif prev_nowplaying['title'] != new_nowplaying.title : + elif prev_nowplaying['title'] != new_nowplaying.title: test_dif = True - elif prev_nowplaying['player_state'] != new_nowplaying.player_state and new_nowplaying.player_state!=['UNKNOWN'] : + elif prev_nowplaying['player_state'] != new_nowplaying.player_state and new_nowplaying.player_state != ['UNKNOWN']: test_dif = True - if test_dif==True : + if test_dif is True: mediastatus = { - "uuid" : self.uuid, - "title" : '' if new_nowplaying.title is None else new_nowplaying.title, - "artist" : '' if new_nowplaying.artist is None else new_nowplaying.artist, + "uuid": self.uuid, + "title": '' if new_nowplaying.title is None else new_nowplaying.title, + "artist": '' if new_nowplaying.artist is None else new_nowplaying.artist, "series_title": '' if new_nowplaying.series_title is None else new_nowplaying.series_title, - "player_state" : '' if new_nowplaying.player_state is None else new_nowplaying.player_state, + "player_state": '' if new_nowplaying.player_state is None else new_nowplaying.player_state, } - logging.debug("JEEDOMCHROMECAST------ NOW PLAYING STATUS SEND " + str(mediastatus)) + logging.debug( + "JEEDOMCHROMECAST------ NOW PLAYING STATUS SEND " + str(mediastatus)) self.previous_nowplaying = mediastatus - globals.JEEDOM_COM.add_changes('devices::'+self.uuid, {'uuid': self.uuid, 'typemsg': 'info', 'status': mediastatus}) + globals.JEEDOM_COM.add_changes( + 'devices::'+self.uuid, {'uuid': self.uuid, 'typemsg': 'info', 'status': mediastatus}) def getDefinition(self): status = { - "friendly_name" : self.gcast.device.friendly_name, - "model_name" : self.gcast.device.model_name, - "manufacturer" : self.gcast.device.manufacturer, - "cast_type" : self.gcast.device.cast_type, - "uri" : self.gcast.uri + "friendly_name": self.gcast.device.friendly_name, + "model_name": self.gcast.device.model_name, + "manufacturer": self.gcast.device.manufacturer, + "cast_type": self.gcast.device.cast_type, + "uri": self.gcast.uri } return status def getStatus(self): return self._internal_get_status() - def _internal_trigger_now_playing_update(self) : - try : + def _internal_trigger_now_playing_update(self): + try: self.gcast.media_controller.update_status() - except Exception : + except Exception: pass def sendNowPlaying(self, force=False): - if force==True : + if force is True: self._internal_send_now_playing() - elif self.now_playing==True: - logging.debug("JEEDOMCHROMECAST------ NOW PLAYING " + self.uuid + " in seconds : " + str(int(time.time())-self.nowplaying_lastupdated)) - if (int(time.time())-self.nowplaying_lastupdated)>=globals.NOWPLAYING_FREQUENCY : + elif self.now_playing is True: + logging.debug("JEEDOMCHROMECAST------ NOW PLAYING " + self.uuid + + " in seconds : " + str(int(time.time())-self.nowplaying_lastupdated)) + if (int(time.time())-self.nowplaying_lastupdated) >= globals.NOWPLAYING_FREQUENCY: self._internal_trigger_now_playing_update() def sendNowPlaying_heartbeat(self): - if self.now_playing==True: - if (int(datetime.utcnow().timestamp())-self.nowplaying_lastupdated)>=globals.NOWPLAYING_FREQUENCY : - logging.debug("JEEDOMCHROMECAST------ NOW PLAYING heartbeat for " + self.uuid + " in seconds : " + str(int(datetime.utcnow().timestamp())-self.nowplaying_lastupdated)) + if self.now_playing is True: + if (int(datetime.utcnow().timestamp())-self.nowplaying_lastupdated) >= globals.NOWPLAYING_FREQUENCY: + logging.debug("JEEDOMCHROMECAST------ NOW PLAYING heartbeat for " + self.uuid + + " in seconds : " + str(int(datetime.utcnow().timestamp())-self.nowplaying_lastupdated)) self._internal_trigger_now_playing_update() - if (int(datetime.utcnow().timestamp())-self.nowplaying_lastupdated)>=globals.NOWPLAYING_FREQUENCY_MAX : - logging.debug("JEEDOMCHROMECAST------ NOW PLAYING heartbeat for " + self.uuid + " : force to resend data after " + str(globals.NOWPLAYING_FREQUENCY_MAX) + " seconds") + if (int(datetime.utcnow().timestamp())-self.nowplaying_lastupdated) >= globals.NOWPLAYING_FREQUENCY_MAX: + logging.debug("JEEDOMCHROMECAST------ NOW PLAYING heartbeat for " + self.uuid + + " : force to resend data after " + str(globals.NOWPLAYING_FREQUENCY_MAX) + " seconds") self._internal_send_now_playing() def _internal_send_now_playing(self): uuid = self.uuid - if self.gcast.status and self.online == True : + if self.gcast.status and self.online is True: playStatus = self.gcast.media_controller.status if self.gcast.media_controller.status.last_updated: - self.nowplaying_lastupdated = int(self.gcast.media_controller.status.last_updated.timestamp()) + self.nowplaying_lastupdated = int( + self.gcast.media_controller.status.last_updated.timestamp()) else: self.nowplaying_lastupdated = int(time.time()) - if len(playStatus.images) > 0 : + if len(playStatus.images) > 0: img = str(playStatus.images[0].url) else: img = None data = { - "uuid" : uuid, - "online" : True, - "friendly_name" : self.gcast.device.friendly_name, - "is_active_input" : True if self.gcast.status.is_active_input else False, - "is_stand_by" : True if self.gcast.status.is_stand_by else False, - "volume_level" : int(self.gcast.status.volume_level*100), #"{0:.2f}".format(cast.status.volume_level), - "volume_muted" : self.gcast.status.volume_muted, - "app_id" : self.gcast.status.app_id, - "icon_url" : self.gcast.status.icon_url, - "display_name" : self.gcast.status.display_name if self.gcast.status.display_name is not None else globals.DEFAULT_NODISPLAY, - "status_text" : self.gcast.status.status_text if self.gcast.status.status_text!="" else globals.DEFAULT_NOSTATUS, - "is_busy" : not self.gcast.is_idle, - "title" : playStatus.title, - "album_artist" : playStatus.album_artist, - "metadata_type" : playStatus.metadata_type, - "album_name" : playStatus.album_name, - #"current_time" : '{0:.0f}'.format(playStatus.current_time), - "current_time" : '{0:.0f}'.format(playStatus.adjusted_current_time), - "artist" : playStatus.artist, + "uuid": uuid, + "online": True, + "friendly_name": self.gcast.device.friendly_name, + "is_active_input": True if self.gcast.status.is_active_input else False, + "is_stand_by": True if self.gcast.status.is_stand_by else False, + # "{0:.2f}".format(cast.status.volume_level), + "volume_level": int(self.gcast.status.volume_level*100), + "volume_muted": self.gcast.status.volume_muted, + "app_id": self.gcast.status.app_id, + "icon_url": self.gcast.status.icon_url, + "display_name": self.gcast.status.display_name if self.gcast.status.display_name is not None else globals.DEFAULT_NODISPLAY, + "status_text": self.gcast.status.status_text if self.gcast.status.status_text != "" else globals.DEFAULT_NOSTATUS, + "is_busy": not self.gcast.is_idle, + "title": playStatus.title, + "album_artist": playStatus.album_artist, + "metadata_type": playStatus.metadata_type, + "album_name": playStatus.album_name, + # "current_time" : '{0:.0f}'.format(playStatus.current_time), + "current_time": '{0:.0f}'.format(playStatus.adjusted_current_time), + "artist": playStatus.artist, 'series_title': playStatus.series_title, 'season': playStatus.season, 'episode': playStatus.episode, - "image" : img, - "stream_type" : playStatus.stream_type, - "track" : playStatus.track, - "player_state" : playStatus.player_state, - "supported_media_commands" : playStatus.supported_media_commands, - "supports_pause" : playStatus.supports_pause, - "duration": playStatus.duration, #'{0:.0f}'.format(playStatus.duration), + "image": img, + "stream_type": playStatus.stream_type, + "track": playStatus.track, + "player_state": playStatus.player_state, + "supported_media_commands": playStatus.supported_media_commands, + "supports_pause": playStatus.supports_pause, + # '{0:.0f}'.format(playStatus.duration), + "duration": playStatus.duration, "content_type": playStatus.content_type, "idle_reason": playStatus.idle_reason } - globals.JEEDOM_COM.send_change_immediate({'uuid' : uuid, 'nowplaying':data}); - else : + globals.JEEDOM_COM.send_change_immediate( + {'uuid': uuid, 'nowplaying': data}) + else: data = { - "uuid" : uuid, - "online" : False, "friendly_name" : "", - "is_active_input" : False, "is_stand_by" : False, - "app_id" : "", "icon_url" : "", - "display_name" : globals.DEFAULT_NODISPLAY, - "status_text" : globals.DEFAULT_NOSTATUS, - "is_busy" : False, "title" : "", - "album_artist" : "","metadata_type" : "", - "album_name" : "", "current_time" : 0, - "artist" : "", "image" : None, + "uuid": uuid, + "online": False, "friendly_name": "", + "is_active_input": False, "is_stand_by": False, + "app_id": "", "icon_url": "", + "display_name": globals.DEFAULT_NODISPLAY, + "status_text": globals.DEFAULT_NOSTATUS, + "is_busy": False, "title": "", + "album_artist": "", "metadata_type": "", + "album_name": "", "current_time": 0, + "artist": "", "image": None, "series_title": "", "season": "", "episode": "", - "stream_type" : "", "track" : "", - "player_state" : "", "supported_media_commands" : 0, - "supports_pause" : "", "duration": 0, + "stream_type": "", "track": "", + "player_state": "", "supported_media_commands": 0, + "supports_pause": "", "duration": 0, 'content_type': "", "idle_reason": "" } - globals.JEEDOM_COM.send_change_immediate({'uuid' : uuid, 'nowplaying':data}); + globals.JEEDOM_COM.send_change_immediate( + {'uuid': uuid, 'nowplaying': data}) # ------------------------------- @@ -642,866 +674,955 @@ def action_handler(message): srcuuid = uuid if uuid in globals.KNOWN_DEVICES and uuid in globals.GCAST_DEVICES and rootcmd == "action": - hascallback=False - callback='' - if 'callback' in message['device'] : - hascallback=message['device']['callback'] if True is not None else False - callback=message['device']['callback'] if message['device']['callback'] is not None else '' + hascallback = False + callback = '' + if 'callback' in message['device']: + hascallback = message['device']['callback'] if True is not None else False + callback = message['device']['callback'] if message['device']['callback'] is not None else '' - source='' - if 'source' in message['device'] : - source=message['device']['source'] + source = '' + if 'source' in message['device']: + source = message['device']['source'] commandlist = message['command'] - if not isinstance(commandlist, list) : + if not isinstance(commandlist, list): commandlist = [commandlist] - for command in commandlist : + for command in commandlist: uuid = srcuuid - if 'broadcast' in command : + if 'broadcast' in command: broadcastList = command['broadcast'] - if broadcastList == 'all' : + if broadcastList == 'all': uuidlist = [] - for broadcastuuid in globals.GCAST_DEVICES : - if not globals.GCAST_DEVICES[broadcastuuid].is_castgroup : + for broadcastuuid in globals.GCAST_DEVICES: + if not globals.GCAST_DEVICES[broadcastuuid].is_castgroup: uuidlist.append(broadcastuuid) - else : + else: uuidlist = broadcastList.split(',') - for newUuid in uuidlist : + for newUuid in uuidlist: newcmd = command.copy() del newcmd['broadcast'] newMessage = { - 'cmd' : 'action', - 'delegated' : True, - 'device' : {'uuid' : newUuid, 'source' : message['device']['source'] }, - 'command' : newcmd + 'cmd': 'action', + 'delegated': True, + 'device': {'uuid': newUuid, 'source': message['device']['source']}, + 'command': newcmd } - logging.debug("ACTION------DELEGATED command to other uuid : " + newUuid) - thread.start_new_thread( action_handler, (newMessage,)) + logging.debug( + "ACTION------DELEGATED command to other uuid : " + newUuid) + thread.start_new_thread(action_handler, (newMessage,)) continue - if 'uuid' in command : + if 'uuid' in command: if 'nothread' in command and command['uuid'] in globals.GCAST_DEVICES: uuid = command['uuid'] - logging.debug("ACTION------Changing uuid to run in sequence in this tread : " + uuid) - else : + logging.debug( + "ACTION------Changing uuid to run in sequence in this tread : " + uuid) + else: newUuid = command['uuid'] del command['uuid'] newMessage = { - 'cmd' : 'action', - 'delegated' : True, - 'device' : {'uuid' : newUuid, 'source' : message['device']['source'] }, - 'command' : command + 'cmd': 'action', + 'delegated': True, + 'device': {'uuid': newUuid, 'source': message['device']['source']}, + 'command': command } - logging.debug("ACTION------DELEGATED command to other uuid : " + newUuid) - thread.start_new_thread( action_handler, (newMessage,)) + logging.debug( + "ACTION------DELEGATED command to other uuid : " + newUuid) + thread.start_new_thread(action_handler, (newMessage,)) continue - if 'storecmd' in command : + if 'storecmd' in command: storecmd = command.copy() del storecmd['storecmd'] jcast = globals.GCAST_DEVICES[uuid] - if jcast.is_castgroup == False : - if 'app' in command and command['app'] in ['media', 'plex', 'web', 'backdrop', 'spotify', 'youtube'] : + if jcast.is_castgroup is False: + if 'app' in command and command['app'] in ['media', 'plex', 'web', 'backdrop', 'spotify', 'youtube']: jcast.savePreviousPlayerCmd(storecmd) - logging.debug("ACTION STORECMD------Storing command for later resume.") - else : - logging.debug("ACTION STORECMD------Not possible for this kind of action !") - else : - logging.debug("ACTION STORECMD------Not possible for cast group !:") + logging.debug( + "ACTION STORECMD------Storing command for later resume.") + else: + logging.debug( + "ACTION STORECMD------Not possible for this kind of action !") + else: + logging.debug( + "ACTION STORECMD------Not possible for cast group !:") continue cmd = 'NONE' - if 'cmd' in command : + if 'cmd' in command: cmd = command['cmd'] app = 'none' - if 'app' in command : + if 'app' in command: app = command['app'] appid = '' - if 'appid' in command : + if 'appid' in command: appid = command['appid'] value = None - if 'value' in command : + if 'value' in command: value = command['value'] - if 'v' in command : + if 'v' in command: value = command['v'] - sleep=0 - if 'sleep' in command : + sleep = 0 + if 'sleep' in command: sleep = float(command['sleep']) - sleepbefore=0 - if 'sleepbefore' in command : + sleepbefore = 0 + if 'sleepbefore' in command: sleepbefore = float(command['sleepbefore']) vol = None - if 'vol' in command : + if 'vol' in command: try: vol = int(command['vol']) if not (0 < vol <= 100) or command['vol'] == '': vol = None - except: + except Exception: vol = None # specific parameters for apps - quit_app_before=True - if 'quit_app_before' in command : + quit_app_before = True + if 'quit_app_before' in command: quit_app_before = True if command['quit_app_before'] else False - quit=False - if 'quit' in command : + quit = False + if 'quit' in command: quit = True if command['quit'] else False - force_register=False - if 'force_register' in command : - force_register = True if command['force_register'] else False - wait=2 - if 'wait' in command : - wait = int(command['wait']) if command['wait'].isnumeric() else 2 - - if app == 'tts' : + # force_register = False + # if 'force_register' in command: + # force_register = True if command['force_register'] else False + wait = 2 + if 'wait' in command: + wait = int(command['wait'] + ) if command['wait'].isnumeric() else 2 + + if app == 'tts': cmd = 'tts' app = 'media' needSendStatus = True fallbackMode = True - logging.debug("ACTION------ " + rootcmd + " - " + cmd + ' - ' + uuid + ' - ' + str(value)+ ' - ' + app) + logging.debug("ACTION------ " + rootcmd + " - " + + cmd + ' - ' + uuid + ' - ' + str(value) + ' - ' + app) - if sleepbefore > 0 : + if sleepbefore > 0: time.sleep(sleepbefore) jcast = globals.GCAST_DEVICES[uuid] gcast = jcast.gcast try: jcast.applaunch_callback_reset() - if app == 'media' : # app=media|cmd=play_media|value=http://bit.ly/2JzYtfX,video/mp4,Mon film - if cmd == 'NONE' : + if app == 'media': # app=media|cmd=play_media|value=http://bit.ly/2JzYtfX,video/mp4,Mon film + if cmd == 'NONE': cmd = 'play_media' possibleCmd = ['play_media'] - if cmd in possibleCmd and value is not None : - if 'offset' in command and float(command['offset'])>0 and 'current_time' not in value : - value = value + ',current_time:'+ str(command['offset']) - if 'live' in command and 'stream_type' not in value : - if int(command['live'])==1 : + if cmd in possibleCmd and value is not None: + if 'offset' in command and float(command['offset']) > 0 and 'current_time' not in value: + value = value + ',current_time:' + \ + str(command['offset']) + if 'live' in command and 'stream_type' not in value: + if int(command['live']) == 1: value = value + ",stream_type:'LIVE'" - else : + else: del command['live'] forceplay = 0 - if 'forceplay' in command : + if 'forceplay' in command: try: forceplay = float(command['forceplay']) - except Exception as e: + except Exception: forceplay = 2.0 del command['forceplay'] value = value.replace('h:/', 'http://') value = value.replace('hs:/', 'https://') - value = value.replace('local://', globals.JEEDOM_WEB+'/plugins/googlecast/'+globals.localmedia_folder+'/') - value = value.replace('logo://', globals.JEEDOM_WEB+'/plugins/googlecast/desktop/images/') - fallbackMode=False - player = jcast.loadPlayer('media', { 'quitapp' : quit_app_before}) - eval( 'player.' + cmd + '('+ gcast_prepareAppParam(value) +')' ) + value = value.replace( + 'local://', globals.JEEDOM_WEB+'/plugins/googlecast/'+globals.localmedia_folder+'/') + value = value.replace( + 'logo://', globals.JEEDOM_WEB+'/plugins/googlecast/desktop/images/') + fallbackMode = False + player = jcast.loadPlayer( + 'media', {'quitapp': quit_app_before}) + eval('player.' + cmd + + '(' + gcast_prepareAppParam(value) + ')') jcast.savePreviousPlayerCmd(command) - if forceplay > 0.0 : + if forceplay > 0.0: time.sleep(forceplay) # logging.debug("FORCEPLAY------ ") player.play() elif app == 'web': # app=web|cmd=load_url|value=https://news.google.com,True,5 - force_register=True - if cmd == 'NONE' : + if cmd == 'NONE': cmd = 'load_url' possibleCmd = ['load_url'] - if cmd in possibleCmd : - fallbackMode=False - player = jcast.loadPlayer(app, { 'quitapp' : quit_app_before}) + if cmd in possibleCmd: + fallbackMode = False + player = jcast.loadPlayer( + app, {'quitapp': quit_app_before}) value = value.replace('h:/', 'http://') value = value.replace('hs:/', 'https://') - eval( 'player.' + cmd + '('+ gcast_prepareAppParam(value) +')' ) + eval('player.' + cmd + + '(' + gcast_prepareAppParam(value) + ')') jcast.savePreviousPlayerCmd(command) elif app == 'youtube': # app=youtube|cmd=play_video|value=fra4QBLF3GU - #possibleCmd = ['play_video', 'start_new_session', 'add_to_queue', 'update_screen_id', 'clear_playlist', 'play', 'stop', 'pause'] - possibleCmd = ['play_video', 'add_to_queue', 'play_next', 'remove_video'] - if cmd in possibleCmd : - fallbackMode=False - if jcast.support_video == True : - player = jcast.loadPlayer(app, { 'quitapp' : quit_app_before, 'wait': wait}) - eval( 'player.' + cmd + '('+ gcast_prepareAppParam(value) +')' ) - if cmd == 'play_video' : + # possibleCmd = ['play_video', 'start_new_session', 'add_to_queue', 'update_screen_id', 'clear_playlist', 'play', 'stop', 'pause'] + possibleCmd = ['play_video', 'add_to_queue', + 'play_next', 'remove_video'] + if cmd in possibleCmd: + fallbackMode = False + if jcast.support_video is True: + player = jcast.loadPlayer( + app, {'quitapp': quit_app_before, 'wait': wait}) + eval('player.' + cmd + + '(' + gcast_prepareAppParam(value) + ')') + if cmd == 'play_video': jcast.savePreviousPlayerCmd(command) - else : - logging.error("ACTION------ YouTube not availble on Google Cast Audio") + else: + logging.error( + "ACTION------ YouTube not availble on Google Cast Audio") elif app == 'spotify': # app=spotify|cmd=launch_app|user=XXXXXX|pass=YYYY|value - if cmd == 'NONE' : + if cmd == 'NONE': cmd = 'play_media' possibleCmd = ['play_media'] - if cmd == 'play_media' : - fallbackMode=False + if cmd == 'play_media': + fallbackMode = False wptoken = None - if 'user' in command and 'pass' in command : + if 'user' in command and 'pass' in command: username = command['user'] password = command['pass'] wptoken = stoken.SpotifyWpToken(username, password) - if 'token' in command : + if 'token' in command: token = command['token'] keepGoing = True - if value is None : - logging.error("ACTION------ Missing content id for spotify") + if value is None: + logging.error( + "ACTION------ Missing content id for spotify") keepGoing = False - if token is None : - logging.error("ACTION------ Missing token paramaters for spotify") + if token is None: + logging.error( + "ACTION------ Missing token paramaters for spotify") keepGoing = False - if keepGoing == True : - player = jcast.loadPlayer(app, { 'quitapp' : quit_app_before, 'wait': wait}) - if wptoken is None : + if keepGoing is True: + player = jcast.loadPlayer( + app, {'quitapp': quit_app_before, 'wait': wait}) + if wptoken is None: player.launch_app(token) - else : + else: time.sleep(1) player.launch_app(wptoken.value) spotifyClient = spotipy.Spotify(auth=token) - time.sleep(1); + time.sleep(1) value = value.replace('spotify:', '') - trycount=0; - success=False - devicefound=False - while trycount < 4 : - if devicefound==False : + trycount = 0 + success = False + devicefound = False + while trycount < 4: + if devicefound is False: devices_available = spotifyClient.devices() device_id = None for device in devices_available['devices']: - logging.debug("ACTION------Spotify registered device : " + str(device['name'])) - if device['name'] == jcast.device.friendly_name : + logging.debug( + "ACTION------Spotify registered device : " + str(device['name'])) + if device['name'] == jcast.device.friendly_name: device_id = device['id'] break - if device_id is not None : - devicefound=True - try : - logging.debug("ACTION------Spotify device found !") + if device_id is not None: + devicefound = True + try: + logging.debug( + "ACTION------Spotify device found !") - if value == 'recent' : - recentlyPlayed = spotifyClient.current_user_recently_played(limit=1) - if len(recentlyPlayed['items'])>0 : + if value == 'recent': + recentlyPlayed = spotifyClient.current_user_recently_played( + limit=1) + if len(recentlyPlayed['items']) > 0: value = recentlyPlayed['items'][0]['track']['uri'] - value = value.replace('spotify:', '') - logging.debug("ACTION------Spotify recently played : " + value) - #logging.debug("ACTION------Spotify recently played : " + str(recentlyPlayed)) - elif 'track' not in value : # album or playlist - out = spotifyClient.start_playback(device_id=device_id, context_uri='spotify:'+value) - else : # track - out = spotifyClient.start_playback(device_id=device_id, uris=['spotify:'+value]) - success=True + value = value.replace( + 'spotify:', '') + logging.debug( + "ACTION------Spotify recently played : " + value) + # logging.debug("ACTION------Spotify recently played : " + str(recentlyPlayed)) + elif 'track' not in value: # album or playlist + spotifyClient.start_playback( + device_id=device_id, context_uri='spotify:'+value) + else: # track + spotifyClient.start_playback( + device_id=device_id, uris=['spotify:'+value]) + success = True break except Exception as e: trycount = trycount+1 - logging.debug("ACTION------Spotify error : %s" % str(e)) - #logging.debug(traceback.format_exc()) + logging.debug( + "ACTION------Spotify error : %s" % str(e)) + # logging.debug(traceback.format_exc()) gcast.media_controller.stop() time.sleep(1) - else : - logging.debug("ACTION------Spotify : device not found, wait for spotify to set an id...") + else: + logging.debug( + "ACTION------Spotify : device not found, wait for spotify to set an id...") device_id = player.wait() - logging.debug("ACTION------Spotify : device not found, returned this new id : " + str(device_id)) + logging.debug( + "ACTION------Spotify : device not found, returned this new id : " + str(device_id)) trycount = trycount+1 - if success==True : + if success is True: jcast.savePreviousPlayerCmd(command) - else : - if devicefound==False : - logging.error("ACTION------ Spotify : device not found ! Have you added the cast device using Spotify phone application ?") - else : - logging.error("ACTION------ Spotify : Starting spotify failed !") + else: + if devicefound is False: + logging.error( + "ACTION------ Spotify : device not found ! Have you added the cast device using Spotify phone application ?") + else: + logging.error( + "ACTION------ Spotify : Starting spotify failed !") break elif app == 'backdrop': # also called backdrop - if jcast.support_video == True : - fallbackMode=False + if jcast.support_video is True: + fallbackMode = False gcast.start_app('E8C28D3C') jcast.savePreviousPlayerCmd(command) - else : - logging.error("ACTION------ Backdrop not availble on Google Cast Audio") + else: + logging.error( + "ACTION------ Backdrop not availble on Google Cast Audio") elif app == 'plex': # app=plex|cmd=pause - quit_app_before=False - if cmd == 'NONE' : + quit_app_before = False + if cmd == 'NONE': cmd = 'play_media' - possibleCmd = ['play_media','play', 'stop', 'pause', 'next', 'previous'] - if cmd in possibleCmd : - fallbackMode=False + possibleCmd = ['play_media', 'play', + 'stop', 'pause', 'next', 'previous'] + if cmd in possibleCmd: + fallbackMode = False - player = jcast.loadPlayer(app, { 'quitapp' : quit_app_before, 'wait': wait}) - #player.namespace = 'urn:x-cast:com.google.cast.sse' + player = jcast.loadPlayer( + app, {'quitapp': quit_app_before, 'wait': wait}) + # player.namespace = 'urn:x-cast:com.google.cast.sse' - if cmd == 'play_media' : + if cmd == 'play_media': serverurl = None - if 'server' in command : + if 'server' in command: serverurl = command['server'] username = None password = None - if 'user' in command and 'pass' in command : + if 'user' in command and 'pass' in command: username = command['user'] password = command['pass'] token = None - if 'token' in command : + if 'token' in command: token = command['token'] type = 'audio' - if 'type' in command : + if 'type' in command: type = command['type'] - if jcast.support_video==False and type=='video' : + if jcast.support_video is False and type == 'video': type = 'audio' offset = 0 - if 'offset' in command : + if 'offset' in command: offset = int(command['offset']) shuffle = 0 - if 'shuffle' in command : + if 'shuffle' in command: shuffle = int(command['shuffle']) repeat = 0 - if 'repeat' in command : + if 'repeat' in command: repeat = int(command['repeat']) keepGoing = True - if serverurl is None : - logging.error("ACTION------ Missing server paramater for plex") + if serverurl is None: + logging.error( + "ACTION------ Missing server paramater for plex") keepGoing = False - if token is None and (username is None or password is None) : - logging.error("ACTION------ Missing token or user/pass paramaters for plex") + if token is None and (username is None or password is None): + logging.error( + "ACTION------ Missing token or user/pass paramaters for plex") keepGoing = False - if keepGoing==True : + if keepGoing is True: is_resume = False - if 'resume_plexitem' in command : + if 'resume_plexitem' in command: is_resume = True - if not is_resume : - if username is not None and password is not None and token is None : - account = MyPlexAccount(username, password) - for res in account.resources() : - logging.debug("PLEX------ Resource available : " +str(res.name)) - plexServer = account.resource(serverurl).connect() - logging.debug("PLEX------ Token for reuse : " +str(account._token)) - else : - plexServer = PlexServer(serverurl, token) - plexmedia = plexServer.search(value, limit=1) - if len(plexmedia)>0 : + if not is_resume: + if username is not None and password is not None and token is None: + account = MyPlexAccount( + username, password) + for res in account.resources(): + logging.debug( + "PLEX------ Resource available : " + str(res.name)) + plexServer = account.resource( + serverurl).connect() + logging.debug( + "PLEX------ Token for reuse : " + str(account._token)) + else: + plexServer = PlexServer( + serverurl, token) + plexmedia = plexServer.search( + value, limit=1) + if len(plexmedia) > 0: command['resume_plexitem'] = plexmedia[0] command['resume_plexserver'] = plexServer - player.play_media(plexmedia[0], plexServer, {'offset':offset, 'type':type, 'shuffle':shuffle, 'repeat':repeat} ) + player.play_media(plexmedia[0], plexServer, { + 'offset': offset, 'type': type, 'shuffle': shuffle, 'repeat': repeat}) jcast.savePreviousPlayerCmd(command) - else : - logging.debug("PLEX------No media found for query " + value) - - else : - logging.debug("PLEX------Restoring from previous call") - player.play_media(command['resume_plexitem'], command['resume_plexserver'], {'offset':offset, 'type':type, 'shuffle':shuffle, 'repeat':repeat} ) + else: + logging.debug( + "PLEX------No media found for query " + value) + + else: + logging.debug( + "PLEX------Restoring from previous call") + player.play_media(command['resume_plexitem'], command['resume_plexserver'], { + 'offset': offset, 'type': type, 'shuffle': shuffle, 'repeat': repeat}) jcast.savePreviousPlayerCmd(command) - else : - eval( 'player.' + cmd + '()' ) + else: + eval('player.' + cmd + '()') - if fallbackMode==False : - logging.debug("ACTION------Playing action " + cmd + ' for application ' + app) + if fallbackMode is False: + logging.debug("ACTION------Playing action " + + cmd + ' for application ' + app) except Exception as e: - logging.error("ACTION------Error while playing action " +cmd+ " on app " +app+" : %s" % str(e)) + logging.error("ACTION------Error while playing action " + + cmd + " on app " + app+" : %s" % str(e)) logging.debug(traceback.format_exc()) jcast.manage_exceptions(str(e)) # low level google cast actions - if fallbackMode==True : + if fallbackMode is True: try: if cmd == 'refresh': logging.debug("ACTION------Refresh action") time.sleep(1) - fallbackMode=False + fallbackMode = False elif cmd == 'reboot': logging.debug("ACTION------Reboot action") gcast.reboot() time.sleep(5) - fallbackMode=False + fallbackMode = False elif cmd == 'volume_up': logging.debug("ACTION------Volumme up action") gcast.volume_up(value if value is not None else 0.1) - fallbackMode=False + fallbackMode = False elif cmd == 'volume_down': logging.debug("ACTION------Volume down action") gcast.volume_down(value if value is not None else 0.1) - fallbackMode=False + fallbackMode = False elif cmd == 'volume_set': logging.debug("ACTION------Volume set action") gcast.set_volume(int(value)/100) - fallbackMode=False + fallbackMode = False elif cmd == 'start_app': logging.debug("ACTION------Start app action") appToLaunch = '' if value is None else value if appid != '': - appToLaunch=appid + appToLaunch = appid gcast.start_app(appToLaunch) - fallbackMode=False + fallbackMode = False elif cmd == 'quit_app': logging.debug("ACTION------Quit app action") gcast.quit_app() jcast.resetPlayer() - fallbackMode=False + fallbackMode = False elif cmd == 'mute_on': logging.debug("ACTION------Mute on action") gcast.set_volume_muted(True) - fallbackMode=False + fallbackMode = False elif cmd == 'mute_off': logging.debug("ACTION------Mute off action") gcast.set_volume_muted(False) - fallbackMode=False + fallbackMode = False elif cmd == 'turn_on': logging.debug("ACTION------Turn on action") if gcast.is_idle: - if gcast.app_id is not None : + if gcast.app_id is not None: # Quit the previous app before starting splash screen gcast.quit_app() # The only way we can turn the Chromecast is on is by launching an app url = generate_warmupnotif() gcast.play_media(url, "BUFFERED") - fallbackMode=False + fallbackMode = False elif cmd == 'turn_off': logging.debug("ACTION------Turn off action") gcast.quit_app() jcast.resetPlayer() - fallbackMode=False + fallbackMode = False elif cmd == 'notif': logging.debug("ACTION------NOTIF action") forcevol = False - if 'forcevol' in command : + if 'forcevol' in command: forcevol = True type = 'audio' - if 'type' in command : + if 'type' in command: type = command['type'] resume = True - if 'noresume' in command : + if 'noresume' in command: resume = False streamtype = 'LIVE' - if 'buffered' in command and command['buffered']=='1': + if 'buffered' in command and command['buffered'] == '1': streamtype = 'BUFFERED' durationparam = 0 - if 'duration' in command : + if 'duration' in command: durationparam = float(command['duration']) curvol = jcast.getCurrentVolume() - if curvol == vol and not forcevol : + if curvol == vol and not forcevol: vol = None - need_duration=False - if vol is not None or quit==True or resume==True : - need_duration=True + need_duration = False + if vol is not None or quit is True or resume is True: + need_duration = True - url,duration,mp3filename=get_notif_data(value, need_duration) - if durationparam > 0 : + url, duration, mp3filename = get_notif_data( + value, need_duration) + if durationparam > 0: duration = durationparam - if url is not None : - thumb=globals.JEEDOM_WEB + '/plugins/googlecast/desktop/images/notif.png' + if url is not None: + thumb = globals.JEEDOM_WEB + '/plugins/googlecast/desktop/images/notif.png' jcast.disable_notif = True if resume: jcast.prepareTTSplay() - player = jcast.loadPlayer('media', { 'quitapp' : False, 'wait': 0}) - if vol is not None : - gcast.media_controller.pause(); + player = jcast.loadPlayer( + 'media', {'quitapp': False, 'wait': 0}) + if vol is not None: + gcast.media_controller.pause() time.sleep(0.1) gcast.set_volume(vol/100) time.sleep(0.1) - if type == 'audio' : - player.play_media(url, 'audio/mp3', 'NOTIF', thumb=thumb, stream_type=streamtype) - else : - player.play_media(url, 'video/mp4', 'NOTIF', thumb=thumb, stream_type=streamtype) - player.block_until_active(timeout=2); + if type == 'audio': + player.play_media( + url, 'audio/mp3', 'NOTIF', thumb=thumb, stream_type=streamtype) + else: + player.play_media( + url, 'video/mp4', 'NOTIF', thumb=thumb, stream_type=streamtype) + player.block_until_active(timeout=2) jcast.disable_notif = False sleep_done = False - if vol is not None : + if vol is not None: time.sleep(duration+1) - if sleep>0 : + if sleep > 0: time.sleep(sleep) - sleep=0 + sleep = 0 gcast.set_volume(curvol/100) vol = None sleep_done = True - if durationparam > 0 : - if sleep_done==False : + if durationparam > 0: + if sleep_done is False: time.sleep(duration) sleep_done = True gcast.media_controller.stop() - if quit : - if vol is None : + if quit: + if vol is None: time.sleep(duration+1) sleep_done = True - if sleep>0 : + if sleep > 0: time.sleep(sleep) - sleep=0 + sleep = 0 gcast.quit_app() if resume: - if vol is None and sleep_done==False : + if vol is None and sleep_done is False: time.sleep(duration+1) - if sleep>0 : + if sleep > 0: time.sleep(sleep) - sleep=0 + sleep = 0 forceapplaunch = False - if 'forceapplaunch' in command : + if 'forceapplaunch' in command: forceapplaunch = True - resumeOk = manage_resume(uuid, message['device']['source'], forceapplaunch, 'NOTIF') - if resumeOk==False : - logging.debug("NOTIF------Resume is not possible!") - else : - logging.debug("NOTIF------Error while getting local media !") + resumeOk = manage_resume( + uuid, message['device']['source'], forceapplaunch, 'NOTIF') + if resumeOk is False: + logging.debug( + "NOTIF------Resume is not possible!") + else: + logging.debug( + "NOTIF------Error while getting local media !") sendErrorDeviceStatus(uuid, 'ERROR') - fallbackMode=False + fallbackMode = False elif cmd == 'tts': logging.debug("ACTION------TTS action") lang = globals.tts_language - if 'lang' in command : + if 'lang' in command: lang = command['lang'] engine = globals.tts_engine - if 'engine' in command : + if 'engine' in command: engine = command['engine'] speed = globals.tts_speed - if 'speed' in command : + if 'speed' in command: speed = float(command['speed']) forcetts = False - if 'forcetts' in command : + if 'forcetts' in command: forcetts = True silence = 300 - if 'silence' in command : + if 'silence' in command: silence = int(command['silence']) - elif jcast.is_castgroup==True : + elif jcast.is_castgroup is True: silence = 1000 generateonly = False - if 'generateonly' in command : + if 'generateonly' in command: generateonly = True quality = '32k' - if 'highquality' in command and command['highquality']=='1' : + if 'highquality' in command and command['highquality'] == '1': quality = '64k' streamtype = 'LIVE' - if 'buffered' in command and command['buffered']=='1': + if 'buffered' in command and command['buffered'] == '1': streamtype = 'BUFFERED' forcevol = False - if 'forcevol' in command : + if 'forcevol' in command: forcevol = True resume = True - if 'noresume' in command : + if 'noresume' in command: resume = False ttsparams = None - if 'voice' in command or 'usessml' in command : + if 'voice' in command or 'usessml' in command: ttsparams = {} - if 'voice' in command : + if 'voice' in command: ttsparams['voice'] = command['voice'] - if 'usessml' in command : + if 'usessml' in command: ttsparams['usessml'] = command['usessml'] - if 'pitch' in command : + if 'pitch' in command: ttsparams['pitch'] = command['pitch'] - if 'volgain' in command : + if 'volgain' in command: ttsparams['volgain'] = command['volgain'] curvol = jcast.getCurrentVolume() - if curvol == vol and not forcevol : + if curvol == vol and not forcevol: vol = None - need_duration=False - if vol is not None or quit==True or resume==True : - need_duration=True - - if generateonly == False : - url,duration,mp3filename=get_tts_data(value, lang, engine, speed, forcetts, need_duration, silence, quality, ttsparams) - if url is not None : - thumb=globals.JEEDOM_WEB + '/plugins/googlecast/desktop/images/tts.png' + need_duration = False + if vol is not None or quit is True or resume is True: + need_duration = True + + if generateonly is False: + url, duration, mp3filename = get_tts_data( + value, lang, engine, speed, forcetts, need_duration, silence, quality, ttsparams) + if url is not None: + thumb = globals.JEEDOM_WEB + '/plugins/googlecast/desktop/images/tts.png' jcast.disable_notif = True if resume: jcast.prepareTTSplay() - player = jcast.loadPlayer('media', { 'quitapp' : False, 'wait': 0}) - if vol is not None : - gcast.media_controller.pause(); + player = jcast.loadPlayer( + 'media', {'quitapp': False, 'wait': 0}) + if vol is not None: + gcast.media_controller.pause() time.sleep(0.1) gcast.set_volume(vol/100) time.sleep(0.1) - player.play_media(url, 'audio/mp3', 'TTS', thumb=thumb, stream_type=streamtype); - player.block_until_active(timeout=2); + player.play_media( + url, 'audio/mp3', 'TTS', thumb=thumb, stream_type=streamtype) + player.block_until_active(timeout=2) jcast.disable_notif = False vol_done = False - if vol is not None : + if vol is not None: time.sleep(duration+(silence/1000)+1) - if sleep>0 : + if sleep > 0: time.sleep(sleep) - sleep=0 + sleep = 0 gcast.set_volume(curvol/100) vol = None vol_done = True - if quit : - if vol is None : + if quit: + if vol is None: time.sleep(duration+(silence/1000)+1) - if sleep>0 : + if sleep > 0: time.sleep(sleep) - sleep=0 + sleep = 0 gcast.quit_app() if resume: - if vol is None and vol_done==False : + if vol is None and vol_done is False: time.sleep(duration+(silence/1000)+1) - if sleep>0 : + if sleep > 0: time.sleep(sleep) - sleep=0 + sleep = 0 forceapplaunch = False - if 'forceapplaunch' in command : + if 'forceapplaunch' in command: forceapplaunch = True - resumeOk = manage_resume(uuid, message['device']['source'], forceapplaunch, 'TTS') - if resumeOk==False : - logging.debug("TTS------Resume is not possible!") - else : - logging.debug("TTS------File generation failed !") + resumeOk = manage_resume( + uuid, message['device']['source'], forceapplaunch, 'TTS') + if resumeOk is False: + logging.debug( + "TTS------Resume is not possible!") + else: + logging.debug( + "TTS------File generation failed !") sendErrorDeviceStatus(uuid, 'ERROR') - else : - logging.error("TTS------Only generating TTS file without playing") - get_tts_data(value, lang, engine, speed, forcetts, False, silence) + else: + logging.error( + "TTS------Only generating TTS file without playing") + get_tts_data(value, lang, engine, speed, + forcetts, False, silence) needSendStatus = False - fallbackMode=False + fallbackMode = False except Exception as e: - logging.error("ACTION------Error while playing action " +cmd+ " on low level commands : %s" % str(e)) + logging.error("ACTION------Error while playing action " + + cmd + " on low level commands : %s" % str(e)) sendErrorDeviceStatus(uuid, 'ERROR') logging.debug(traceback.format_exc()) jcast.manage_exceptions(str(e)) - fallbackMode==False + fallbackMode is False # media/application controler level Google Cast actions - if fallbackMode==True : + if fallbackMode is True: try: - player=gcast.media_controller + player = gcast.media_controller if cmd == 'play': logging.debug("ACTION------Play action") player.play() - fallbackMode=False + fallbackMode = False elif cmd == 'stop': logging.debug("ACTION------Stop action") player.stop() - fallbackMode=False + fallbackMode = False elif cmd == 'rewind': logging.debug("ACTION------Rewind action") player.rewind() - fallbackMode=False + fallbackMode = False elif cmd == 'skip': logging.debug("ACTION------Skip action") # player.skip() player.queue_next() - fallbackMode=False + fallbackMode = False elif cmd == 'next': logging.debug("ACTION------Next action") player.queue_next() - fallbackMode=False + fallbackMode = False elif cmd == 'prev': logging.debug("ACTION------Previous action") player.queue_prev() - fallbackMode=False + fallbackMode = False elif cmd == 'seek': logging.debug("ACTION------Seek action") - if value is not None and '+' in value : - player.seek(jcast.media_current_time + float(value.replace('+',''))) - elif value is not None and '-' in value : - player.seek(jcast.media_current_time - float(value.replace('-',''))) - else : + if value is not None and '+' in value: + player.seek(jcast.media_current_time + + float(value.replace('+', ''))) + elif value is not None and '-' in value: + player.seek(jcast.media_current_time - + float(value.replace('-', ''))) + else: player.seek(0 if value is None else float(value)) - fallbackMode=False + fallbackMode = False elif cmd == 'pause': logging.debug("ACTION------Stop action") player.pause() - fallbackMode=False + fallbackMode = False elif cmd == 'resume': forceapplaunch = False - if 'forceapplaunch' in command : + if 'forceapplaunch' in command: forceapplaunch = True offset = None - if 'offset' in command : + if 'offset' in command: offset = command['offset'] status = None - if 'status' in command : + if 'status' in command: status = command['status'] jcast.prepareForceResume(status, offset) - resumeOk = manage_resume(uuid, message['device']['source'], forceapplaunch, 'ACTION') - if resumeOk==False : - logging.debug("ACTION------Resume is not possible!") - else : + resumeOk = manage_resume( + uuid, message['device']['source'], forceapplaunch, 'ACTION') + if resumeOk is False: + logging.debug( + "ACTION------Resume is not possible!") + else: logging.debug("ACTION------Resume OK") - fallbackMode=False - elif cmd == "warmupnotif" : + fallbackMode = False + elif cmd == "warmupnotif": jcast.prepareWarumplay() url = generate_warmupnotif() - if url is not None : + if url is not None: jcast.disable_notif = True - player = jcast.loadPlayer('media', { 'quitapp' : False, 'wait': 0}) - player.play_media(url, 'audio/mp3', 'WARMUP', stream_type="LIVE") - player.block_until_active(timeout=3); + player = jcast.loadPlayer( + 'media', {'quitapp': False, 'wait': 0}) + player.play_media( + url, 'audio/mp3', 'WARMUP', stream_type="LIVE") + player.block_until_active(timeout=3) time.sleep(0.3) - #gcast.quit_app() + # gcast.quit_app() jcast.disable_notif = False - fallbackMode=False + fallbackMode = False elif cmd == 'sleep': logging.debug("ACTION------Sleep") time.sleep(float(value)) - fallbackMode=False + fallbackMode = False except Exception as e: - logging.error("ACTION------Error while playing action " +cmd+ " on default media controler : %s" % str(e)) + logging.error("ACTION------Error while playing action " + + cmd + " on default media controler : %s" % str(e)) logging.debug(traceback.format_exc()) jcast.manage_exceptions(str(e)) - if vol is not None and uuid in globals.GCAST_DEVICES : + if vol is not None and uuid in globals.GCAST_DEVICES: logging.debug("ACTION------SET VOLUME OPTION") time.sleep(0.1) - try : + try: gcast.set_volume(vol/100) except Exception as e: - logging.error("ACTION------SET VOLUME OPTION ERROR : %s" % str(e)) + logging.error( + "ACTION------SET VOLUME OPTION ERROR : %s" % str(e)) jcast.manage_exceptions(str(e)) - if fallbackMode==True : - logging.debug("ACTION------Action " + cmd + " not implemented or exception occured !") + if fallbackMode is True: + logging.debug("ACTION------Action " + cmd + + " not implemented or exception occured !") sendErrorDeviceStatus(uuid, 'CMD UNKNOWN') - if sleep>0 : + if sleep > 0: time.sleep(sleep) - if needSendStatus and uuid in globals.GCAST_DEVICES : + if needSendStatus and uuid in globals.GCAST_DEVICES: time.sleep(0.1) jcast.sendDeviceStatus() - if hascallback : - callbackret=manage_callback(uuid, callback) - callbackmsg={'callback' : 1,'source' : source, 'uuid' : uuid, 'result': callbackret} - globals.JEEDOM_COM.send_change_immediate(callbackmsg); + if hascallback: + callbackret = manage_callback(uuid, callback) + callbackmsg = {'callback': 1, 'source': source, + 'uuid': uuid, 'result': callbackret} + globals.JEEDOM_COM.send_change_immediate(callbackmsg) - else : + else: logging.debug("ACTION------ Device not connected !") sendErrorDeviceStatus(uuid, 'NOT CONNECTED') return False return True + def manage_callback(uuid, callback_type): # todo things for callback before returning value return True + def generate_warmupnotif(): logging.debug("WARMUPNOTIF------ Checking file generation...") - cachepath=globals.tts_cachefolderweb - symlinkpath=globals.tts_cachefoldertmp + cachepath = globals.tts_cachefolderweb + symlinkpath = globals.tts_cachefoldertmp try: os.stat(symlinkpath) - except: + except Exception: os.mkdir(symlinkpath) try: os.stat(cachepath) - except: + except Exception: os.symlink(symlinkpath, cachepath) try: file = hashlib.md5('WARMUPNOTIF'.encode('utf-8')).hexdigest() - filenamemp3=os.path.join(cachepath,file+'.mp3') - if not os.path.isfile(filenamemp3) : + filenamemp3 = os.path.join(cachepath, file+'.mp3') + if not os.path.isfile(filenamemp3): warmup = AudioSegment.silent(duration=80) - warmup.export(filenamemp3, format="mp3", bitrate='32k', tags={'albumartist': 'Jeedom', 'title': 'WARMUPNOTIF', 'artist':'Jeedom'}, parameters=["-ac", "1", "-ar", "24000"]) - else : - try : # touch file so cleaning can be done later based on date - if os.stat(filenamemp3).st_mtime < (time.time() - 86400) : + warmup.export(filenamemp3, format="mp3", bitrate='32k', tags={ + 'albumartist': 'Jeedom', 'title': 'WARMUPNOTIF', 'artist': 'Jeedom'}, parameters=["-ac", "1", "-ar", "24000"]) + else: + try: # touch file so cleaning can be done later based on date + if os.stat(filenamemp3).st_mtime < (time.time() - 86400): os.utime(filenamemp3, None) - except : + except Exception: logging.debug("WARMUPNOTIF------Touching file failed !") pass - urltoplay=globals.JEEDOM_WEB+'/plugins/googlecast/tmp/'+file+'.mp3' + urltoplay = globals.JEEDOM_WEB+'/plugins/googlecast/tmp/'+file+'.mp3' except Exception as e: - logging.error("WARMUPNOTIF------Exception while generating warmupnotif file : %s" % str(e)) - urltoplay=None + logging.error( + "WARMUPNOTIF------Exception while generating warmupnotif file : %s" % str(e)) + urltoplay = None return urltoplay + def manage_resume(uuid, source='googlecast', forceapplaunch=False, origin='TTS'): jcast = globals.GCAST_DEVICES[uuid] - prevcommand = jcast.getPreviousPlayerCmd(forceapplaunch, True if origin!='ACTION' else False) - if prevcommand is not None : + prevcommand = jcast.getPreviousPlayerCmd( + forceapplaunch, True if origin != 'ACTION' else False) + if prevcommand is not None: newMessage = { - 'cmd' : 'action', - 'delegated' : True, - 'resume' : True, - 'device' : {'uuid' : uuid, 'source' : source }, - 'command' : prevcommand + 'cmd': 'action', + 'delegated': True, + 'resume': True, + 'device': {'uuid': uuid, 'source': source}, + 'command': prevcommand } - logging.debug("RESUME------DELEGATED RESUME AFTER "+origin+" for uuid : " + uuid) + logging.debug("RESUME------DELEGATED RESUME AFTER " + + origin+" for uuid : " + uuid) time.sleep(0.3) jcast.resetPreviousPlayerCmd() - thread.start_new_thread( action_handler, (newMessage,)) + thread.start_new_thread(action_handler, (newMessage,)) return True return False + def get_tts_data(text, language, engine, speed, forcetts, calcduration, silence=300, quality='32k', ttsparams=None): srclanguage = language if engine == 'gttsapidev': # removed this engine but failover to gttsapi engine = 'gttsapi' - if not globals.tts_gapi_haskey and engine=='gttsapi' : - logging.error("CMD-TTS------No key provided, fallback to picotts engine") + if not globals.tts_gapi_haskey and engine == 'gttsapi': + logging.error( + "CMD-TTS------No key provided, fallback to picotts engine") engine = 'picotts' speed = 1 - if globals.tts_cacheenabled==False : - try : - if os.path.exists(globals.tts_cachefoldertmp) : + if globals.tts_cacheenabled is False: + try: + if os.path.exists(globals.tts_cachefoldertmp): shutil.rmtree(globals.tts_cachefoldertmp) - except : + except Exception: pass - cachepath=globals.tts_cachefolderweb + cachepath = globals.tts_cachefolderweb # manage cache in ram memory - symlinkpath=globals.tts_cachefoldertmp + symlinkpath = globals.tts_cachefoldertmp ttstext = text try: os.stat(symlinkpath) - except: + except Exception: os.mkdir(symlinkpath) try: os.stat(cachepath) - except: + except Exception: os.symlink(symlinkpath, cachepath) try: rawfilename = text+engine+language+str(silence) - if engine=='gttsapi' : # add exception when using gttsapi engine to use voice over language - if ttsparams is not None and 'voice' in ttsparams : + if engine == 'gttsapi': # add exception when using gttsapi engine to use voice over language + if ttsparams is not None and 'voice' in ttsparams: rawfilename = text+engine+ttsparams['voice']+str(silence) - else : + else: rawfilename = text+engine+globals.tts_gapi_voice+str(silence) file = hashlib.md5(rawfilename.encode('utf-8')).hexdigest() - filenamemp3=os.path.join(cachepath,file+'.mp3') - logging.debug("CMD-TTS------TTS Filename hexdigest : " + file + " ("+rawfilename+")") - if not os.path.isfile(filenamemp3) or forcetts==True : + filenamemp3 = os.path.join(cachepath, file+'.mp3') + logging.debug("CMD-TTS------TTS Filename hexdigest : " + + file + " ("+rawfilename+")") + if not os.path.isfile(filenamemp3) or forcetts is True: logging.debug("CMD-TTS------Generating file") samplerate = '24000' - if quality != '32k' : + if quality != '32k': samplerate = '44100' if engine == 'gtts': speed = float(speed) - language=language.split('-')[0] + language = language.split('-')[0] try: tts = gTTS(text=ttstext, lang=language) tts.save(filenamemp3) - if speed!=1: + if speed != 1: try: - os.system('sox '+filenamemp3+' '+filenamemp3+ 'tmp.mp3 tempo ' +str(speed)) + os.system('sox '+filenamemp3+' ' + + filenamemp3 + 'tmp.mp3 tempo ' + str(speed)) os.remove(filenamemp3) - os.rename(filenamemp3+'tmp.mp3', filenamemp3); + os.rename(filenamemp3+'tmp.mp3', filenamemp3) except OSError: pass speech = AudioSegment.from_mp3(filenamemp3) - if silence > 0 : + if silence > 0: start_silence = AudioSegment.silent(duration=silence) speech = start_silence + speech - speech.export(filenamemp3, format="mp3", bitrate=quality, tags={'albumartist': 'Jeedom', 'title': 'TTS', 'artist':'Jeedom'}, parameters=["-ac", "1", "-ar", samplerate,"-vol", "200"]) + speech.export(filenamemp3, format="mp3", bitrate=quality, tags={ + 'albumartist': 'Jeedom', 'title': 'TTS', 'artist': 'Jeedom'}, parameters=["-ac", "1", "-ar", samplerate, "-vol", "200"]) duration_seconds = speech.duration_seconds except Exception as e: - if os.path.isfile(filenamemp3) : + if os.path.isfile(filenamemp3): try: os.remove(filenamemp3) except OSError: pass - logging.error("CMD-TTS------Google Translate API : Cannot connect to API - failover to picotts (%s)" % str(e)) + logging.error( + "CMD-TTS------Google Translate API : Cannot connect to API - failover to picotts (%s)" % str(e)) logging.debug(traceback.format_exc()) engine = 'picotts' filenamemp3 = filenamemp3.replace(".mp3", "_failover.mp3") @@ -1509,44 +1630,49 @@ def get_tts_data(text, language, engine, speed, forcetts, calcduration, silence= language = srclanguage speed = 1.2 - elif engine == 'gttsapi' : + elif engine == 'gttsapi': ttsformat = 'text' voice = globals.tts_gapi_voice speed = float(speed) - 0.2 pitch = 0.0 volumegaindb = 0.0 - if ttsparams is not None : - if 'voice' in ttsparams : + if ttsparams is not None: + if 'voice' in ttsparams: voice = ttsparams['voice'] - if 'pitch' in ttsparams : + if 'pitch' in ttsparams: pitch = float(ttsparams['pitch']) - if 'volgain' in ttsparams : + if 'volgain' in ttsparams: volumegaindb = float(ttsparams['volgain']) - if 'usessml' in ttsparams : + if 'usessml' in ttsparams: ttsformat = 'ssml' ttstext = ttstext.replace('^', '=') # ttstext = urllib.parse.quote_plus(ttstext) - success=True + success = True try: gctts = gcloudTTS(globals.tts_gapi_key) - rawttsdata = gctts.tts(voice, voice[:5], ttstext, ttsformat, speed, pitch, volumegaindb, 'LINEAR16') + rawttsdata = gctts.tts( + voice, voice[:5], ttstext, ttsformat, speed, pitch, volumegaindb, 'LINEAR16') except gcloudTTSError as e: - success=False - logging.error("CMD-TTS------Google Cloud TextToSpeech API Error : %s" % str(e)) - except : - success=False - logging.debug("CMD-TTS------Google Cloud TextToSpeech API : Unknown error") + success = False + logging.error( + "CMD-TTS------Google Cloud TextToSpeech API Error : %s" % str(e)) + except Exception: + success = False + logging.debug( + "CMD-TTS------Google Cloud TextToSpeech API : Unknown error") logging.debug(traceback.format_exc()) - if success==True : + if success is True: speech = AudioSegment(data=rawttsdata) - if silence > 0 : + if silence > 0: start_silence = AudioSegment.silent(duration=silence) speech = start_silence + speech - #speech.export(filenamemp3, format="mp3", bitrate=quality, tags={'albumartist': 'Jeedom', 'title': 'TTS', 'artist':'Jeedom'}, parameters=["-ac", "1", "-ar", samplerate,"-vol", "200"]) - speech.export(filenamemp3, format="mp3", tags={'albumartist': 'Jeedom', 'title': 'TTS', 'artist':'Jeedom'}, parameters=["-ac", "1", "-vol", "200"]) + # speech.export(filenamemp3, format="mp3", bitrate=quality, tags={'albumartist': 'Jeedom', 'title': 'TTS', 'artist':'Jeedom'}, parameters=["-ac", "1", "-ar", samplerate,"-vol", "200"]) + speech.export(filenamemp3, format="mp3", tags={ + 'albumartist': 'Jeedom', 'title': 'TTS', 'artist': 'Jeedom'}, parameters=["-ac", "1", "-vol", "200"]) duration_seconds = speech.duration_seconds - else : - logging.error("CMD-TTS------Google Cloud TextToSpeech API : Error while using Google Cloud TextToSpeech API - failover to picotts") + else: + logging.error( + "CMD-TTS------Google Cloud TextToSpeech API : Error while using Google Cloud TextToSpeech API - failover to picotts") engine = 'picotts' filenamemp3 = filenamemp3.replace(".mp3", "_failover.mp3") file = file + '_failover' @@ -1555,9 +1681,10 @@ def get_tts_data(text, language, engine, speed, forcetts, calcduration, silence= elif engine == 'jeedomtts' or engine == 'ttswebserver': speed = float(speed) - proxyttsfile = globals.JEEDOM_COM.proxytts(engine, ttstext, {'language': language}); + proxyttsfile = globals.JEEDOM_COM.proxytts( + engine, ttstext, {'language': language}) if proxyttsfile is not None: - with open(filenamemp3 , 'wb') as f: + with open(filenamemp3, 'wb') as f: f.write(proxyttsfile) # if speed!=1: # try: @@ -1567,13 +1694,15 @@ def get_tts_data(text, language, engine, speed, forcetts, calcduration, silence= # except OSError: # pass speech = AudioSegment.from_mp3(filenamemp3) - if silence > 0 : + if silence > 0: start_silence = AudioSegment.silent(duration=silence) speech = start_silence + speech - speech.export(filenamemp3, format="mp3", bitrate=quality, tags={'albumartist': 'Jeedom', 'title': 'TTS', 'artist':'Jeedom'}, parameters=["-ac", "1", "-ar", samplerate,"-vol", "200"]) + speech.export(filenamemp3, format="mp3", bitrate=quality, tags={ + 'albumartist': 'Jeedom', 'title': 'TTS', 'artist': 'Jeedom'}, parameters=["-ac", "1", "-ar", samplerate, "-vol", "200"]) duration_seconds = speech.duration_seconds - else : - logging.error("CMD-TTS------Jeedom TTS Proxy API : Cannot connect or incorrect output - failover to picotts") + else: + logging.error( + "CMD-TTS------Jeedom TTS Proxy API : Cannot connect or incorrect output - failover to picotts") engine = 'picotts' filenamemp3 = filenamemp3.replace(".mp3", "_failover.mp3") file = file + '_failover' @@ -1582,181 +1711,205 @@ def get_tts_data(text, language, engine, speed, forcetts, calcduration, silence= if engine == 'picotts': speed = float(speed) - 0.2 - filename=os.path.join(cachepath,file+'.wav') + filename = os.path.join(cachepath, file+'.wav') # fix accent issue for picotts - ttstext = ttstext.encode('utf-8').decode('ascii','ignore') - os.system('pico2wave -l '+language+' -w '+filename+ ' "' +ttstext+ '"') + ttstext = ttstext.encode('utf-8').decode('ascii', 'ignore') + os.system('pico2wave -l '+language+' -w ' + + filename + ' "' + ttstext + '"') speech = AudioSegment.from_wav(filename) - if silence > 0 : + if silence > 0: start_silence = AudioSegment.silent(duration=silence) speech = start_silence + speech - speech.export(filenamemp3, format="mp3", bitrate=quality, tags={'albumartist': 'Jeedom', 'title': 'TTS', 'artist':'Jeedom'}, parameters=["-ac", "1", "-ar", samplerate,"-vol", "200"]) + speech.export(filenamemp3, format="mp3", bitrate=quality, tags={ + 'albumartist': 'Jeedom', 'title': 'TTS', 'artist': 'Jeedom'}, parameters=["-ac", "1", "-ar", samplerate, "-vol", "200"]) duration_seconds = speech.duration_seconds - if speed!=1: + if speed != 1: try: - os.system('sox '+filenamemp3+' '+filenamemp3+ 'tmp.mp3 tempo ' +str(speed)) + os.system('sox '+filenamemp3+' ' + + filenamemp3 + 'tmp.mp3 tempo ' + str(speed)) os.remove(filenamemp3) - os.rename(filenamemp3+'tmp.mp3', filenamemp3); + os.rename(filenamemp3+'tmp.mp3', filenamemp3) except OSError: pass - try : + try: os.remove(filename) except OSError: pass - logging.debug("CMD-TTS------Sentence: '" +ttstext+ "' ("+engine+","+language+",speed:"+"{0:.2f}".format(speed)+")") + logging.debug("CMD-TTS------Sentence: '" + ttstext + "' (" + + engine+","+language+",speed:"+"{0:.2f}".format(speed)+")") else: logging.debug("CMD-TTS------Using from cache") - if calcduration == True: - try : + if calcduration is True: + try: speech = AudioSegment.from_mp3(filenamemp3) duration_seconds = speech.duration_seconds - except : - logging.error("CMD-TTS------Exception when trying to get duration. Will try to remove file to force generation next time...") + except Exception: + logging.error( + "CMD-TTS------Exception when trying to get duration. Will try to remove file to force generation next time...") logging.debug(traceback.format_exc()) duration_seconds = 0 - try : + try: os.remove(filenamemp3) - except : + except Exception: pass else: - duration_seconds=0 - logging.debug("CMD-TTS------Sentence: '" +ttstext+ "' ("+engine+","+language+")") + duration_seconds = 0 + logging.debug("CMD-TTS------Sentence: '" + + ttstext + "' ("+engine+","+language+")") - try : # touch file so cleaning can be done later based on date - if os.stat(filenamemp3).st_mtime < (time.time() - 86400) : + try: # touch file so cleaning can be done later based on date + if os.stat(filenamemp3).st_mtime < (time.time() - 86400): os.utime(filenamemp3, None) - except : + except Exception: logging.debug("CMD-TTS------Touching file failed !") pass - urltoplay=globals.JEEDOM_WEB+'/plugins/googlecast/tmp/'+file+'.mp3' + urltoplay = globals.JEEDOM_WEB+'/plugins/googlecast/tmp/'+file+'.mp3' except Exception as e: - logging.error("CMD-TTS------Exception while generating tts file : %s" % str(e)) + logging.error( + "CMD-TTS------Exception while generating tts file : %s" % str(e)) logging.debug(traceback.format_exc()) - urltoplay=None - duration_seconds=0 - filenamemp3=None + urltoplay = None + duration_seconds = 0 + filenamemp3 = None return urltoplay, duration_seconds, filenamemp3 + def get_notif_data(mediafilename, calcduration): try: - urltoplay = globals.JEEDOM_WEB+'/plugins/googlecast/'+globals.localmedia_folder+'/'+mediafilename - filename = os.path.join(globals.localmedia_fullpath,mediafilename) - if os.path.isfile(filename) : - if calcduration : + urltoplay = globals.JEEDOM_WEB+'/plugins/googlecast/' + \ + globals.localmedia_folder+'/'+mediafilename + filename = os.path.join(globals.localmedia_fullpath, mediafilename) + if os.path.isfile(filename): + if calcduration: extension = os.path.splitext(filename)[1] - if extension.lower()=='.mp3' : + if extension.lower() == '.mp3': notifSound = AudioSegment.from_mp3(filename) - else : - notifSound = AudioSegment.from_file(filename, extension.lower().replace('.','')) + else: + notifSound = AudioSegment.from_file( + filename, extension.lower().replace('.', '')) duration_seconds = notifSound.duration_seconds else: - logging.debug("CMD-NOTIF------File doesn't exist (" + filename + ')') - urltoplay=None - duration_seconds=0 - filename=None + logging.debug( + "CMD-NOTIF------File doesn't exist (" + filename + ')') + urltoplay = None + duration_seconds = 0 + filename = None except Exception as e: logging.error("CMD-NOTIF------Error processing file (%s)" % str(e)) logging.debug(traceback.format_exc()) - urltoplay=None - duration_seconds=0 - filename=None - logging.debug("CMD-NOTIF------NOTIF debug : " + ('Unknown' if urltoplay is None else urltoplay) + ", duration: " + str(duration_seconds)) + urltoplay = None + duration_seconds = 0 + filename = None + logging.debug("CMD-NOTIF------NOTIF debug : " + + ('Unknown' if urltoplay is None else urltoplay) + ", duration: " + str(duration_seconds)) return urltoplay, duration_seconds, filename + def logByTTS(text_id): lang = globals.tts_language engine = globals.tts_engine speed = globals.tts_speed - if text_id == 'CMD_ERROR' : + if text_id == 'CMD_ERROR': text = "La commande n'a pas pu être lancée !" - else : + else: text = "Un erreur s'est produite !" - url,duration,mp3filename=get_tts_data(text, language, engine, speed, False, False, 300) - thumb=globals.JEEDOM_WEB + '/plugins/googlecast/desktop/images/tts.png' - player = jcast.loadPlayer('media', { 'quitapp' : False, 'wait': 0}) - player.play_media(url, 'audio/mp3', 'TTS', thumb=thumb, stream_type="LIVE"); - player.block_until_active(timeout=2); + url, duration, mp3filename = get_tts_data( + text, lang, engine, speed, False, False, 300) + thumb = globals.JEEDOM_WEB + '/plugins/googlecast/desktop/images/tts.png' + jcast = None # TODO: get googlecast device first + player = jcast.loadPlayer('media', {'quitapp': False, 'wait': 0}) + player.play_media(url, 'audio/mp3', 'TTS', thumb=thumb, stream_type="LIVE") + player.block_until_active(timeout=2) def gcast_prepareAppParam(params): if params is None or params == '': return '' ret = '' - s = [k for k in re.split("(,|\w*?:'.*?'|'.*?')", params) if k.strip() and k!=','] - for p in s : + s = [k for k in re.split("(,|\w*?:'.*?'|'.*?')", params) # noqa: W605 + if k.strip() and k != ','] + for p in s: p = p.strip() - s2 = [k for k in re.split("(:|'.*?'|http:.*|https:.*)", p) if k.strip() and k!=':'] + s2 = [k for k in re.split( + "(:|'.*?'|http:.*|https:.*)", p) if k.strip() and k != ':'] prefix = '' - if len(s2)==2 : + if len(s2) == 2: prefix = s2[0].strip() + '=' p = s2[1].strip() - if p.isnumeric() : + if p.isnumeric(): ret = ret + ',' + prefix + p - elif p.lower() == 'true' or p.lower() == 'false' or p.lower() == 'none' : + elif p.lower() == 'true' or p.lower() == 'false' or p.lower() == 'none': ret = ret + ',' + prefix + p[0].upper()+p[1:] - elif p.lower() == 't' : + elif p.lower() == 't': ret = ret + ',' + prefix + 'True' - elif p.lower() == 'f' : + elif p.lower() == 'f': ret = ret + ',' + prefix + 'False' - else : - if p.startswith( "'" ) and p.endswith("'") : # if starts already with simple quote + else: + # if starts already with simple quote + if p.startswith("'") and p.endswith("'"): withoutQuote = p[1:-1].lower() - if withoutQuote.isnumeric() : + if withoutQuote.isnumeric(): ret = ret + ',' + prefix + withoutQuote - elif withoutQuote=='true' or withoutQuote=='false' or withoutQuote=='none' : - ret = ret + ',' + prefix + withoutQuote[0].upper()+withoutQuote[1:] - else : + elif withoutQuote == 'true' or withoutQuote == 'false' or withoutQuote == 'none': + ret = ret + ',' + prefix + \ + withoutQuote[0].upper()+withoutQuote[1:] + else: ret = ret + ',' + prefix + p - else : - ret = ret + ',' + prefix + '"'+ p +'"' # else add quotes - retval=ret[1:].replace(')', '') + else: + ret = ret + ',' + prefix + '"' + p + '"' # else add quotes + retval = ret[1:].replace(')', '') logging.debug("PARAMPARSER---- Returned: " + str(retval)) return retval def start(cycle=2): jeedom_socket.open() - logging.info("GLOBAL------Socket started and waiting for messages from Jeedom...") - #logging.info("GLOBAL------Waiting for messages...") - thread.start_new_thread( read_socket, (globals.cycle_event,)) - globals.JEEDOM_COM.send_change_immediate({'started' : 1,'source' : globals.daemonname}); + logging.info( + "GLOBAL------Socket started and waiting for messages from Jeedom...") + # logging.info("GLOBAL------Waiting for messages...") + thread.start_new_thread(read_socket, (globals.cycle_event,)) + globals.JEEDOM_COM.send_change_immediate( + {'started': 1, 'source': globals.daemonname}) try: generate_warmupnotif() - except: + except Exception: pass try: - while not globals.IS_SHUTTINGDOWN : + while not globals.IS_SHUTTINGDOWN: try: current_time = int(time.time()) - if globals.LEARN_MODE and (globals.LEARN_BEGIN+globals.LEARN_TIMEOUT) < current_time : + if globals.LEARN_MODE and (globals.LEARN_BEGIN+globals.LEARN_TIMEOUT) < current_time: globals.LEARN_MODE = False globals.ZEROCONF_RESTART = True globals.SCAN_LAST = 0 - logging.info('HEARTBEAT------Quitting learn mode (90s elapsed)') - globals.JEEDOM_COM.send_change_immediate({'learn_mode' : 0,'source' : globals.daemonname}) - - if (globals.LAST_BEAT + globals.HEARTBEAT_FREQUENCY/2) < current_time : - globals.JEEDOM_COM.send_change_immediate({'heartbeat' : 1,'source' : globals.daemonname}) + logging.info( + 'HEARTBEAT------Quitting learn mode (90s elapsed)') + globals.JEEDOM_COM.send_change_immediate( + {'learn_mode': 0, 'source': globals.daemonname}) + + if (globals.LAST_BEAT + globals.HEARTBEAT_FREQUENCY/2) < current_time: + globals.JEEDOM_COM.send_change_immediate( + {'heartbeat': 1, 'source': globals.daemonname}) globals.LAST_BEAT = current_time - if not globals.SCAN_PENDING : - if globals.LEARN_MODE : - thread.start_new_thread( scanner, ('learnmode',)) - elif (current_time - globals.SCAN_LAST) > globals.SCAN_FREQUENCY : - thread.start_new_thread( scanner, ('schedule',)) + if not globals.SCAN_PENDING: + if globals.LEARN_MODE: + thread.start_new_thread(scanner, ('learnmode',)) + elif (current_time - globals.SCAN_LAST) > globals.SCAN_FREQUENCY: + thread.start_new_thread(scanner, ('schedule',)) - if (current_time - globals.NOWPLAYING_LAST)>globals.NOWPLAYING_FREQUENCY/2 and not globals.LEARN_MODE: - for uuid in globals.GCAST_DEVICES : + if (current_time - globals.NOWPLAYING_LAST) > globals.NOWPLAYING_FREQUENCY/2 and not globals.LEARN_MODE: + for uuid in globals.GCAST_DEVICES: globals.GCAST_DEVICES[uuid].sendNowPlaying_heartbeat() globals.NOWPLAYING_LAST = current_time time.sleep(cycle) - except Exception as e: + except Exception: logging.error("GLOBAL------Exception on main loop") except KeyboardInterrupt: @@ -1765,95 +1918,111 @@ def start(cycle=2): def read_socket(cycle): - while not globals.IS_SHUTTINGDOWN : + while not globals.IS_SHUTTINGDOWN: try: global JEEDOM_SOCKET_MESSAGE if not JEEDOM_SOCKET_MESSAGE.empty(): - logging.debug("SOCKET-READ------Message received in socket JEEDOM_SOCKET_MESSAGE") + logging.debug( + "SOCKET-READ------Message received in socket JEEDOM_SOCKET_MESSAGE") message = json.loads(JEEDOM_SOCKET_MESSAGE.get()) if message['apikey'] != globals.apikey: - logging.error("SOCKET-READ------Invalid apikey from socket : " + str(message)) + logging.error( + "SOCKET-READ------Invalid apikey from socket : " + str(message)) return - logging.debug('SOCKET-READ------Received command from jeedom : '+str(message['cmd'])) + logging.debug( + 'SOCKET-READ------Received command from jeedom : '+str(message['cmd'])) if message['cmd'] == 'add': - logging.debug('SOCKET-READ------Add device : '+str(message['device'])) + logging.debug( + 'SOCKET-READ------Add device : '+str(message['device'])) if 'uuid' in message['device']: uuid = message['device']['uuid'] - if uuid not in globals.KNOWN_DEVICES : + if uuid not in globals.KNOWN_DEVICES: globals.KNOWN_DEVICES[uuid] = { 'uuid': uuid, 'status': {}, 'typemsg': 'info', - 'lastOnline':0, 'online':False, + 'lastOnline': 0, 'online': False, 'lastSent': 0, 'lastOfflineSent': 0, - 'options' : message['device']['options'] + 'options': message['device']['options'] } globals.SCAN_LAST = 0 globals.ZEROCONF_RESTART = True elif message['cmd'] == 'remove': - logging.debug('SOCKET-READ------Remove device : '+str(message['device'])) + logging.debug( + 'SOCKET-READ------Remove device : '+str(message['device'])) if 'uuid' in message['device']: uuid = message['device']['uuid'] - if uuid in globals.NOWPLAYING_DEVICES : + if uuid in globals.NOWPLAYING_DEVICES: del globals.NOWPLAYING_DEVICES[uuid] - if uuid in globals.GCAST_DEVICES : + if uuid in globals.GCAST_DEVICES: globals.GCAST_DEVICES[uuid].disconnect() - if uuid in globals.KNOWN_DEVICES : + if uuid in globals.KNOWN_DEVICES: del globals.KNOWN_DEVICES[uuid] globals.SCAN_LAST = 0 elif message['cmd'] == 'nowplaying': if 'uuid' in message: uuid = message['uuid'] globals.NOWPLAYING_DEVICES[uuid] = int(time.time()) - if uuid in globals.GCAST_DEVICES : - logging.debug('SOCKET-READ------Now playing activated for '+uuid) + if uuid in globals.GCAST_DEVICES: + logging.debug( + 'SOCKET-READ------Now playing activated for '+uuid) globals.GCAST_DEVICES[uuid].startNowPlaying() - else : - logging.debug('SOCKET-READ------Now playing for ' +uuid+ ' not activated because is offline') + else: + logging.debug( + 'SOCKET-READ------Now playing for ' + uuid + ' not activated because is offline') elif message['cmd'] == 'learnin': logging.info('SOCKET-READ------Enter in learn mode') globals.LEARN_MODE = True globals.ZEROCONF_RESTART = True globals.LEARN_BEGIN = int(time.time()) - globals.JEEDOM_COM.send_change_immediate({'learn_mode' : 1,'source' : globals.daemonname}); + globals.JEEDOM_COM.send_change_immediate( + {'learn_mode': 1, 'source': globals.daemonname}) elif message['cmd'] == 'learnout': logging.info('SOCKET-READ------Leave learn mode') globals.LEARN_MODE = False - globals.JEEDOM_COM.send_change_immediate({'learn_mode' : 0,'source' : globals.daemonname}); + globals.JEEDOM_COM.send_change_immediate( + {'learn_mode': 0, 'source': globals.daemonname}) elif message['cmd'] == 'refresh': - logging.debug('SOCKET-READ------Attempt a refresh on a device') + logging.debug( + 'SOCKET-READ------Attempt a refresh on a device') uuid = message['device']['uuid'] - if uuid in globals.GCAST_DEVICES : + if uuid in globals.GCAST_DEVICES: globals.GCAST_DEVICES[uuid].sendDeviceStatus() elif message['cmd'] == 'cleanttscache': logging.debug('SOCKET-READ------Clean TTS cache') - if 'days' in message : + if 'days' in message: cleanCache(int(message['days'])) - else : + else: cleanCache() elif message['cmd'] == 'refreshall': - logging.debug('SOCKET-READ------Attempt a refresh on all devices') - for uuid in globals.GCAST_DEVICES : + logging.debug( + 'SOCKET-READ------Attempt a refresh on all devices') + for uuid in globals.GCAST_DEVICES: globals.GCAST_DEVICES[uuid].sendDeviceStatus() elif message['cmd'] == 'action': - logging.debug('SOCKET-READ------Attempt an action on a device') - thread.start_new_thread( action_handler, (message,)) + logging.debug( + 'SOCKET-READ------Attempt an action on a device') + thread.start_new_thread(action_handler, (message,)) logging.debug('SOCKET-READ------Action Thread Launched') elif message['cmd'] == 'logdebug': - logging.info('SOCKET-READ------Passage du demon en mode debug force') + logging.info( + 'SOCKET-READ------Passage du demon en mode debug force') log = logging.getLogger() for hdlr in log.handlers[:]: log.removeHandler(hdlr) jeedom_utils.set_log_level('debug') logging.debug('SOCKET-READ------<----- La preuve ;)') elif message['cmd'] == 'lognormal': - logging.info('SOCKET-READ------Passage du demon en mode de log initial') + logging.info( + 'SOCKET-READ------Passage du demon en mode de log initial') log = logging.getLogger() for hdlr in log.handlers[:]: log.removeHandler(hdlr) jeedom_utils.set_log_level(globals.log_level) elif message['cmd'] == 'stop': - logging.info('SOCKET-READ------Arret du demon sur demande socket') - globals.JEEDOM_COM.send_change_immediate({'learn_mode' : 0,'source' : globals.daemonname}); + logging.info( + 'SOCKET-READ------Arret du demon sur demande socket') + globals.JEEDOM_COM.send_change_immediate( + {'learn_mode': 0, 'source': globals.daemonname}) time.sleep(2) shutdown() except Exception as e: @@ -1870,15 +2039,19 @@ def zeroconfMonitoring_start(): def ccdiscovery_callback(chromecast): cast = JeedomChromeCast(chromecast, scan_mode=True) uuid = cast.uuid - logging.debug("ZEROCONF------ Signal detected from chromecast on zeroconf network : " + cast.friendly_name + "") + logging.debug( + "ZEROCONF------ Signal detected from chromecast on zeroconf network : " + cast.friendly_name + "") if uuid not in globals.GCAST_DEVICES: - logging.debug("ZEROCONF------ Signal from chromecast will be processed soon (" + cast.friendly_name + ")") + logging.debug( + "ZEROCONF------ Signal from chromecast will be processed soon (" + cast.friendly_name + ")") globals.SCAN_LAST = 0 globals.NETDISCOVERY_DEVICES[cast.uuid] = cast - globals.NETDISCOVERY_STOPFN = pychromecast.get_chromecasts(tries=1, retry_wait=2, timeout=globals.SCAN_TIMEOUT, blocking=False, callback=ccdiscovery_callback) + globals.NETDISCOVERY_STOPFN = pychromecast.get_chromecasts( + tries=1, retry_wait=2, timeout=globals.SCAN_TIMEOUT, blocking=False, callback=ccdiscovery_callback) except Exception as e: - logging.error("ZEROCONF START------Exception on zeroconf monitoring : %s" % str(e)) + logging.error( + "ZEROCONF START------Exception on zeroconf monitoring : %s" % str(e)) logging.debug(traceback.format_exc()) @@ -1892,9 +2065,11 @@ def zeroconfMonitoring_stop(): except Exception as e: # globals.NETDISCOVERY_DEVICES = {} - logging.error("ZEROCONF STOP------Exception on netdiscovery : %s" % str(e)) + logging.error( + "ZEROCONF STOP------Exception on netdiscovery : %s" % str(e)) logging.debug(traceback.format_exc()) + def scanner(name='UNKNOWN SOURCE'): try: logging.debug("SCANNER------ Start scanning... (" + name + ")") @@ -1903,121 +2078,130 @@ def scanner(name='UNKNOWN SOURCE'): scanForced = False discoveryMode = False - if (int(time.time())-globals.DISCOVERY_LAST)>globals.DISCOVERY_FREQUENCY : + if (int(time.time())-globals.DISCOVERY_LAST) > globals.DISCOVERY_FREQUENCY: scanForced = True discoveryMode = True - if globals.ZEROCONF_RESTART==True : + if globals.ZEROCONF_RESTART is True: globals.ZEROCONF_RESTART = False scanForced = True - if scanForced==True : + if scanForced is True: zeroconfMonitoring_stop() zeroconfMonitoring_start() time.sleep(1) # go through discovered devices in case new appeared tobecleaned = [] - for uuid in globals.NETDISCOVERY_DEVICES : + for uuid in globals.NETDISCOVERY_DEVICES: cast = globals.NETDISCOVERY_DEVICES[uuid] uuid = cast.uuid current_time = int(time.time()) - if uuid in globals.KNOWN_DEVICES : + if uuid in globals.KNOWN_DEVICES: globals.KNOWN_DEVICES[uuid]['online'] = True globals.KNOWN_DEVICES[uuid]['lastScan'] = current_time globals.KNOWN_DEVICES[uuid]["lastOnline"] = current_time - if uuid not in globals.GCAST_DEVICES : - logging.info("SCANNER------ Adding chromecast : " + cast.friendly_name) - globals.GCAST_DEVICES[uuid] = JeedomChromeCast(cast.gcast, globals.KNOWN_DEVICES[uuid]["options"]) + if uuid not in globals.GCAST_DEVICES: + logging.info( + "SCANNER------ Adding chromecast : " + cast.friendly_name) + globals.GCAST_DEVICES[uuid] = JeedomChromeCast( + cast.gcast, globals.KNOWN_DEVICES[uuid]["options"]) - if uuid in globals.NOWPLAYING_DEVICES : - if (current_time-globals.NOWPLAYING_DEVICES[uuid]) > globals.NOWPLAYING_TIMEOUT : + if uuid in globals.NOWPLAYING_DEVICES: + if (current_time-globals.NOWPLAYING_DEVICES[uuid]) > globals.NOWPLAYING_TIMEOUT: del globals.NOWPLAYING_DEVICES[uuid] globals.GCAST_DEVICES[uuid].stopNowPlaying() - else : + else: globals.GCAST_DEVICES[uuid].startNowPlaying() globals.GCAST_DEVICES[uuid].sendDeviceStatusIfNew() - else : - if globals.LEARN_MODE : - data = {'friendly_name':cast.friendly_name, 'uuid': uuid, 'lastScan': current_time } + else: + if globals.LEARN_MODE: + data = {'friendly_name': cast.friendly_name, + 'uuid': uuid, 'lastScan': current_time} data['def'] = cast.getDefinition() data['status'] = cast.getStatus() - data['learn'] = 1; - logging.info("SCANNER------ LEARN MODE : New device : " + uuid + ' (' + data["friendly_name"] + ')') - globals.JEEDOM_COM.add_changes('devices::'+uuid,data) + data['learn'] = 1 + logging.info("SCANNER------ LEARN MODE : New device : " + + uuid + ' (' + data["friendly_name"] + ')') + globals.JEEDOM_COM.add_changes('devices::'+uuid, data) - elif (current_time-globals.DISCOVERY_LAST)>globals.DISCOVERY_FREQUENCY : - logging.debug("SCANNER------ DISCOVERY MODE : New device : " + uuid + ' (' + cast.friendly_name + ')') - globals.JEEDOM_COM.send_change_immediate({'discovery' : 1, 'uuid' : uuid, 'friendly_name' : cast.friendly_name}) + elif (current_time-globals.DISCOVERY_LAST) > globals.DISCOVERY_FREQUENCY: + logging.debug("SCANNER------ DISCOVERY MODE : New device : " + + uuid + ' (' + cast.friendly_name + ')') + globals.JEEDOM_COM.send_change_immediate( + {'discovery': 1, 'uuid': uuid, 'friendly_name': cast.friendly_name}) tobecleaned.append(uuid) # memory cleaning for uuid in list(globals.NETDISCOVERY_DEVICES.keys()): - if uuid in tobecleaned : + if uuid in tobecleaned: globals.NETDISCOVERY_DEVICES[uuid].disconnect() - if uuid in globals.NETDISCOVERY_DEVICES : + if uuid in globals.NETDISCOVERY_DEVICES: del globals.NETDISCOVERY_DEVICES[uuid] del tobecleaned # loop through all known devices to find those not connected - for known in globals.KNOWN_DEVICES : + for known in globals.KNOWN_DEVICES: current_time = int(time.time()) is_not_available = True - if known in globals.GCAST_DEVICES : - if globals.GCAST_DEVICES[known].is_connected==True : + if known in globals.GCAST_DEVICES: + if globals.GCAST_DEVICES[known].is_connected is True: is_not_available = False - else : + else: # something went wrong so disconnect completely globals.GCAST_DEVICES[known].disconnect() - if is_not_available==True : + if is_not_available is True: logging.debug("SCANNER------No connection to device " + known) - if globals.KNOWN_DEVICES[known]['online']==True : - logging.info("SCANNER------Connection lost to device " + known) + if globals.KNOWN_DEVICES[known]['online'] is True: + logging.info( + "SCANNER------Connection lost to device " + known) globals.KNOWN_DEVICES[known]['lastScan'] = current_time - if ( globals.KNOWN_DEVICES[known]['online']==True or (current_time-globals.KNOWN_DEVICES[known]['lastOfflineSent'])>globals.LOSTDEVICE_RESENDNOTIFDELAY ) : + if (globals.KNOWN_DEVICES[known]['online'] is True or (current_time-globals.KNOWN_DEVICES[known]['lastOfflineSent']) > globals.LOSTDEVICE_RESENDNOTIFDELAY): globals.KNOWN_DEVICES[known]['online'] = False globals.KNOWN_DEVICES[known]['lastOfflineSent'] = current_time - globals.KNOWN_DEVICES[known]['status'] = status = { - "uuid" : known, - "is_stand_by" : False, "is_active_input" : False, - "display_name" : globals.DEFAULT_NODISPLAY, "status_text" : globals.DEFAULT_NOSTATUS, - "app_id" : "", "icon_url" : "", "is_busy" : False, - "title" : "", "artist" : "", "series_title": "", "stream_type" : "", "player_state" : "", + globals.KNOWN_DEVICES[known]['status'] = { + "uuid": known, + "is_stand_by": False, "is_active_input": False, + "display_name": globals.DEFAULT_NODISPLAY, "status_text": globals.DEFAULT_NOSTATUS, + "app_id": "", "icon_url": "", "is_busy": False, + "title": "", "artist": "", "series_title": "", "stream_type": "", "player_state": "", } - #globals.JEEDOM_COM.add_changes('devices::'+known, globals.KNOWN_DEVICES[known]) - globals.JEEDOM_COM.send_change_immediate_device(known, globals.KNOWN_DEVICES[known]) + # globals.JEEDOM_COM.add_changes('devices::'+known, globals.KNOWN_DEVICES[known]) + globals.JEEDOM_COM.send_change_immediate_device( + known, globals.KNOWN_DEVICES[known]) globals.KNOWN_DEVICES[known]['lastSent'] = current_time if known in globals.NOWPLAYING_DEVICES: del globals.NOWPLAYING_DEVICES[known] data = { - "uuid" : known, - "online" : False, "friendly_name" : "", - "is_active_input" : False, "is_stand_by" : False, - "display_name" : globals.DEFAULT_NODISPLAY, "status_text" : globals.DEFAULT_NOSTATUS, - "app_id" : "", "icon_url" : "", "is_busy" : False, "title" : "", - "album_artist" : "", "metadata_type" : "", - "album_name" : "", "current_time" : 0, - "artist" : "", "image" : None, + "uuid": known, + "online": False, "friendly_name": "", + "is_active_input": False, "is_stand_by": False, + "display_name": globals.DEFAULT_NODISPLAY, "status_text": globals.DEFAULT_NOSTATUS, + "app_id": "", "icon_url": "", "is_busy": False, "title": "", + "album_artist": "", "metadata_type": "", + "album_name": "", "current_time": 0, + "artist": "", "image": None, "series_title": "", "season": "", "episode": "", - "stream_type" : "", "track" : "", - "player_state" : "", "supported_media_commands" : 0, - "supports_pause" : "", "duration": 0, + "stream_type": "", "track": "", + "player_state": "", "supported_media_commands": 0, + "supports_pause": "", "duration": 0, "content_type": "", "idle_reason": "" } - globals.JEEDOM_COM.send_change_immediate({'uuid' : known, 'nowplaying':data}); + globals.JEEDOM_COM.send_change_immediate( + {'uuid': known, 'nowplaying': data}) - else : + else: globals.KNOWN_DEVICES[known]["lastScan"] = current_time - if discoveryMode==True : + if discoveryMode is True: globals.DISCOVERY_LAST = int(time.time()) except Exception as e: @@ -2027,99 +2211,116 @@ def scanner(name='UNKNOWN SOURCE'): globals.SCAN_LAST = int(time.time()) globals.SCAN_PENDING = False + def sendErrorDeviceStatus(uuid, message, online=True): # send to plugin errorstatus = { - "uuid" : uuid, "display_name" : message, "status_text" : message + "uuid": uuid, "display_name": message, "status_text": message } - globals.JEEDOM_COM.add_changes('devices::'+uuid, {'uuid': uuid, 'typemsg': 'error', 'status': errorstatus}) + globals.JEEDOM_COM.add_changes( + 'devices::'+uuid, {'uuid': uuid, 'typemsg': 'error', 'status': errorstatus}) # send to now playing widget data = { - "uuid" : uuid, "online" : online, - "is_active_input" : False, "is_stand_by" : False, - "display_name" : message, "status_text" : message, "player_state" : message, - "title" : "", "album_artist" : "", - "album_name" : "", "current_time" : 0, - "artist" : "", "image" : None, + "uuid": uuid, "online": online, + "is_active_input": False, "is_stand_by": False, + "display_name": message, "status_text": message, "player_state": message, + "title": "", "album_artist": "", + "album_name": "", "current_time": 0, + "artist": "", "image": None, 'series_title': "", 'season': "", 'episode': "", - "stream_type" : "", "track" : "" + "stream_type": "", "track": "" } - globals.JEEDOM_COM.send_change_immediate({'uuid' : uuid, 'nowplaying':data}); + globals.JEEDOM_COM.send_change_immediate( + {'uuid': uuid, 'nowplaying': data}) + + +memory_last_use = 0 +memory_last_time = int(time.time()) +memory_first_time = int(time.time()) + -memory_last_use=0 -memory_last_time=int(time.time()) -memory_first_time=int(time.time()) def show_memory_usage(): - if logging.getLogger().isEnabledFor(logging.DEBUG) : + if logging.getLogger().isEnabledFor(logging.DEBUG): usage = resource.getrusage(resource.RUSAGE_SELF) try: global memory_last_use, memory_last_time, memory_first_time ru_utime = getattr(usage, 'ru_utime') ru_stime = getattr(usage, 'ru_stime') ru_maxrss = getattr(usage, 'ru_maxrss') - total=ru_utime+ru_stime - curtime=int(time.time()) - timedif=curtime-memory_last_time - timediftotal=curtime-memory_first_time - logging.debug(' MEMORY---- Total CPU time used : %.3fs (%.2f%%) | Last %i sec : %.3fs (%.2f%%) | Memory : %s Mo' % (total, total/timediftotal*100, timedif, total-memory_last_use, (total-memory_last_use)/timedif*100, int(round(ru_maxrss/1000)))) - memory_last_use=total - memory_last_time=curtime - except: + total = ru_utime+ru_stime + curtime = int(time.time()) + timedif = curtime-memory_last_time + timediftotal = curtime-memory_first_time + logging.debug(' MEMORY---- Total CPU time used : %.3fs (%.2f%%) | Last %i sec : %.3fs (%.2f%%) | Memory : %s Mo' % ( + total, total/timediftotal*100, timedif, total-memory_last_use, (total-memory_last_use)/timedif*100, int(round(ru_maxrss/1000)))) + memory_last_use = total + memory_last_time = curtime + except Exception: pass + def cleanCache(nbDays=0): - if nbDays == 0 : # clean entire directory including containing folder + if nbDays == 0: # clean entire directory including containing folder try: if os.path.exists(globals.tts_cachefoldertmp): shutil.rmtree(globals.tts_cachefoldertmp) generate_warmupnotif() - except: - logging.warn("CLEAN CACHE------Error while cleaning cache entirely") + except Exception: + logging.warn( + "CLEAN CACHE------Error while cleaning cache entirely") pass - else : # clean only files older than X days + else: # clean only files older than X days now = time.time() path = globals.tts_cachefoldertmp try: for f in os.listdir(path): - logging.debug("CLEAN CACHE------Age for " + f + " is "+ str( int((now - (os.stat(os.path.join(path,f)).st_mtime)) / 86400 )) + " days") - if os.stat(os.path.join(path,f)).st_mtime < (now - (nbDays * 86400)) : + logging.debug("CLEAN CACHE------Age for " + f + " is " + str( + int((now - (os.stat(os.path.join(path, f)).st_mtime)) / 86400)) + " days") + if os.stat(os.path.join(path, f)).st_mtime < (now - (nbDays * 86400)): os.remove(os.path.join(path, f)) - logging.debug("CLEAN CACHE------Removed " + f + " due to expiration ("+ str(nbDays)+ " days)") + logging.debug("CLEAN CACHE------Removed " + f + + " due to expiration (" + str(nbDays) + " days)") generate_warmupnotif() - except: - logging.warn("CLEAN CACHE------Error while cleaning cache based on date number") + except Exception: + logging.warn( + "CLEAN CACHE------Error while cleaning cache based on date number") pass + def handler(signum=None, frame=None): logging.debug("GLOBAL------Signal %i caught, exiting..." % int(signum)) shutdown() + def shutdown(): logging.debug("GLOBAL------Shutdown") globals.IS_SHUTTINGDOWN = True logging.debug("GLOBAL------Removing PID file " + str(globals.pidfile)) try: os.remove(globals.pidfile) - except: + except Exception: pass try: - globals.JEEDOM_COM.send_change_immediate({'stopped' : 1,'source' : globals.daemonname}); + globals.JEEDOM_COM.send_change_immediate( + {'stopped': 1, 'source': globals.daemonname}) zeroconfMonitoring_stop() - for uuid in globals.GCAST_DEVICES : + for uuid in globals.GCAST_DEVICES: globals.GCAST_DEVICES[uuid].disconnect() time.sleep(0.5) jeedom_socket.close() logging.debug("GLOBAL------Shutdown completed !") - except: + except Exception: pass logging.debug("Exit 0") sys.stdout.flush() os._exit(0) + # ------------------------------------------- # ------ PROGRAM STARTS HERE ---------------- # ------------------------------------------- -parser = argparse.ArgumentParser(description='GoogleCast Daemon for Jeedom plugin') +parser = argparse.ArgumentParser( + description='GoogleCast Daemon for Jeedom plugin') parser.add_argument("--loglevel", help="Log Level for the daemon", type=str) parser.add_argument("--pidfile", help="PID filname", type=str) parser.add_argument("--callback", help="Callback url", type=str) @@ -2130,7 +2331,8 @@ def shutdown(): parser.add_argument("--ttscache", help="Use cache", type=str) parser.add_argument("--ttsspeed", help="TTS speech speed", type=str) parser.add_argument("--ttsgapikey", help="TTS Google Speech API Key", type=str) -parser.add_argument("--gcttsvoice", help="TTS Google Speech API default voice", type=str) +parser.add_argument( + "--gcttsvoice", help="TTS Google Speech API default voice", type=str) parser.add_argument("--socketport", help="Socket Port", type=str) parser.add_argument("--sockethost", help="Socket Host", type=str) parser.add_argument("--daemonname", help="Daemon Name", type=str) @@ -2138,8 +2340,10 @@ def shutdown(): parser.add_argument("--scanfrequency", help="Frequency for scan", type=str) parser.add_argument("--cycle", help="Cycle to send/receive event", type=str) parser.add_argument("--cyclemain", help="Cycle for main loop", type=str) -parser.add_argument("--cyclefactor", help="Factor for event cycles (default=1)", type=str) -parser.add_argument("--defaultstatus", help="Returned display string", type=str) +parser.add_argument( + "--cyclefactor", help="Factor for event cycles (default=1)", type=str) +parser.add_argument("--defaultstatus", + help="Returned display string", type=str) args = parser.parse_args() @@ -2164,10 +2368,10 @@ def shutdown(): if args.ttsspeed: globals.tts_speed = args.ttsspeed if args.ttscache: - globals.tts_cacheenabled = False if int(args.ttscache)==0 else True + globals.tts_cacheenabled = False if int(args.ttscache) == 0 else True if args.ttsgapikey: globals.tts_gapi_key = args.ttsgapikey - if globals.tts_gapi_key != 'none' : + if globals.tts_gapi_key != 'none': globals.tts_gapi_haskey = True if args.gcttsvoice: globals.tts_gapi_voice = args.gcttsvoice @@ -2186,9 +2390,10 @@ def shutdown(): if args.defaultstatus: globals.DEFAULT_NOSTATUS = args.defaultstatus -if globals.cycle_factor==0: - globals.cycle_factor=1 -globals.NOWPLAYING_FREQUENCY = int(globals.NOWPLAYING_FREQUENCY*globals.cycle_factor) +if globals.cycle_factor == 0: + globals.cycle_factor = 1 +globals.NOWPLAYING_FREQUENCY = int( + globals.NOWPLAYING_FREQUENCY*globals.cycle_factor) globals.SCAN_FREQUENCY = int(globals.SCAN_FREQUENCY*globals.cycle_factor) globals.socketport = int(globals.socketport) @@ -2205,22 +2410,24 @@ def shutdown(): logging.info('GLOBAL------Socket port : '+str(globals.socketport)) logging.info('GLOBAL------Socket host : '+str(globals.sockethost)) logging.info('GLOBAL------PID file : '+str(globals.pidfile)) -#logging.info('GLOBAL------Apikey : '+str(globals.apikey)) +# logging.info('GLOBAL------Apikey : '+str(globals.apikey)) logging.info('GLOBAL------Apikey : *******************************') logging.info('GLOBAL------TTS Jeedom server : '+str(globals.JEEDOM_WEB)) logging.info('GLOBAL------TTS default language : '+str(globals.tts_language)) logging.info('GLOBAL------TTS default engine : '+str(globals.tts_engine)) logging.info('GLOBAL------TTS default speech speed : '+str(globals.tts_speed)) -if globals.tts_gapi_haskey : +if globals.tts_gapi_haskey: logging.info('GLOBAL------TTS Google Speech API Key (optional) : OK') - logging.info('GLOBAL------TTS Google Speech API Voice (optional) : '+str(globals.tts_gapi_voice)) -else : + logging.info('GLOBAL------TTS Google Speech API Voice (optional) : ' + + str(globals.tts_gapi_voice)) +else: logging.info('GLOBAL------TTS Google API Key (optional) : NOK') logging.info('GLOBAL------Cache status : '+str(globals.tts_cacheenabled)) logging.info('GLOBAL------Callback : '+str(globals.callback)) logging.info('GLOBAL------Event cycle : '+str(globals.cycle_event)) logging.info('GLOBAL------Main cycle : '+str(globals.cycle_main)) -logging.info('GLOBAL------Default status message : '+str(globals.DEFAULT_NOSTATUS)) +logging.info('GLOBAL------Default status message : ' + + str(globals.DEFAULT_NOSTATUS)) logging.info('-----------------------------------------------------') signal.signal(signal.SIGINT, handler) @@ -2228,13 +2435,16 @@ def shutdown(): try: jeedom_utils.write_pid(str(globals.pidfile)) - globals.JEEDOM_COM = jeedom_com(apikey = globals.apikey,url = globals.callback,cycle=globals.cycle_event) + globals.JEEDOM_COM = jeedom_com( + apikey=globals.apikey, url=globals.callback, cycle=globals.cycle_event) if not globals.JEEDOM_COM.test(): - logging.error('GLOBAL------Network communication issues. Please fix your Jeedom network configuration.') + logging.error( + 'GLOBAL------Network communication issues. Please fix your Jeedom network configuration.') shutdown() - else : + else: logging.info('GLOBAL------Network communication to jeedom OK.') - jeedom_socket = jeedom_socket(port=globals.socketport,address=globals.sockethost) + jeedom_socket = jeedom_socket( + port=globals.socketport, address=globals.sockethost) start(globals.cycle_main) except Exception as e: diff --git a/resources/jeedom/jeedom.py b/resources/jeedom/jeedom.py index b5f698d..c4218f8 100644 --- a/resources/jeedom/jeedom.py +++ b/resources/jeedom/jeedom.py @@ -14,7 +14,6 @@ # along with Jeedom. If not, see . # -import time import logging import threading import _thread as thread @@ -22,59 +21,67 @@ from datetime import datetime import collections import os -import socket import queue import json import socketserver as SocketServer -from socketserver import (TCPServer, StreamRequestHandler) +from socketserver import (TCPServer, StreamRequestHandler) # ------------------------------------------------------------------------------ + class jeedom_com(): - def __init__(self,apikey = '',url = '',cycle = 0.5,retry = 3): + def __init__(self, apikey='', url='', cycle=0.5, retry=3): self.apikey = apikey self.url = url self.cycle = cycle self.retry = retry self.changes = {} - if cycle > 0 : + if cycle > 0: self.send_changes_async() logging.debug('Init request module v%s' % (str(requests.__version__),)) def send_changes_async(self): try: if len(self.changes) == 0: - resend_changes = threading.Timer(self.cycle, self.send_changes_async) + resend_changes = threading.Timer( + self.cycle, self.send_changes_async) resend_changes.start() return start_time = datetime.now() changes = self.changes self.changes = {} logging.debug('SENDER------Send to jeedom : '+str(changes)) - i=0 + i = 0 while i < self.retry: try: - r = requests.post(self.url + '?apikey=' + self.apikey, json=changes, timeout=(0.5, 120), verify=False) + r = requests.post(self.url + '?apikey=' + self.apikey, + json=changes, timeout=(0.5, 120), verify=False) if r.status_code == requests.codes.ok: break except Exception as error: - logging.error('SENDER------Error on send request to jeedom ' + str(error)+' retry : '+str(i)+'/'+str(self.retry)) + logging.error('SENDER------Error on send request to jeedom ' + + str(error)+' retry : '+str(i)+'/'+str(self.retry)) i = i + 1 if r.status_code != requests.codes.ok: - logging.error('SENDER------Error on send request to jeedom, return code %s' % (str(r.status_code),)) + logging.error( + 'SENDER------Error on send request to jeedom, return code %s' % (str(r.status_code),)) dt = datetime.now() - start_time - ms = (dt.days * 24 * 60 * 60 + dt.seconds) * 1000 + dt.microseconds / 1000.0 + ms = (dt.days * 24 * 60 * 60 + dt.seconds) * \ + 1000 + dt.microseconds / 1000.0 timer_duration = self.cycle - ms if timer_duration < 0.1: timer_duration = 0.1 - resend_changes = threading.Timer(timer_duration, self.send_changes_async) + resend_changes = threading.Timer( + timer_duration, self.send_changes_async) resend_changes.start() except Exception as error: - logging.error('SENDER------Critical error on send_changes_async %s' % (str(error),)) - resend_changes = threading.Timer(self.cycle, self.send_changes_async) + logging.error( + 'SENDER------Critical error on send_changes_async %s' % (str(error),)) + resend_changes = threading.Timer( + self.cycle, self.send_changes_async) resend_changes.start() - def add_changes(self,key,value): + def add_changes(self, key, value): if key.find('::') != -1: tmp_changes = {} changes = value @@ -87,127 +94,142 @@ def add_changes(self,key,value): if self.cycle <= 0: self.send_change_immediate(changes) else: - self.merge_dict(self.changes,changes) + self.merge_dict(self.changes, changes) else: if self.cycle <= 0: - self.send_change_immediate({key:value}) + self.send_change_immediate({key: value}) else: self.changes[key] = value - def send_change_immediate(self,change): - thread.start_new_thread( self.thread_change, (change,)) + def send_change_immediate(self, change): + thread.start_new_thread(self.thread_change, (change,)) - def send_change_immediate_device(self,uuid, change): - thread.start_new_thread( self.thread_change, ({'devices': {uuid: change}},)) + def send_change_immediate_device(self, uuid, change): + thread.start_new_thread( + self.thread_change, ({'devices': {uuid: change}},)) - def thread_change(self,change): + def thread_change(self, change): logging.debug('SENDER------Send to jeedom : %s' % (str(change),)) - i=0 + i = 0 while i < self.retry: try: - r = requests.post(self.url + '?apikey=' + self.apikey, json=change, timeout=(0.5, 120), verify=False) + r = requests.post(self.url + '?apikey=' + self.apikey, + json=change, timeout=(0.5, 120), verify=False) if r.status_code == requests.codes.ok: break except Exception as error: - logging.error('SENDER------Error on send request to jeedom ' + str(error)+' retry : '+str(i)+'/'+str(self.retry)) + logging.error('SENDER------Error on send request to jeedom ' + + str(error)+' retry : '+str(i)+'/'+str(self.retry)) i = i + 1 - def set_change(self,changes): + def set_change(self, changes): self.changes = changes def get_change(self): return self.changes - def merge_dict(self,d1, d2): - for k,v2 in d2.items(): - v1 = d1.get(k) # returns None if v1 has no value for this key - if ( isinstance(v1, collections.Mapping) and - isinstance(v2, collections.Mapping) ): + def merge_dict(self, d1, d2): + for k, v2 in d2.items(): + v1 = d1.get(k) # returns None if v1 has no value for this key + if (isinstance(v1, collections.Mapping) and + isinstance(v2, collections.Mapping)): self.merge_dict(v1, v2) else: d1[k] = v2 def proxytts(self, ttsengine, ttsmessage, options): filecontent = None - proxyttsdata = {'ttsproxy': ttsengine, 'ttsmsg': ttsmessage, 'options': options} + proxyttsdata = {'ttsproxy': ttsengine, + 'ttsmsg': ttsmessage, 'options': options} try: - response = requests.post(self.url + '?apikey=' + self.apikey, json=proxyttsdata, timeout=4, verify=False) + response = requests.post( + self.url + '?apikey=' + self.apikey, json=proxyttsdata, timeout=4, verify=False) filecontent = response.content if response.status_code != requests.codes.ok: filecontent = None - logging.error('SENDER------PROXYTTS Callback error: %s'% (response.status_code,)) - else : - logging.debug('SENDER------PROXYTTS Using Proxy tts request to jeedom server for ' + ttsengine + ' engine.') + logging.error('SENDER------PROXYTTS Callback error: %s' % + (response.status_code,)) + else: + logging.debug( + 'SENDER------PROXYTTS Using Proxy tts request to jeedom server for ' + ttsengine + ' engine.') if len(response.content) < 254 and os.path.exists(response.content): - logging.debug('SENDER------PROXYTTS Data returned is a file path. Downloading content now...') - fc = open(response.content,"rb") + logging.debug( + 'SENDER------PROXYTTS Data returned is a file path. Downloading content now...') + fc = open(response.content, "rb") filecontent = fc.read() fc.close() except Exception as e: - logging.error('SENDER------PROXYTTS Callback result as a unknown error: %s. '% str(e)) + logging.error( + 'SENDER------PROXYTTS Callback result as a unknown error: %s. ' % str(e)) filecontent = None return filecontent def test(self): try: - response = requests.get(self.url + '?apikey=' + self.apikey, verify=False) + response = requests.get( + self.url + '?apikey=' + self.apikey, verify=False) if response.status_code != requests.codes.ok: - logging.error('SENDER------Callback error: %s %s. Please check your network configuration page'% (response.status.code, response.status.message,)) + logging.error('SENDER------Callback error: %s %s. Please check your network configuration page' % + (response.status.code, response.status.message,)) return False except Exception as e: - logging.error('SENDER------Callback result as a unknown error: %s. Please check your network configuration page. '% str(e)) + logging.error( + 'SENDER------Callback result as a unknown error: %s. Please check your network configuration page. ' % str(e)) return False return True # ------------------------------------------------------------------------------ + class jeedom_utils(): @staticmethod - def convert_log_level(level = 'error'): + def convert_log_level(level='error'): LEVELS = {'debug': logging.DEBUG, - 'info': logging.INFO, - 'notice': logging.WARNING, - 'warning': logging.WARNING, - 'error': logging.ERROR, - 'critical': logging.CRITICAL, - 'none': logging.NOTSET} + 'info': logging.INFO, + 'notice': logging.WARNING, + 'warning': logging.WARNING, + 'error': logging.ERROR, + 'critical': logging.CRITICAL, + 'none': logging.NOTSET} return LEVELS.get(level, logging.NOTSET) @staticmethod - def set_log_level(level = 'error'): + def set_log_level(level='error'): FORMAT = '[%(asctime)-15s][%(levelname)s] : %(message)s' - if level=='default' : - level='info' - if level=='1000' : - level='critical' - if level=='none' : - level='critical' - - if level=='debug' : + if level == 'default': + level = 'info' + if level == '1000': + level = 'critical' + if level == 'none': + level = 'critical' + + if level == 'debug': logging.getLogger("pychromecast").setLevel(logging.ERROR) logging.getLogger("plexapi").setLevel(logging.DEBUG) logging.getLogger("pydub").setLevel(logging.ERROR) logging.getLogger("gtts").setLevel(logging.ERROR) logging.getLogger("requests").setLevel(logging.ERROR) logging.getLogger("urllib3").setLevel(logging.ERROR) - logging.getLogger("requests.packages.urllib3").setLevel(logging.ERROR) - else : + logging.getLogger( + "requests.packages.urllib3").setLevel(logging.ERROR) + else: logging.getLogger("pychromecast").setLevel(logging.CRITICAL) logging.getLogger("plexapi").setLevel(logging.ERROR) logging.getLogger("pydub").setLevel(logging.CRITICAL) logging.getLogger("gtts").setLevel(logging.CRITICAL) logging.getLogger("requests").setLevel(logging.CRITICAL) logging.getLogger("urllib3").setLevel(logging.CRITICAL) - logging.getLogger("requests.packages.urllib3").setLevel(logging.CRITICAL) + logging.getLogger("requests.packages.urllib3").setLevel( + logging.CRITICAL) - if level=='none' : + if level == 'none': logging.getLogger().disabled = True - else : - #logging.getLogger().disabled = False - logging.basicConfig(level=jeedom_utils.convert_log_level(level),format=FORMAT, datefmt="%Y-%m-%d %H:%M:%S") - + else: + # logging.getLogger().disabled = False + logging.basicConfig(level=jeedom_utils.convert_log_level( + level), format=FORMAT, datefmt="%Y-%m-%d %H:%M:%S") @staticmethod def write_pid(path): @@ -222,32 +244,38 @@ def write_pid(path): JEEDOM_SOCKET_MESSAGE = queue.Queue() + class jeedom_socket_handler(StreamRequestHandler): def handle(self): global JEEDOM_SOCKET_MESSAGE - logging.debug("SOCKETHANDLER------Client connected to [%s:%d]" % self.client_address) + logging.debug( + "SOCKETHANDLER------Client connected to [%s:%d]" % self.client_address) lg = self.rfile.readline().strip().decode("ascii") JEEDOM_SOCKET_MESSAGE.put(lg) - if logging.getLogger().isEnabledFor(logging.DEBUG) : + if logging.getLogger().isEnabledFor(logging.DEBUG): try: lgdebug = json.loads(lg) if lgdebug and lgdebug['apikey']: lgdebug['apikey'] = 'XXXXXXXXXXXXX' - logging.debug("SOCKETHANDLER------Message read from socket: " + json.dumps(lgdebug)) - except Exception as e: - logging.debug("SOCKETHANDLER------Message read from socket: " + lg) + logging.debug( + "SOCKETHANDLER------Message read from socket: " + json.dumps(lgdebug)) + except Exception: + logging.debug( + "SOCKETHANDLER------Message read from socket: " + lg) self.netAdapterClientConnected = False - logging.debug("SOCKETHANDLER------Client disconnected from [%s:%d]" % self.client_address) + logging.debug( + "SOCKETHANDLER------Client disconnected from [%s:%d]" % self.client_address) class jeedom_socket(): - def __init__(self,address='localhost', port=55000): + def __init__(self, address='localhost', port=55000): self.address = address self.port = port SocketServer.TCPServer.allow_reuse_address = True def open(self): - self.netAdapter = TCPServer((self.address, self.port), jeedom_socket_handler) + self.netAdapter = TCPServer( + (self.address, self.port), jeedom_socket_handler) if self.netAdapter: logging.debug("SOCKETHANDLER------Socket interface started") threading.Thread(target=self.loopNetServer, args=()).start() @@ -256,7 +284,8 @@ def open(self): def loopNetServer(self): logging.debug("SOCKETHANDLER------LoopNetServer Thread started") - logging.debug("SOCKETHANDLER------Listening on: [%s:%d]" % (self.address, self.port)) + logging.debug( + "SOCKETHANDLER------Listening on: [%s:%d]" % (self.address, self.port)) self.netAdapter.serve_forever() logging.debug("SOCKETHANDLER------LoopNetServer Thread stopped") diff --git a/tests/tools/.pylintrc b/tests/tools/.pylintrc deleted file mode 100644 index 4d21b94..0000000 --- a/tests/tools/.pylintrc +++ /dev/null @@ -1,4 +0,0 @@ -[BASIC] - -const-rgx=[a-z_][a-z0-9_]{2,30}$ -module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ diff --git a/tests/tools/.pylintrctest b/tests/tools/.pylintrctest deleted file mode 100644 index 421a173..0000000 --- a/tests/tools/.pylintrctest +++ /dev/null @@ -1,6 +0,0 @@ -[MESSAGES CONTROL] -disable=unused-argument, - missing-docstring, - too-many-public-methods, - invalid-name - \ No newline at end of file diff --git a/tests/tools/lintAllPythonFiles.sh b/tests/tools/lintAllPythonFiles.sh index 7aa7bc5..eac842e 100644 --- a/tests/tools/lintAllPythonFiles.sh +++ b/tests/tools/lintAllPythonFiles.sh @@ -1,6 +1,6 @@ #!/bin/bash -for file in `find . -name "*.py" ! -name "__init__.py"`; +for file in `find ./resources -name "*.py" ! -name "__init__.py"`; do echo "Check $file with pylint" - python3 -m pylint --rcfile=tests/tools/.pylintrc $file + python3 -m flake8 $file done diff --git a/tests/tools/setCustomMDWarnings.sh b/tests/tools/setCustomMDWarnings.sh deleted file mode 100644 index e0ebd67..0000000 --- a/tests/tools/setCustomMDWarnings.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -export MDLWAR="MD003,MD004,MD005,MD006,MD007,MD008,MD009,MD010,MD011,MD012,MD014,MD018,MD019,MD020,MD021,MD022,MD023,MD024,MD027,MD028,MD029,MD030,MD031,MD032,MD033,MD034,MD035,MD036,MD038,MD039"