Sony Bravia TV integration does not permit sleeping/standby

Hello there.

My FW-49BZ35F TV is frequently pulled by Home Assistant every 10s. Even if it is OFF, it can’t go sleeping. This is noticeable by looking on power consumption, dropping any packet from HA to IP_ADDRESS:80 using iptables permits the TV to enter sleep mode, otherwise the Wi-Fi (same with Ethernet) interface is still pingable and no REAL sleep is reached.

I’m not interested in wake up my TV programmatically (wake on lan), but I definitely want to save these watts after I turn it OFF. As a workaround I tried to disable the 2 entities created by the integration, it works. I have tried to create an automation which disables the entities after the tv goes from ‘on’, to ‘off’ status (re-enabling after 5 minutes). That would be enough to permit the sleeping while keeping the integration working and saving money as well :slight_smile: Unfortunately I haven’t found any method to disable an entity programmatically.

What can I do? Is there any real solution for this?

Did you ever find a satisfactory longer term solution? Like you my main interest is in being able to control the TV once its on, using HA. Having it consume 30W indefinitely isn’t really an option.

Has anyone found a solution to this problem?

I made a workaround with appdaemon and a script. It works likes this:

  • once the tv has turned off (api event), it calls a script that, with iptables, drops any network traffic to/from the tv

  • once I manually turn the tv on with its remote, il detects the Power consumption and remove the firewall rules, so the api became Active again

Still waiting for a Better method :laughing:

Hi @aventrax
I"m facing the same issue. Could you please post your script? I’ll try it then for my case. For me not even disabling the Integration helps. Only a reboot of HA allows the TV to sleep.

It would be good if the Sony Integration could be configured to not query a turned-off tv to allow deep standby.

What is the power consumption of the TV while turned off but not sleeping? I doubt it’s enough to bother doing this to let it sleep.

Just a bit of explanation of what will follow:

  • sensor.media_station_w is a sensor which measure the power consumption of the TV
  • media_player.sony_bravia_tv is the TV itself with bravia integration
  • media_player.bravia_4k_gb_atv3 is the TV with android integration (is not required, I added this later for other meanings)
  • 172.31.31.145 is the IP of my TV

This is my appdaemon app:

import appdaemon.plugins.hass.hassapi as hass
import json
import requests
from bravia_tv import BraviaRC


class SonyPowerManagement(hass.Hass):

    def initialize(self):
        self.log("***** Sony Power Management *****")

        self._host = self.args["host"]
        self._pin = self.args["pin"]
        self._policy = None

        self.tv = BraviaRC(self._host)

        self.msw = self.get_entity("sensor.media_station_w")
        self.mps = self.get_entity("media_player.sony_bravia_tv")

        self.mps.listen_state(self.on_turnoff, new="off", duration=300)
        self.msw.listen_state(self.on_powerup)

    def on_turnoff(self, entity, attribute, old, new, kwargs):
        if not self.tv.is_connected():
            try:
                self.tv.connect(self._pin, 'my_device_id', 'my device name')
            except:
                self.log('TV not connected!!')
                return

        self.disable_wol()
        self.reboot()
        self.network('DROP')

    def on_powerup(self, entity, attribute, old, new, kwargs):
        if float(old) < 90 < float(new):
            self.network('ALLOW')
            self.call_service("homeassistant/reload_config_entry", entity_id="media_player.bravia_4k_gb_atv3")

    def disable_wol(self):
        self.tv.setWolMode(False)
        self.log('WOL disabled')

    def reboot(self):
        jdata = self.tv._jdata_build('requestReboot')
        self.tv.bravia_req_json('system', jdata)
        self.log('TV rebooted.')

    def network(self, policy):
        if policy == self._policy:
            return
        url = 'http://172.31.31.31:6667/sony/network'
        headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
        jdata = json.dumps({'action': policy.upper()})
        if requests.post(url, jdata, headers=headers):
            self._policy = policy.upper()
            self.log('NET policy changed to {}'.format(policy.upper()))

