之前组了NAS之后也是用了一段时间,好用是挺好用的,现在慢慢的把各种服务都迁移了过去。但是始终有个问题,就是没法远程看到电脑的显示。联想这种主板挺有特色,风扇碰一下就不开机了,想排查只能接显示器看看是按哪个键继续。
另外比较难顶的是,这个板子没有IPMI。虽然支持Intel的vPro技术(或者说AMT),但是W2133这个U是没有核显的,进而导致vPro的页面上kvm的功能就纯纯变成了一个摆设。远程用vPro的时候,除了开关机和看着串口干瞪眼,啥也干不了。想改BIOS只能搬个小板凳去客厅,把电视接到NAS上去改。
不过买都买了,组都组了,总不能就这么扔了。所以也就是凑活用用看看有没有解决办法。网上查到可以给BIOS加串口重定向,然后可以用串口控制台调BIOS。BIOS加上串口重定向之后,确实就是可以在网页上调了,但是中文支持还有问题,显示的全是方块。后来我在淘宝上花16块买了个采集卡,接到了平板上把视频流导了出来,这样用手机就能看显示的内容。这样输出倒是不用占一个显示器了,但是输入还是没解决。想重装个系统,调个阵列卡BIOS啥的还是得人去蹲着,毕竟出了主板BIOS就不关你串口控制台的事了。
在被迫蹲在NAS前面调了几次阵列卡BIOS后,为了我的脊椎健康,我决定还是手搓一个kvm用。
方案
主要考虑一下硬件的选型。
我手里已经有了一个x86的平板,所以就直接用了平板作为采集卡的捕获设备。采集卡的话,反正能看就行,所以就是直接淘宝买了个最便宜的采集卡,也就半顿外卖钱。键鼠输入模拟的话,本来想看看vPro能不能行,但是没想到kvm必须得建立显示连接,反正我是没找到不开视频只接输入的选项。找了找淘宝上卖的这种都很贵,无奈只好自行用esp32实现一个。
esp32并不是全系都有USB从机模式。我手里现有的几个esp32都没有usb功能,板子上的USB口连接是CH340,只能当串口用。经过详细的查询后,我发现esp32-c2的板子应该是最理想的选择。淘宝上的话,大概8元一个包邮。于是就决定买一个试试水。选择esp32系列的原因是,这个板子同时还可以连接Wifi,并且资料比较丰富。我之前也接触过esp系列的板子,也算是路径依赖了。
实现
前端
前端用网页实现,分别去请求视频流和发送键鼠的捕获数据。视频流直接用img标签至于顶层,页面会尝试捕获所有的键鼠输入,然后发送给esp32。
输出
其实输出部分之前已经算是做好了,逻辑也很简单,用python的opencv库,把摄像头的图像转成jpeg,用一个flask框架搭一个web服务,打开浏览器访问这个服务,就能看到画面了。
上位机使用的是x86平板,实际上任何能跑python并且能读UVC摄像头的设备应该都可以。手上的树莓派因为之前把sd卡搞炸了,就没用。把视频流接口的URL提取出来,丢到网页上就行。
输入
输入部分用esp32实现,代码使用了cursor配合platformIO去编写,使用了arduino框架里面的hid库。
一开始的想法是用http post请求,用json去上报键鼠的操作数据。花了一晚上,指挥cursor把整个功能写完了后,用了用才发现,这个操作流畅度不能说是有点流畅吧,只能说是完全没有,还会出现松开键之后一直识别为长按的情况,根本没法用。cursor生成的键值对应也是错的离谱,一个都对应不上。这里放一个键值的参考:鍵盤鍵碼值對照表。
于是后面改了改键值映射,通信也换用了websocket协议。换上websocket协议之后,确实是马上流畅的起来,但是又开始犯新毛病了,鼠标随便晃两下,这个websocket就自己断了。键盘功能倒是没啥问题。
用浏览器的开发者工具看了一下,发现一个websocket从发送到响应大概要10来ms,网页上一晃鼠标,这实时的请求全发过去,单片机就只顾着处理请求管不上连接了,所以websocket的连接就断了(纯推测,因为没法看串口日志)。
接下来就是想想办法能不能把这10ms优化一下。首先想到就是干掉json解析。既然功能已经验证没有问题了,那就优化一下内部的逻辑。把数据的请求从json格式改成了裸的二进制,把websocket的响应报文也干掉。这下再晃鼠标就不断连了。
总结
实际看起来还挺像模像样的,配合vPro的iso挂载功能也是能做到100%无人值守了。
晚点有空再把项目代码打包放到github上。