Module spotify_state -> mqtt
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import config
  2. import logging
  3. import paho.mqtt.client as paho
  4. import report
  5. import socket
  6. import subprocess
  7. import time
  8. import spotipy
  9. from spotipy.oauth2 import SpotifyClientCredentials
  10. import config
  11. import json
  12. try:
  13. from config import APP_NAME as ROOT_LOGGER_NAME
  14. except ImportError:
  15. ROOT_LOGGER_NAME = 'root'
  16. logger = logging.getLogger(ROOT_LOGGER_NAME).getChild('main')
  17. class librespot(object):
  18. ON_CMD = ['play', ]
  19. OFF_CMD = ['pause', 'stop', ]
  20. def __init__(self, state_callback, title_callback):
  21. logger.info("Starting Librespot...")
  22. self.__state_callback__ = state_callback
  23. self.__title_callback__ = title_callback
  24. self.__process__ = subprocess.Popen(["librespot", "-v", "--name", config.DEVICE_NAME],
  25. shell=False,
  26. # We pipe the output to an internal pipe
  27. stdout=subprocess.PIPE,
  28. stderr=subprocess.STDOUT)
  29. self.__state__ = None
  30. self.__preload_state__ = False
  31. self.__title__ = None
  32. self.__title_preload__ = None
  33. self.__title_published__ = None
  34. self.set_state(False)
  35. self.set_title("")
  36. def run(self):
  37. while True:
  38. output = self.__process__.stdout.readline()
  39. # Polling returns None when the program is still running, return_code otherwise
  40. return_code = self.__process__.poll()
  41. if return_code is not None:
  42. self.__process__.close()
  43. # Program ended, get exit/return code
  44. raise RuntimeError("Command '{}' finished with exit code {}".format(command, return_code))
  45. # If the output is not empty, feed it to the function, strip the newline first
  46. if output:
  47. out_txt = output.decode('utf-8').strip('\n').strip()
  48. out_txt = out_txt[out_txt.find(']') + 2:]
  49. #logger.debug("librespot output: %s", out_txt)
  50. if out_txt.lower().startswith("loading"):
  51. logger.debug("librespot: %s", out_txt)
  52. title = out_txt[out_txt.index("<") + 1:out_txt.index(">")]
  53. if self.__preload_state__:
  54. self.__title_preload__ = title
  55. logger.info("Upcomming Title %s identified", title)
  56. else:
  57. self.__title__ = title
  58. logger.info("Current Title %s identified", title)
  59. if "command=" in out_txt:
  60. command = out_txt[out_txt.find('command=') + 8:].strip().lower()
  61. logger.debug("librespot command: %s", command)
  62. if command.startswith("preload"):
  63. self.__preload_state__ = True
  64. if command.startswith("load"):
  65. self.set_state(command.split(',')[2].strip() == 'true')
  66. #
  67. self.__preload_state__ = False
  68. if self.__title_preload__ is not None:
  69. self.__title__ = self.__title_preload__
  70. self.__title_preload__ = None
  71. #
  72. elif command in self.ON_CMD:
  73. self.set_state(True)
  74. elif command in self.OFF_CMD:
  75. self.set_state(False)
  76. if self.__state__:
  77. self.set_title(self.__title__)
  78. else:
  79. self.set_title("")
  80. def set_state(self, target_state):
  81. if target_state != self.__state__:
  82. self.__state__ = target_state
  83. logger.info("spotify state changed to %s", self.__state__)
  84. self.__state_callback__(self.__state__)
  85. def set_title(self, title):
  86. if self.__title_published__ != title:
  87. self.__title_published__= title
  88. logger.info("spotify title changed to \"%s\"", title)
  89. self.__title_callback__(title)
  90. def send_state_msg_mqtt(state):
  91. client= paho.Client(config.APP_NAME)
  92. client.username_pw_set(config.MQTT_USER, config.MQTT_PASS)
  93. try:
  94. client.connect(config.MQTT_SERVER, 1883)
  95. topic = config.MQTT_TOPIC + "/state"
  96. logger.info("Sending Spotify status information to mqtt %s = %s", topic, str(state))
  97. client.publish(topic, "true" if state else "false")
  98. except (socket.timeout, OSError) as e:
  99. logger.warning("Erro while sending state information")
  100. def send_title_msg_mqtt(title):
  101. client= paho.Client(config.APP_NAME)
  102. client.username_pw_set(config.MQTT_USER, config.MQTT_PASS)
  103. try:
  104. client.connect(config.MQTT_SERVER, 1883)
  105. topic = config.MQTT_TOPIC + "/title"
  106. logger.info("Sending Spotify status information to mqtt %s = %s", topic, title)
  107. client.publish(topic, title)
  108. except (socket.timeout, OSError) as e:
  109. logger.warning("Erro while sending title information")
  110. if __name__ == '__main__':
  111. report.appLoggingConfigure(config.__BASEPATH__, config.LOGTARGET, ((config.APP_NAME, config.LOGLVL), ), fmt=config.formatter, host=config.LOGHOST, port=config.LOGPORT)
  112. ls = librespot(send_state_msg_mqtt, send_title_msg_mqtt)
  113. ls.run()