My appdaemon config:

sony_bravia:
  module: sony
  class: SonyPowerManagement
  host: '172.31.31.145'
  pin: '1234'

On the host I have the port tcp/6667 opened by this:

import subprocess
from flask import Flask, jsonify, request

app = Flask(__name__)

@app.route('/sony/network', methods=['POST'])
def allow_traffic():
    action = request.json['action']
    cmd = ['/usr/local/bin/sony.sh', action]
    print(cmd)

    try:
        subprocess.run(cmd, check=True)
        return jsonify(request.json)

    except Exception as e:
        return jsonify({"error": str(e)})


if __name__ == "__main__":
    app.run()

Finally the script it launches:

#!/bin/bash

IPT=/usr/sbin/iptables

if [ "$1" == "DROP" ];
then
        $IPT -L OUTPUT 1 -n | grep 145 || $IPT -I OUTPUT 1 -d 172.31.31.145 -j DROP
fi


if [ "$1" == "ALLOW" ];
then
        $IPT -L OUTPUT 1 -n | grep 145 && $IPT -D OUTPUT 1
fi

@odwide It is around 30W if not sleeping, in comparison to 0.5W in deep sleep. So it makes quite a difference in my case.

@aventrax Thank you. I will try it for my case

1 Like

@Zueri yep. Adjust the values because my sensor.media_station_w, as the name suggests, includes other stuff with the home assistant server itself, so my baseline is 40-50W and the “turn on value” is 90W. The appdaemon app waits 5 minutes after it detects the shutdown and then disable the wake on lan and reboot the tv. This has been done because of a bug in the firmware that keeps turning WOL “on” and the standby power consumption increases as well. If I remember well, 20 minutes after you turn off the TV, the consumption decreases.

@aventrax are you using HomeAssistant OS? The appdeamon part is running, but I’m struggling on the part:

and the sony.sh part (where to put these and how to get them running).

I really do not know the home assistant os, I use the supervised install.

Anyway, somewhere between HA and the TV, there must be something like a firewall that drops the packets to the tv. The appdaemon part is used to “manage” the firewall through and http call to the port 6667. In my case the firewall is the VM where the supervised HA has been installed but it can be anywhere. If your HomeAssistant OS is installed on a virtual machine, you can put the app.py and sony.sh on the host OS (it has to be linux). To clarify, app.py is a Flask app that opens the port 6667 and launches sony.sh that is a shell script managing a single firewall rule using iptables. I know that this part is a bit complex…

Thanks for pointing me in the right direction. I forgot that I run Hassio in Proxmox and put the script and flusk service there. I will now check if it works and lowers the power consumption of my TV in standby.

Hopefully this gets easier in future :grinning:

I got it working in my setup. The iptables script was not working in my cases (using a proxmox VM). So I went the way of using the Proxmox firewall. The firewall needs to be enabled on datacenter, node, VM AND network interface of the VM levels. I missed the last one was wondering why the script newer worked.

The shell script to enable/disable communication of the homeassistant VM to the TV looks like this. The IP_ADDRESS and FILE variables needs to be changed to the IP of the TV and the ID of the VM in Proxmox.

#!/bin/bash
IP_ADDRESS="192.168.75.75"
RULE="OUT DROP -dest $IP_ADDRESS -log nolog"
FILE="/etc/pve/firewall/101.fw"

if [ "$1" == "DROP" ]; then
    # Remove the rule if it exists
    /usr/bin/sed -i "\|^$RULE|d" "$FILE"

    # Add the rule
    echo "$RULE" >> "$FILE"
    /usr/bin/logger "Blocked connection to $IP_ADDRESS"
fi

if [ "$1" == "ALLOW" ]; then
    # Remove the rule
    /usr/bin/sed -i "\|^$RULE|d" "$FILE"
    /usr/bin/logger "Allowed connection to $IP_ADDRESS"
fi

Great job.