Blondie
Blondie

Reputation: 23

using cec-client without reconnect in bash

I try to write a script for my Raspberry to turn on a relay (on gpio) while my tv is powered on. I want to capture the status via HDMI.

I can use the cec-client to get the status from my tv:

echo pow 0 | cec-client -s -d 1

but it takes a few seconds to complete.

I have write a script to get the status continuous

#!/bin/sh

while :; do
    command="echo pow 0 | cec-client -s -d 1 | grep 'power status' | awk split(\$0,a,\":\");print a[2]}' | sed 's/ //'"
    status=$(eval $command)

echo $status
done
exit 0

It takes about 5% CPU and is very slow.

It would be much faster if i connect only once. This is working very fast:

(while true ; do sleep 1 ; echo "pow 0" ; done) | cec-client -d 1

But how can I take the output to a variable (in a bash script) and use this status?

Or do I have to go another way / other programming language?

[edit]

Having now realized that it is better to program it with c++. I've tried a couple of hours but it is very difficult for me to programm in c++. I have ony programmed in VB.net,Java (all with IDE) and a simple things with bash.

I've looked at the source code from cec-client. But i can´t compile it directly. So i have found this site: link

This is a very good working example that i can compile. But i dont know how to add the power status request. I think that must be in the main loop at line 106. The command would be: cec_adapter->GetDevicePowerStatus but i dont know how to use enum CEC::cec_logical_address within this code.

Can you please help me with it? It is for me as beginner to difficult to understand this.

Thank you!

[/edit]

[edit2] How Ross Ridge already commented...the extension is another question. I have now found the solution. And post this only for completeness.

The Example from DrGeoff link is very good. If i add before line 107:

CEC::cec_power_status power = cec_adapter->GetDevicePowerStatus((CEC::cec_logical_address)0); std::cout << "Status:" << cec_adapter->ToString(power) << std::endl; i can read the status from my tv. So the rest is "only" simple c ++ and i can help me out with google.

Thanks for the Help! The question is done. [edit2]

Upvotes: 0

Views: 2613

Answers (1)

Ross Ridge
Ross Ridge

Reputation: 39581

I don't have a Raspberry-Pi to test it out with, but try this:

(while true ; do echo "pow 0" ; sleep 1; done) |
    cec-client -d 1 |
    awk '/power status/ {split($0,a,":"); print a[2]; fflush()}' |
    while read status
    do
         echo $status
    done

Part of the trick here is calling fflush in the AWK script so that it's output isn't buffered. Otherwise all the extracted status values will accumulate in awk's output buffer until it's full, which will take a long time.

For this to work the output of cec-client also needs to be unbuffered. From looking at the source it appears that it's line buffering its output, so it should work.

Upvotes: 1

Related Questions