ztalbot2000 / homebridge-cmd4

CMD4 Plugin for Homebridge - Supports ~All Accessory Types & now all Characteristics too
Apache License 2.0
149 stars 13 forks source link

stateChangeResponseTime needed for the Switch function #54

Closed jsiegenthaler closed 4 years ago

jsiegenthaler commented 4 years ago

Hi

My Stereo takes about 10 seconds to boot up following the Power On command HomeKit times out and shows a not-responding orange (!) on the button, but the stereo is still within it's boot up phase.

Between issuing the ON command or the OFF command, my stereo takes some time to react: around 5s to turn off, and 10s to turn on. If the Polling command occurs within the power down or power up phase, it reports the current state (e.g. goes back to ON when it is in the process of turning OFF). I'd like to add a polling inhibit for a programmable time

Something like a stateChangeResponseTimeOnToOff and stateChangeResponseTimeOffToOn During the state change time, the polling would be inhibited.

What do you think?

ztalbot2000 commented 4 years ago

Hi,

I can see your dilemma. Have you tried just changing the interval and the polling timeout?. There may be a sweet spot there.

I would not really like a config item for just on/off but per characteristic. Try my first suggestion and let me know how you make out.

ttfn, John Talbot

On Thu, Jun 4, 2020 at 10:41 AM jsiegenthaler notifications@github.com wrote:

Hi

My Stereo takes about 10 seconds to boot up following the Power On command HomeKit times out and shows a not-responding orange (!) on the button, but the stereo is still within it's boot up phase.

Between issuing the ON command or the OFF command, my stereo takes some time to react: around 5s to turn off, and 10s to turn on. If the Polling command occurs within the power down or power up phase, it reports the current state (e.g. goes back to ON when it is in the process of turning OFF). I'd like to add a polling inhibit for a programmable time

Something like a stateChangeResponseTimeOnToOff and stateChangeResponseTimeOffToOn During the state change time, the polling would be inhibited.

What do you think?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ztalbot2000/homebridge-cmd4/issues/54, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABSBCX4CVDLPQLHDCEJKMUDRU6XCJANCNFSM4NSWEB2Q .

jsiegenthaler commented 4 years ago

Hi John  Thanks for responding I solved this in my bash script by setting the state to a transitional state, and returning dummy ping answers during transition. Transition stays valid for up to 15s if not cancelled earlier, and it works perfectly  So you can ignore this request 😉 Thanks , Jochen 

jsiegenthaler commented 4 years ago

I'm closing this for John as I solved it through a clever use of my bash script. I added a transition state and pinged the device I was turning on/off. When the ping started/failed to received responses I knew it was at the right state. So closing this ticket as no change is needed.. Jochen

ztalbot2000 commented 4 years ago

Congrats on your cleverness!

TTFN, John Talbot

On Sat, Jun 6, 2020 at 11:33 PM jsiegenthaler notifications@github.com wrote:

Closed #54 https://github.com/ztalbot2000/homebridge-cmd4/issues/54.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/ztalbot2000/homebridge-cmd4/issues/54#event-3415734441, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABSBCX26P47XZEMQCVZ2QODRVMDBDANCNFSM4NSWEB2Q .

MichlW commented 3 years ago

Hi @jsiegenthaler

Could you please post your bash script as I need a solution for my TV that needs approx. 10s to boot before i can use ping to poll its active state.

Thanks in advance.

Greets Michael

ztalbot2000 commented 3 years ago

Hey Mitch,

My script was your script. Maybe I'm getting Mitch's mixed up. I'm confused.

On Tue, Oct 27, 2020 at 4:29 PM MichlW notifications@github.com wrote:

Hi @jsiegenthaler https://github.com/jsiegenthaler

Could you please post your bash script as I need a solution for my TV that needs approx. 10s to boot before i can use ping to poll its active state.

Thanks in advance.

Greets Michael

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/ztalbot2000/homebridge-cmd4/issues/54#issuecomment-717519796, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABSBCX3XHVO5DMCEBZGQ5SLSM4USTANCNFSM4NSWEB2Q .

MichlW commented 3 years ago

Hey John,

you do not need to be confused... I simply want to have a look to @jsiegenthaler 's bash script how he handles the delay when the device boots up.

I want to tune my Television.sh script with that idea.

jsiegenthaler commented 3 years ago

Hello @MichlW The trick is to understand that the TV actually has 4 states: Off, TransitioningFromOffToOn, On, TransitioningFromOnToOff During a transitioning phase, you need to send dummy responses to Cmd4. I set a transitioning time of 15s for my TV

Here's the piece from my cmd4 bash script, it's been working reliably for many many months. Sorry, you'll have to re-indent it:

#!/bin/bash

#   Notes
#   1) This script is called as defined by the config.json file as:
#      "state_cmd_prefix": "bash",
#    "state_cmd":   ".homebridge/Cmd4Scripts/TV.sh"
#    $1 = 'Get'
#    $2 = <Device   name>    DO NOT USE SPACES IN DEVICE   NAME. IT SCREWS UP COMMAND LINE PARSING
#    $3 = <Characteristic>   For the TV, this is On or Off
#    $4 = <Device option>   (not used in this case)
#
#   2) For a Set of On, the command issued would be:
#    bash   .homebridge/Cmd4Scripts/TV.sh Set TV On false
#       or
#    bash   .homebridge/Cmd4Scripts/TV.sh Set TV On true
#
#   3) For a Get of On, the command issued would be:
#    bash   .homebridge/Cmd4Scripts/TV.sh Get TV On
#
#    Homebridge-cmd4 will   interpret the result of false to be 1
#    and true to be 0
 
