sebbo2002 / pyatv-mqtt-bridge

Bridge which allows you to control your Apple TV via MQTT
MIT License
37 stars 8 forks source link

/powerState MQTT messages stop being published after a few minutes #308

Closed glecoz closed 10 months ago

glecoz commented 10 months ago

Context : I send some appletv/$id/turnOff MQTT messages to pyatv-mqtt-bridge to standby my Apple Tv. But if send these messages when the the apple Tv is already off, it turns it on instead. This is why I subscribed to the appletv/$id/powerState messages published by your bridge to my broker, then I update a value in a DB each time the powerState value changes, so that I know when to turn off the TV or not.

Issue : When starting the container, the /powerState messages are published by your bridge to my MQTT broker, but after about 2-3 minutes, if I switch the Apple TV bon on or off, then the powerState messages stop being published to the broker, for an unknown reason.

If I restart the pyatv-mqtt-bridge container, it works again for 2-3 minutes, then these messages stop being published again. It seems to be like your bridge doesn't keep the connection alive with the broker (Mosquitto in my case), then stops publishing any MQTT message for such reasons.

[info][10.0.0.125] [node-pyatv][18] stdout: {"result": "success", "datetime": "2024-01-11T17:05:32.981710+00:00", "power_state": "on"}
[info][10.0.0.125] [node-pyatv][18] No hash value found in input ({"result":"success","datetime":"2024-01-11T17:05:32.981710+00:00","power_state":"on"})
[info][10.0.0.125] [node-pyatv][18] No mediaType value found in input ({"result":"success","datetime":"2024-01-11T17:05:32.981710+00:00","power_state":"on"})
[info][10.0.0.125] [node-pyatv][18] No deviceState value found in input ({"result":"success","datetime":"2024-01-11T17:05:32.981710+00:00","power_state":"on"})
[info][10.0.0.125] [node-pyatv][18] No title value found in input ({"result":"success","datetime":"2024-01-11T17:05:32.981710+00:00","power_state":"on"})
[info][10.0.0.125] [node-pyatv][18] No artist value found in input ({"result":"success","datetime":"2024-01-11T17:05:32.981710+00:00","power_state":"on"})
[info][10.0.0.125] [node-pyatv][18] No album value found in input ({"result":"success","datetime":"2024-01-11T17:05:32.981710+00:00","power_state":"on"})
[info][10.0.0.125] [node-pyatv][18] No genre value found in input ({"result":"success","datetime":"2024-01-11T17:05:32.981710+00:00","power_state":"on"})
[info][10.0.0.125] [node-pyatv][18] No totalTime value found in input ({"result":"success","datetime":"2024-01-11T17:05:32.981710+00:00","power_state":"on"})
[info][10.0.0.125] [node-pyatv][18] No position value found in input ({"result":"success","datetime":"2024-01-11T17:05:32.981710+00:00","power_state":"on"})
[info][10.0.0.125] [node-pyatv][18] No shuffle value found in input ({"result":"success","datetime":"2024-01-11T17:05:32.981710+00:00","power_state":"on"})
[info][10.0.0.125] [node-pyatv][18] No repeat value found in input ({"result":"success","datetime":"2024-01-11T17:05:32.981710+00:00","power_state":"on"})
[info][10.0.0.125] [node-pyatv][18] No app value found in input ({"result":"success","datetime":"2024-01-11T17:05:32.981710+00:00","power_state":"on"})
[info][10.0.0.125] [node-pyatv][18] No appId value found in input ({"result":"success","datetime":"2024-01-11T17:05:32.981710+00:00","power_state":"on"})
[info][10.0.0.125] [node-pyatv][18] No focusState value found in input ({"result":"success","datetime":"2024-01-11T17:05:32.981710+00:00","power_state":"on"})
[info][10.0.0.125] {"values":{"key":"dateTime","old":"2024-01-11T17:05:20.129Z","new":"2024-01-11T17:05:32.981Z","device":{"name":"Salon","host":"10.0.0.125","id":"64D2C4C9FF9A"}}}
[info][10.0.0.125] {"values":{"key":"powerState","old":"off","new":"on","device":{"name":"Salon","host":"10.0.0.125","id":"64D2C4C9FF9A"}}}

The last empty lines on the log above are when I did carriage returns in my terminal and was switching on / off with the Apple TV remote and nothing was logged anymore in terms of powerState messages...

So basically I have no way to standby my Apple TV through pyatv-mqtt-bridge

glecoz commented 10 months ago

I checked with MQTT explorer and the /powerState messages stop being published effectively to my broker after a few minutes

sebbo2002 commented 10 months ago

Can you please check manually with atvscript whether it behaves differently? I suspect that this is a technical limitation of the protocol.

glecoz commented 10 months ago

I have exactly the same behavior with a fresh npm install -g @sebbo2002/pyatv-mqtt-bridge followed by pyatv-mqtt-bridge --debug config.json.

/powerState MQTT messages are published during the first 45 seconds, then stop being published while switching Apple TV on/off from the remote, and the logs also stop, as shown above.

sebbo2002 commented 10 months ago

If no events are logged with --debug, these events are also not generated by pyatv. You would have to contact pyatv directly. Unfortunately I cannot offer support for pyatv here, sorry.

I would close the ticket for now as it is a problem with pyatv and not pyatv-mqtt-bridge. Please reopen the ticket if this is wrong.

glecoz commented 10 months ago

Context : I send some appletv/$id/turnOff MQTT messages to pyatv-mqtt-bridge to standby my Apple Tv. But if send these messages when the the apple Tv is already off, it turns it on instead. This is why I subscribed to the appletv/$id/powerState messages published by your bridge to my broker, then I update a value in a DB each time the powerState value changes, so that I know when to turn off the TV or not.

So basically I have no way to standby my Apple TV through pyatv-mqtt-bridge

Sending appletv/$id/standby command (instead of appletv/$id/turnOff twice) seems to do the trick for now (although stated as deprecated). It doesn't turn the TV on while already off. Thus no need to rely on the unreliable powerState value.

glecoz commented 10 months ago

Sending appletv/$id/standby command (instead of appletv/$id/turnOff twice) seems to do the trick for now (although stated as deprecated). It doesn't turn the TV on while already off. Thus no need to rely on the unreliable powerState value. -> Unable to wake up.

So the only workaround is to switch TV on, wait 11 sec. then turn it off twice (with 3.5 sec. wait between each) :

import { mqttConfig } from '@src/config';
import mqtt from 'mqtt';

export const standby = (appleTvId: string): void => {
  const client = mqtt.connect(mqttConfig.client.server, mqttConfig.client.options);
  client.publish(`appletv-bridge/${appleTvId}/turnOn`, '');
  //console.log('Apple TV on');
  setTimeout(() => {
    client.publish(`appletv-bridge/${appleTvId}/turnOff`, '');
    //console.log('Apple TV button off');
    setTimeout(() => {
      client.publish(`appletv-bridge/${appleTvId}/turnOff`, '');
      //console.log('Apple TV button off');
      client.end();
    }, 3500); // 3.5 sec.
  }, 11000); // 11 sec.
};