• 导航

使用 sg90 舵机控制 HP 1106 打印机

记事本 2024-09-23 67 次浏览
家里打印机由于停电或者其他原因会中断与路由器的连接,导致打印文件时,没有反应,还得手动去重启打印机来解决,虽然出现这种情况不是很多,但是家人解决起来还是得靠口头指挥,非常不方便。
这种情况发生过几次,就考虑能否通过程序来检测打印机状态,一旦检测掉线,就让打印机重启。
程序定时检查打印机状态,这个对于搞程序的同学,不是难事。如何让打印机自动重启?有两种方法
软件来解决,这个需要打印机提供重启命令,涉及到硬件。
额外增加硬件,帮我们手动按重启键
起初,找了找打印机官方说明,没有找到任何线索,想到耗费时间长,先当作备选。
最后,就优先增加硬件来解决。在查询一番资料后,有两种硬件:
推拉式电磁锁。比如小区的门禁,都是这类硬件,通电后,能吸动铁杆,放点后,铁杆通过弹簧还原到初始状态,优点结构简单,给电就行。缺点是,持续给电过程中,会发热;伸缩幅度需要通过机械调整才能精确控制;停留时间依赖通电时间。
舵机。听起来高大上,其实生活中应用也很广泛,比如小朋友遥控车方向控制,有的就使用它。工业上机械臂就使用的是舵机。优点是,幅度和停留时间都可以通过软件精确控制。非工业用的舵机价格很便宜,某宝不到 10块钱。
比较后,最终选择舵机来帮我们手动点击开关。
确定软件和硬件后,剩下就是实现了。
控制舵机软件,采用 Python 来实现,整个代码,加上空行和注释,不到 50 行,非常简单。点击 这里 查看。
控制舵机,需要发送 PWA 命令,控制设备需要有 GPIO 引脚。家里闲置的树莓派正好派上用场,树莓派通过控制 GPIO 引脚来控制 舵机。
最后在树莓派,又启动了一个 web 服务,对外提供服务,路由器通过 HTTP 服务调用 python 来启动舵机,大致的流程是:
路由器 → 调用 HTTP 服务 → 调用 Python 服务 → 启动舵机
舵机硬件,直接粘贴在打印上,如下图
路由器在通过 shell 命令定时检测打印机存活,来完成打印机的重启,代码如下
      
  #!/bin/bash
# 0 */1 * * * /bin/sh /opt/web/shell-collection/check-hp-1106-printer.sh

currentPath="$(cd "$(dirname "$0")"; pwd)"
source ${currentPath}/send-message-util.sh

# 定时监测打印机是否存活
# 打印机离线,调用 sg90 web 执行重启动作
#PRINTER_STATUS="$(lsusb | grep P1106 2>/dev/null)"

CHECK_RETRY=3
RETRY_INTERVAL=3
SG90_WEB_STATUS=`curl -o /dev/null -s -w %{http_code} http://sg90.sixwifi.com/alive`
SG90_WEB_GO=http://sg90.sixwifi.com/go

echo "----The information of environment----"
echo "CHECK_RETRY: $CHECK_RETRY"
echo "SG90_WEB_STATUS: $SG90_WEB_STATUS"
echo "--------------------------------------"


function func_send_log() {
send_message $1 "$(date '+%Y-%m-%d_%H:%M:%S') 执行 check-hp-1106-printer.sh"
}

function func_check_printer() {
PRINTER_STATUS="$(lsusb | grep P1106 2>/dev/null)"
echo "PRINTER_STATUS: $PRINTER_STATUS"
if [ "${PRINTER_STATUS}" != "" ];then
# 打印机正常,直接退出
exit 0
fi
echo "The printer has been offline. Start to run sg90"
if [ $SG90_WEB_STATUS != 200 ];then
# 打印机 和 sg90 proxy 都不正常,没有必要在循环了,直接退出
func_send_log "[ERROR] 「打印机」和「SG90 Web」均离线。"
exit 0
fi
# 执行 sg90
curl -o /dev/null -s $SG90_WEB_GO
# sg90 需要执行一段时间,所以停顿下
echo "wait 10s"
sleep 10
}


while [ $CHECK_RETRY -gt 0 ]
do
echo "Start to retry..., $CHECK_RETRY"
func_check_printer
let CHECK_RETRY--
sleep $RETRY_INTERVAL
if [ "${CHECK_RETRY}" = 0 ]; then
func_send_log "[ERROR] 重试已达上限,打印机还在「离线」状态。"
fi
done