#   comment out this line only for testing
#   echo "\$1='$1' \$2='$2' \$3='$3' \$4='$4'"
 
 
if [ "$1" = "Get" ]; then
# Get the TV power status by pinging the network port (faster) or   asking for cec power status (slower)
# The port does not respond when turned off
# HomeKit HAP recognises 0=On, 1=Off
# The script must output "0" and have an exit status of 0   (no error) if the device is On
# The script must output "1" and have an exit status of 0   (no error) if the device is Off
# [[ "$pingresponse" == *"1 received"* ]]; is a   regex compare to check for substring within pingresponse
# cec is slower than a ping, so use ping. The cec command is left   here, commented out, for future possible use
# cecresponse=$(echo "pow 0" \| cec-client -s -p 1 -t r -d 1   RPI \| grep -i 'power status:')
# if [[ "$cecresponse" == *"power status: on"* ]];   then
#    echo 1
#    exit 0
# elif [[ "$cecresponse" == *"power status: in   transition from standby to on"* ]]; then
#    echo 1
#    exit 0
# else
#    echo 0
#    exit 0
# fi
pingresponse=$(ping -c 1 -w 1 192.168.0.151 \| grep -i '1 received')
if [[ "$pingresponse" == *"1 received"* ]]; then
# a ping response was received, so the TV is On, but might be   transitioning from On to Standby
# so look for the transitioning file, and return a Standby response   (echo 0) if transitioning to Standby
if [ -f "/tmp/powerStatusTV_InTransitionFromOnToStandby" ];   then
# a valid ping response was received, but the TV is transitioning from   On to Standby
# check the age of the transitioning file
# if older than 15s, something went wrong, the TV did not shut down in   time. So timeout, delete the file and return On
# else the TV is off, so return Standby
if (( $(( $(date +%s) - $(date -r   "/tmp/powerStatusTV_InTransitionFromOnToStandby" +%s) )) > 15   )); then
rm -f   "/tmp/powerStatusTV_InTransitionFromOnToStandby"
echo 1
else
echo 0
fi
 
else
# no ping response was received, so the TV is on Standby, but might be   transitioning from Standby to On
# so look for the transitioning file, and return a On response (echo   1) if transitioning to On
if [ -f "/tmp/powerStatusTV_InTransitionFromStandbyToOn" ];   then
# no ping response was received, but the TV is transitioning from   Standby to On
# check the age of the transitioning file
# if older than 15s, something went wrong, the TV did not boot up in   time. So timeout, delete the file and return Standby
# else the TV is booting up, so return On
if (( $(( $(date +%s) - $(date -r   "/tmp/powerStatusTV_InTransitionFromStandbyToOn" +%s) )) > 15   )); then
rm -f   "/tmp/powerStatusTV_InTransitionFromStandbyToOn"
echo 0
else
echo 1
fi
elif [ -f "/tmp/powerStatusTV_InTransitionFromOnToStandby"   ]; then
# no ping response was received, and the TV was transitioning from On   to Standby
# as the TV is now at Standby, remove the transitioning file and   return Standby
rm -f "/tmp/powerStatusTV_InTransitionFromOnToStandby"
echo 0
else
# no ping response was received, and the TV is not transitioning, so   return Standby
echo 0
fi
exit 0
fi
fi
MichlW commented 3 years ago

Hey @jsiegenthaler,

many thanks for the script that helped me so much to handle the transition states of my TV. I tuned it a little, because:

#!/bin/sh

TELEVISION_IP=172.16.2.30

TRANSITION_TO_STANDBY="/dev/shm/Television.TransitionToStandby"
TRANSITION_TO_ON="/dev/shm/Television.TransitionToOn"

if [ "$1" = "Get" ]; then
        case $3 in
                "Active")
                        ping -c 2 -W 1 -w 2 $TELEVISION_IP > /dev/null 2>&1
                        if [ $? -eq 0 ]; then
                                # if ping delivers results
                                if [ -f $TRANSITION_TO_STANDBY ]; then
                                        # fake standby state while in transition to standby
                                        echo 0
                                else
                                        # real on state -> delete fake transition to on
                                        if [ -f $TRANSITION_TO_ON ]; then rm -f $TRANSITION_TO_ON; fi
                                        echo 1
                                fi
                        else
                                # if ping do not delivers results
                                if [ -f $TRANSITION_TO_ON ]; then
                                        # fake on state while in transition to on
                                        echo 1
                                else
                                        # real standby state -> delete fake transition to standby
                                        if [ -f $TRANSITION_TO_STANDBY ]; then rm -f $TRANSITION_TO_STANDBY; fi
                                        echo 0
                                fi
                        fi
                ;;
        esac
        exit 0
fi

if [ "$1" = "Set" ]; then
        case $3 in
                "Active")
                if [ "$4" = "1" ]; then
                        if [ ! -f $TRANSITION_TO_STANDBY ]; then
                                # <place command to put TV to on here>
                                touch $TRANSITION_TO_ON
                        fi
                else
                        if [ ! -f $TRANSITION_TO_ON ]; then
                                # <place command to put TV to standby here>
                                touch $TRANSITION_TO_STANDBY
                        fi
                fi
                ;;
        esac
        exit 0
fi

exit 66

Thanks again for your help.

Greetings Michael