实战:SoftAgent 直控投影机与播放器(不上中控主机)
- 用 SoftAgent 的 pjlink 指令控制投影机开关机与切信号源
- 用 sendtcp / sendudp / sendhttp 给播放器等网络设备直接下发报文
- 把多条设备指令串成"开馆/闭馆"两个可复用的动作
- 看懂设备控制类指令的错误码,能自己定位连不上/超时/认证失败
- 判断清楚什么场景该用这条轻量路线、什么场景必须上中控
| 器材 | 数量 | 参考 |
|---|---|---|
| SoftAgent(设备控制指令免费版可用) | 1 | — |
| 支持 PJLink 的投影机 | 1 | — |
| 支持网络指令的播放器/处理器(可选) | 1 | — |
| 交换机 + 网线 | 1套 | — |
价格随渠道波动,以购买页实时为准。
器材清单
| 名称 | 数量 | 说明 |
|---|---|---|
| SoftAgent | 1 | 装在展厅那台播放电脑上;设备控制这几条指令免费版就能用 |
| PJLink 投影机 | 1 | 需接网线、设固定 IP、菜单里开启网络控制 |
| 网络播放器/处理器 | 1(可选) | 支持 TCP/UDP/HTTP 指令的都行,没有可以跳过对应小节 |
| 交换机 + 网线 | 1 套 | 投影机、播放电脑在同一网段 |
本节涉及投影机开关机。投影机关机后有 60~90 秒散热期,期间无法再开机,测试时别急着反复开关,容易误判成"指令没生效"。
先想清楚:为什么不用中控主机
前面几节讲的都是"中控主机 + 各种网关"的标准路线,这一节反过来问一句:一两台投影的小场子,值得为它单配一台中控主机吗?
算笔账。中控主机、控制面板、布线、调试,加起来是一笔不小的开支和工期。而如果需求只是"每天到点开投影、闭馆关掉、偶尔切个信号源",这些动作本质上就是往投影机的网口上发几条文本命令而已。
展厅里本来就有一台常年开着的电脑——那台放片子的播放主机。让它顺带兼任发指令的角色,硬件成本是零。
这条路线的能力边界后面会讲清楚,先动手做出来。
第一步:确认投影机这端准备好了
三件事,缺一条后面都不通:
- 接网线、设固定 IP。DHCP 分的地址会变,一变脚本就失灵。在投影机菜单里设静态 IP,或在路由上做 MAC 绑定。
- 开启网络控制 / PJLink。有些机型出厂默认关闭,菜单里找"网络设置",名字可能叫 PJLink、网络控制、或者 Crestron/AMX 兼容。
- 待机模式选"网络待机",不要选"节能待机"。节能模式下投影机关机后会切断网卡供电,你发再多开机指令它都收不到。
第三条是远程开不了机最常见的原因,没有之一。装机时顺手改掉,能省掉日后无数次跑现场。
先用 ping 确认投影机 IP 通,再往下走。PJLink 协议本身的细节(命令格式、认证握手、Class 1/2 区别)在用 PJLink 控制投影机开关机里讲透了,这一节聚焦"怎么让 SoftAgent 去发"。
第二步:用 SoftAgent 发第一条 PJLink
沿用上一节那个 Send-Agent 函数。设备控制类指令推荐用 JSON 形式下发,字段清晰、不会有转义歧义:
$cmd = @{
cmd = 'pjlink'
host = '192.168.1.10' # 投影机 IP
command = 'POWR 1' # 开机
} | ConvertTo-Json -Compress
Send-Agent -Ip '192.168.1.50' -Cmd $cmd # 192.168.1.50 是被控电脑
注意这里有两个 IP,别搞混:指令发给被控电脑(.50),被控电脑再去连投影机(.10)。SoftAgent 在中间做了一次转发,这正是它的价值——你不需要能直连投影机,只要能连上那台播放电脑就行。
你应该看到——投影机风扇转起来开始预热,控制端返回 ok:pjlink,payload 里带着设备的响应原文。
关机同理,把 command 换成 POWR 0。切信号源用 INPT 31(3x 是数字输入,31 通常对应 HDMI1,但各厂商编号排法不一样,要挨个试过记下来,别照抄别人的表)。
投影机设了 PJLink 密码的话,加一个 password 字段就行,MD5 认证握手由 SoftAgent 内部处理,你不用自己算摘要:
$cmd = @{
cmd = 'pjlink'
host = '192.168.1.10'
command = 'POWR 1'
password = 'your-pjlink-password'
} | ConvertTo-Json -Compress
还可以带 port(默认 4352)和 timeoutMs(默认 5000,是整个操作的墙钟上限)。
第三步:给播放器发 TCP 报文
投影机有 PJLink 这种标准协议,播放器、矩阵、处理器这类设备大多是各家自定义的私有协议——说明书上给一张十六进制指令表,让你往某个端口发。
sendtcp 就是干这个的,text 和 hex 二选一:
# 十六进制形式(最常见,照着说明书的指令表填)
$cmd = @{
cmd = 'sendtcp'
host = '192.168.1.60'
port = 5000
hex = 'AA 01 05 FF'
} | ConvertTo-Json -Compress
Send-Agent -Ip '192.168.1.50' -Cmd $cmd
# 文本形式(有些设备用 ASCII 指令)
$cmd = @{
cmd = 'sendtcp'
host = '192.168.1.60'
port = 5000
text = "PLAY`r`n"
} | ConvertTo-Json -Compress
hex 大小写不敏感,带不带空格都行。文本形式支持 \r \n \t \0 \xNN 这几种转义。
你应该看到——返回 ok:sendtcp,payload 是设备回读内容的可打印表示。这里有个设计细节要知道:读不到响应不算失败。很多设备收到指令就默默执行、根本不回话,所以只要连上并发出去了就算成功,别因为 payload 是空的就以为没生效——看设备的实际反应才准。
UDP 和 HTTP 是同一套路子:
# UDP(默认不等回包)
@{ cmd='sendudp'; host='239.0.0.1'; port=5000; hex='AA BB' } | ConvertTo-Json -Compress
# HTTP(METHOD 支持 GET/POST/PUT/DELETE/HEAD)
@{ cmd='sendhttp'; method='GET'; url='http://192.168.1.70/play' } | ConvertTo-Json -Compress
# HTTP 带 body
@{ cmd='sendhttp'; method='POST'; url='http://192.168.1.70/api';
body='{"cmd":"play"}'; contentType='application/json' } | ConvertTo-Json -Compress
sendhttp 的回执有个区分:2xx 回 ok:sendhttp,非 2xx 回 err:sendhttp.status,两种情况都会把状态码和响应体片段带回来,方便你判断到底是网络不通还是设备拒绝了。
第四步:串成开馆 / 闭馆流程
单条指令能通了,把它们串起来才有实用价值。开馆流程的典型顺序:
$AGENT = '192.168.1.50'
# 1. 投影机开机
Send-Agent -Ip $AGENT -Cmd (@{cmd='pjlink';host='192.168.1.10';command='POWR 1'} | ConvertTo-Json -Compress)
# 2. 等预热(关键,别省)
Start-Sleep -Seconds 40
# 3. 切到 HDMI1
Send-Agent -Ip $AGENT -Cmd (@{cmd='pjlink';host='192.168.1.10';command='INPT 31'} | ConvertTo-Json -Compress)
# 4. 启动本机播放软件
Send-Agent -Ip $AGENT -Cmd 'startpro:0'
那个 Start-Sleep 40 是重点。 投影机开机后有预热期,期间不接受其它指令,你紧接着发切源它会回 ERR3(当前状态无法执行)。很多人第一次串流程都栽在这,以为指令写错了,其实只是太急。
讲究一点的做法是轮询状态而不是死等:反复发 POWR ?,直到返回值是 1(已开机)再往下走。返回 3 表示还在预热,2 表示冷却中。
闭馆反过来,注意先关投影再关电脑——投影机需要散热时间,跟着电脑一起断电对灯泡不好:
Send-Agent -Ip $AGENT -Cmd 'killall' # 停播放软件
Send-Agent -Ip $AGENT -Cmd (@{cmd='pjlink';host='192.168.1.10';command='POWR 0'} | ConvertTo-Json -Compress)
Start-Sleep -Seconds 90 # 等散热
Send-Agent -Ip $AGENT -Cmd 'shutdown:60' # 电脑延时关机
把这两个脚本挂上定时任务,无人值守的开闭馆就成了。更稳的做法是把定时也交给端侧——SoftAgent 自带定时任务,断网照样触发,配法见展厅电脑端侧定时任务。
进阶:用轮询状态代替死等
上面那个 Start-Sleep 40 能用,但不够聪明——投影机型号不同,预热时间从 20 秒到 60 秒都有。等短了切源失败,等长了浪费开馆时间。
更稳的做法是轮询电源状态,就绪了立刻往下走:
function Wait-ProjectorReady {
param([string]$Agent, [string]$Host, [int]$MaxWait = 90)
$sw = [Diagnostics.Stopwatch]::StartNew()
while ($sw.Elapsed.TotalSeconds -lt $MaxWait) {
$q = @{cmd='pjlink'; host=$Host; command='POWR ?'} | ConvertTo-Json -Compress
$r = Send-Agent -Ip $Agent -Cmd $q
# 回执 payload 里带设备响应原文,形如 %1POWR=1
if ($r -match 'POWR=1') { return $true } # 1 = 已开机
if ($r -match 'POWR=3') { Write-Host '预热中…' } # 3 = 预热
if ($r -match 'POWR=2') { Write-Host '冷却中…' } # 2 = 冷却
Start-Sleep -Seconds 3
}
return $false
}
if (Wait-ProjectorReady -Agent $AGENT -Host '192.168.1.10') {
Send-Agent -Ip $AGENT -Cmd (@{cmd='pjlink';host='192.168.1.10';command='INPT 31'} | ConvertTo-Json -Compress)
} else {
Write-Host '投影机超时未就绪,检查设备'
}
POWR ? 的四个返回值要记住:0 关机、1 开机、2 冷却中、3 预热中。冷却和预热这两个过渡态是展厅脚本翻车的重灾区——不认这两个状态,写出来的流程就是薛定谔的,有时候好使有时候不好使。
多台投影一起等的话,别串行等(三台就是三倍时间),改成先全部发开机指令,再统一轮询所有设备直到都就绪。
怎么找到设备的指令表
PJLink 是标准协议,命令是固定的。但播放器、矩阵、处理器这些大多是私有协议,指令得自己找。几条路子:
一是翻说明书的"通讯协议"章节。 商用设备的说明书通常有一节专门讲串口/网络控制,给出指令表和端口号。这是最权威的来源。
二是找厂商要。 说明书上没有的话,直接问技术支持要"网络控制协议文档",多数厂商都提供。采购阶段就该问清楚支不支持网络控制,别等装完了才发现只能用遥控器。
三是抓包。 设备自带的控制软件能控,说明协议是通的。用抓包工具看看它发了什么,照着复现。这招在文档缺失时很管用,但要注意有些设备有握手或校验位。
拿到指令表之后,先用指令编码转换器把 ASCII 转成 HEX、算好校验位,再用 SoftAgent 发出去。不确定格式对不对时,先用 sendtcp 发一条查询类指令(比如"查询当前状态"),这类指令无害且通常有回包,最适合验证链路。
第五步:日常巡检顺手做
设备控制通了之后,有两条查询指令值得挂进每周巡检:
# 灯泡使用小时数
@{cmd='pjlink';host='192.168.1.10';command='LAMP ?'} | ConvertTo-Json -Compress
# 错误状态:6 位数字,依次是 风扇/灯泡/温度/滤网/盖板/其它
@{cmd='pjlink';host='192.168.1.10';command='ERST ?'} | ConvertTo-Json -Compress
灯泡衰减是渐进的,等到画面明显发暗才换,中间那段时间观众看到的一直是打折的画面。ERST ? 则能提前发现滤网堵塞、温度偏高这类还没到报警程度的隐患。这是最省事的预防性维护,成本几乎为零。
错误码速查
设备控制类指令的错误码很有指向性,看懂了排错快很多:
| 错误码 | 含义 | 怎么办 |
|---|---|---|
pjlink.connectFailed |
TCP 4352 连不上 | 查投影机 IP、网络控制开关、防火墙 |
pjlink.timeout |
连上了但没在超时窗内回话 | 调大 timeoutMs;查设备是否忙 |
pjlink.authRequired |
设备要密码,你没给 | 加 password 字段 |
pjlink.authFailed |
密码错 | 核对投影机菜单里设的 PJLink 密码 |
pjlink.err3 |
当前状态无法执行 | 多半是预热/冷却中,等一会儿或先查 POWR ? |
pjlink.err1 |
未定义命令 | 命令名拼错,或该机型不支持 |
pjlink.err4 |
投影机故障 | 发 ERST ? 看具体哪一项 |
sendtcp.connectFailed |
连不上目标设备 | 查 IP、端口、设备是否在线 |
sendtcp.timeout |
超时 | 设备可能不回包,属正常;确认实际动作是否执行 |
sendudp.connectFailed |
发送失败或 DNS 解析失败 | UDP 无独立超时码,这一条兼管超时 |
sendhttp.status |
设备返回非 2xx | 看回执里的状态码和响应体 |
dispatch.unknownVerb |
指令名写错 | 发 describe 看支持的指令表 |
这条路线的边界在哪
必须诚实说清楚:轻量路线解决的是"到点开关一两台设备",不是"一个按钮统管全场"。 碰上下面任意一条,就别硬扛了,老实上中控:
- 要墙面控制面板或平板一键操作——脚本没有界面,现场讲解员没法用;
- 要联动非网络设备——幕布、灯光、电动窗帘走继电器或 RS485,得有硬件去接,见SoftControl + 网络继电器实战;
- 要复杂场景编排——"迎宾模式"同时开投影、降幕布、调灯光、起片子,还讲究先后时序;
- 设备数量上去了——十几台以上还用脚本挨个连,出错定位会很痛苦。
中控与轻量路线的选型判断,中控系统怎么选那一节有更完整的对比。
小结
这一节做的事,本质上是把那台常年开着的播放电脑,变成了一个微型中控。
投影机走 PJLink 标准协议,播放器走各家私有协议的 TCP/UDP/HTTP,SoftAgent 在中间做转发——你只需要能连上这台电脑,就能间接指挥它身后的所有设备。这几条设备控制指令在免费版里就能用,对小场子来说,硬件成本是零。
串流程时记住两个"等":开机后等预热再切源,关机后等散热再断电。这两个 sleep 是新手最容易省掉、也最容易翻车的地方。
本教程对应产品
查看产品详情 →