Hi
thanks for helping. I think the queue class is working fine, it just appears that the worker thread is not being called when a new item is added to the queue, it does it the first time around, but then never again unleass I re-start AD
Here is the startup log for AD. Production is set to false in my appdaemon.yaml. I have ~25 AD apps running and they seem to all be working Ok except for the ones using the sound utility to announce things through TTS
[s6-init] making user provided files available at /var/run/s6/etc...exited 0.
[s6-init] ensuring user provided files have correct perms...exited 0.
[fix-attrs.d] applying ownership & permissions fixes...
[fix-attrs.d] done.
[cont-init.d] executing container initialization scripts...
[cont-init.d] 00-banner.sh: executing...
-----------------------------------------------------------
Hass.io Add-on: AppDaemon v1.6.0
Python Apps and HADashboard using AppDaemon 3.x for Home Assistant
From: Community Hass.io Add-ons
By: Franck Nijhof <[email protected]>
-----------------------------------------------------------
armhf / HassOS 1.12 / HA 0.86.4 / SU 142 / stable
-----------------------------------------------------------
[cont-init.d] 00-banner.sh: exited 0.
[cont-init.d] 01-log-level.sh: executing...
Log level is set to INFO
[cont-init.d] 01-log-level.sh: exited 0.
[cont-init.d] 02-updates.sh: executing...
INFO: You are running the latest version of this add-on
[cont-init.d] 02-updates.sh: exited 0.
[cont-init.d] 20-init-configuration.sh: executing...
[cont-init.d] 20-init-configuration.sh: exited 0.
[cont-init.d] 21-compiled-dir.sh: executing...
[cont-init.d] 21-compiled-dir.sh: exited 0.
[cont-init.d] 30-auto-token.sh: executing...
INFO: Updating Hass.io API token in AppDaemon with the current one...
[cont-init.d] 30-auto-token.sh: exited 0.
[cont-init.d] 31-ha-url.sh: executing...
[cont-init.d] 31-ha-url.sh: exited 0.
[cont-init.d] 50-compiled-symlink.sh: executing...
[cont-init.d] 50-compiled-symlink.sh: exited 0.
[cont-init.d] 80-system-packages.sh: executing...
[cont-init.d] 80-system-packages.sh: exited 0.
[cont-init.d] 81-python-packages.sh: executing...
[cont-init.d] 81-python-packages.sh: exited 0.
[cont-init.d] done.
[services.d] starting services
[services.d] done.
This is the app I am using for testing - just fires of a state change of an Input boolean
import appdaemon.plugins.hass.hassapi as hass
import globals
import random
## App for testing
class AppTest(hass.Hass):
def initialize(self):
# Subscribe to sensors
self.sound = self.get_app("ttssound")
self.utility = self.get_app("utilities")
self.listen_state(self.state_change_detected, self.args["sensor"])
self.handle = None
def state_change_detected(self, entity, attribute, old, new, kwargs):
name = self.friendly_name(self.args["sensor"])
#message = self.args["message"]
message = self.getLeaveMessage("Scott")
self.sendNotification(message)
def sendNotification(self, notifyMessage):
self.log(notifyMessage)
if self.args["notifyOn"]:
self.utility.send_notification(notifyMessage,NotificationService = 1, titleText = "Test App")
self.playTTS(notifyMessage)
def playTTS(self, TTSMessage):
self.log(" External tts called")
self.sound.tts(TTSMessage, len(TTSMessage)/11)
def getLeaveMessage(self, name):
with open ('/config/appdaemon/apps/message/leave.txt') as f:
leavelines = f.read().splitlines()
quote = (random.choice(leavelines)) %(name)
return quote
The utility app where the problem is - with lots of debugging turned on this is instance ttssound. I removed all the try/catch statements it now reflects the original code snipet posted by @aimc inthe post i mentioned above
import appdaemon.plugins.hass.hassapi as hass
from queue import Queue
from threading import Thread
from threading import Event
import time
#
# App to manage announcements via TTS and stream sound files to Google Home
#
# Provides methods to enqueue TTS and Media file requests and make sure that only one is executed at a time
# Volume of the media player is set to a specified level and then restored afterwards
#
# Args:
#
# player: media player to use for announcements
# TTSVolume: media played volume 0-1
class Sound(hass.Hass):
def initialize(self):
# Create Queue
self.queue = Queue(maxsize=0)
# Create worker thread
t = Thread(target=self.worker)
t.daemon = True
t.start()
self.event = Event()
self.log("Thread Alive {}, {}" .format (t.isAlive(), t.is_alive()))
def worker(self):
while True:
self.log("Calling TTS from worker")
#try:
# Get data from queue
data = self.queue.get()
self.log(" This is has been pulled off the current Queue {}".format(data))
# Save current volume
volume = self.get_state(self.args["player"], attribute="volume_level")
self.log("Current Volume save {}".format(volume))
# Turn on Google and Set to the desired volume
self.call_service("media_player/turn_on", entity_id = self.args["player"])
self.call_service("media_player/volume_set", entity_id = self.args["player"], volume_level = self.args["TTSVolume"])
self.log("Set the Volume to {}".format(self.args["TTSVolume"]))
# Call TTS service
self.call_service("tts/google_say", entity_id = self.args["player"], message = data["text"])
self.log("This is the text said - {}".format(data["text"]))
# Sleep to allow message to complete before restoring volume
self.log("Now sleep for {}".format(int(data["length"])))
time.sleep(int(data["length"]))
# Restore volume
self.call_service("media_player/volume_set", entity_id = self.args["player"], volume_level = volume)
self.log("Restore Volume")
# Set state locally as well to avoid race condition
self.set_state(self.args["player"], attributes = {"volume_level": volume})
self.queue.task_done()
self.log("Worker thread exiting")
def tts(self, text, length):
self.queue.put({"text": text, "length": length})
self.log("Message added to queue Queue enmpy {}".format(self.queue.empty()))
self.log("Queue Size is now {}".format(self.queue.qsize()))
self.log(self.queue.queue)
def terminate(self):
self.event.clear()
self.queue.put({"type": "terminate"})
self.log(" Terminate function called")
self.event.wait()
A snippet of the info.log ( nothing in the error log.). This is the result of changing the input boolean three times. The first time it fires off the worker thread and plays the TTS message, the subsequent ones are added to the queue, but the worker function is not called
2019-02-03 16:29:01.673543 INFO automation_test: Scott, Life is a series of hellos and goodbyes
2019-02-03 16:29:02.716449 INFO utilities: Scott, Life is a series of hellos and goodbyes
2019-02-03 16:29:02.724997 INFO automation_test: External tts called
2019-02-03 16:29:02.737850 INFO ttssound: This is has been pulled off the current Queue {'text': 'Scott, Life is a series of hellos and goodbyes', 'length': 4.181818181818182}
2019-02-03 16:29:02.749289 INFO ttssound: Current Volume save None
2019-02-03 16:29:02.773843 INFO ttssound: Message added to queue Queue enmpy False
2019-02-03 16:29:02.795868 INFO ttssound: Queue Size is now 0
2019-02-03 16:29:02.797518 INFO ttssound: deque([])
2019-02-03 16:29:03.423809 INFO ttssound: Set the Volume to 0.7
2019-02-03 16:29:03.567851 INFO ttssound: This is the text said - Scott, Life is a series of hellos and goodbyes
2019-02-03 16:29:03.582922 INFO ttssound: Now sleep for 4
2019-02-03 16:29:23.017036 INFO automation_test: where for art thou Scott
2019-02-03 16:29:23.786153 INFO utilities: where for art thou Scott
2019-02-03 16:29:23.794649 INFO automation_test: External tts called
2019-02-03 16:29:23.803889 INFO ttssound: Message added to queue Queue enmpy False
2019-02-03 16:29:23.812771 INFO ttssound: Queue Size is now 1
2019-02-03 16:29:23.814048 INFO ttssound: deque([{'text': 'where for art thou Scott', 'length': 2.1818181818181817}])
2019-02-03 16:29:51.292356 INFO automation_test: Scott has gone, but will return soon
2019-02-03 16:29:53.083603 INFO utilities: Scott has gone, but will return soon
2019-02-03 16:29:53.093565 INFO automation_test: External tts called
2019-02-03 16:29:53.103075 INFO ttssound: Message added to queue Queue enmpy False
2019-02-03 16:29:53.112814 INFO ttssound: Queue Size is now 2
2019-02-03 16:29:53.114181 INFO ttssound: deque([{'text': 'where for art thou Scott', 'length': 2.1818181818181817}, {'text': 'Scott has gone, but will return soon', 'length': 3.272727272727273}])