I would like to ask a question: What method should I use to add projectors from the local network? The projectors are Panasonic projectors that support the pjlink power control protocol. The power-off command is “%1POWR 0\r” and the power-on command is “%1POWR 1\r”. The port number is standard, set at 4352. The IP address of one of the projectors is 192.168.10.23, and there are also a few other projectors, such as 192.168.10.24 or 192.168.10.25.
I just finished getting my Epson 11000 connected, and it’s kind of a pain. The big issue is that the PJLink support thinks that power condition 3 is an actual error, and lots of scripts will end up failing.
At least on my Epson, the way it works is that when you send
%1POWR=1
The projector transitions to a state where it’s basically saying “yeah, sure, you’d like me to turn on. I’ll get to it. Eventually. I’m on my break right now, so stop bothering me.” And while the projector is enjoying a cigarette, it’ll reply to just about every command with:
%1POWR=ERR3
Home Assistant sees that error as fatal for scripts. It shouldn’t be fatal though; the pjlink doc describes that state as “Warm-up status (Transition period from Power-off to Power-on)”. That means that everything using pjlink has to be prepared to do lots of retries until that state goes away. As it stands right now, it doesn’t look like anything is written that way.
Eventually (sometimes up to 40 seconds) the projector will start responding with %1POWR=0 or %1POWR=0 (on or off) but the intermediate state when it’s transitioning between those states is a real problem.
PJLink doc:
So what I actually did was just add a script on the home assistant side that just sends a message to mqtt:
send_projector_on_to_mqtt:
alias: Send projector on to mqtt
sequence:
- action: mqtt.publish
metadata: {}
data:
evaluate_payload: false
qos: '2'
retain: false
topic: projector/power
payload: '1'
description: ''
And I have another machine that watches for mqtt commands and runs various scripts. One of those scripts is:
#!/usr/bin/python # This is client.py file
import sys
import time
import socket # Import socket module
host = "epson11000"
port = 4352
if len(sys.argv) < 2:
print("Usage: pr.py <power_state>")
sys.exit(1)
power_state = sys.argv[1]
result = ""
def execute_cmd(s, cmd):
print("send: ", cmd)
s.sendall(cmd)
response = s.recv(1024)
print("recv: ", response)
return response
with socket.socket(socket.AF_INET,socket.SOCK_STREAM ) as s:
s.connect((host, port))
while result.strip() != b'PJLINK 0':
result = s.recv(1024)
print("recv: ", result)
expect = f'%1POWR={power_state}'.encode()
request_current_state = b'%1POWR ?\r'
set_power_state = f'%1POWR {power_state}\r'.encode()
while True:
response = execute_cmd(s, request_current_state)
if response.strip() == expect:
break
response = execute_cmd(s, set_power_state)
time.sleep(2)
s.close() # Close the socket when done
(some of this is still a bit of work-in-progress; code cleanup is left as an exercise for the reader :-])
That script will just keep trying until the projector reaches the requested state.