V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
SilencerL
V2EX  ›  分享创造

有目的(di)地(de)瞎折腾——为了温暖的被窝而实现远程开机

  •  1
     
  •   SilencerL · 2021-01-09 19:23:25 +08:00 · 7039 次点击
    这是一个创建于 1401 天前的主题,其中的信息可能已经有所发展或是发生改变。

    0x0

    这个冬天真的太 TM 的冷了,冷到我想一天 24 小时都呆在床上哪儿也不去。本来在这个美好的周六是可以实现这个同样美好的愿望,但是一大早同事来的电话击碎了我的梦想——线上项目出了点问题需要排查一下问题。虽然不情愿,但是寄人篱下给人打工哪能不低头(……),只好抄起枕边的 Surface 看一下到底是啥情况。粗略看了一下发现应该只是配置问题,去后台修改配置项就可以解决。

    正当庆幸不是什么大问题改完就能继续 V 坡(本地方言睡觉)时我突然悲剧的发现:登录后台的账号密码入口在内网的一个服务上,公司的 VPN 只装在距离我床大概两米的台式机上,平时只要远程连过去就可以,但是台式机昨晚上被我手贱关机了……如果要开机势必要爬出温暖的被窝。就是在这么一个 2021 年冬日的早晨,从被窝到书桌,两米的距离好似咫尺天涯,就像鱼儿与飞鸟一个在天上一个在深海;又好似我与喜欢的人,永远不会有交会的轨迹(……)。我大概尝试了 25565 种体位,不管怎么探出手抑或用拖鞋辅助,都没法实现人在床上摸到电脑开机键。万般无奈下只好跳出被窝—冲去开机—杀回被窝(天知道这么冷为什么我还要裸睡)。

    0x1

    经过这么一番折腾也没啥心思接着睡觉了,为了生活的美好和温暖的被窝,我决定思考一下如何实现远程开机。正常情况下是可以借助 WOL ( Wake On LAN )来实现,但是前段时间网线坏了,所以一直都是用 WiFi 联网,然而大部分无线网卡是不支持 WOL 的。既然目前 WOL 这条路走不通,那就从硬件方面下手。

    主板控制电脑开机是通过 Power SW( Power Switch )的两个引脚开合状态来控制的,通常情况下这两个引脚的状态是 ON(常开),当这两个引脚的闭合(短接)时间超过一定阈值主板则进行开关机操作,当时间更长一点则进行强制关机的操作。所以我们只要想办法远程控制这两个引脚的开合就可以实现远程开机和远程强制关机(当远程操作的时候电脑宕机了就会发现远程强制关机多么重要……),同时顺便把 WOL 给支持进去。

    0x2

    了解了主板开机的原理后开始考虑下如何实现目标。大概的上网搜索了一下信息,发现了一个 Blinker 平台提供了一大坨非常方便入手的 SDK 和文档之类的,配合廉价的 ESP 8266 模块可以快速搭建物联网设备。这样我们可以通过 ESP 8266 + 继电器 + Blinker 平台并稍微动手接一下电路构建一个远程开关机模块。

    需要的物料:

    • ESP 8266 ESP-01s 模块
    • ESP-01s 继电器模块(上游厂家已经组装好的配合 ESP 8266 ESP-01s 的继电器模块,通过 ESP 8266 的 GPIO 0 控制,低电平激活)
    • 杜邦线若干
    • CH340C 烧录器

    需要的软件(点击可查看或下载)

    Arduino IDE 配置

    • 首选项 - 附加开发板管理器网址 输入 https://arduino.esp8266.com/stable/package_esp8266com_index.json
    • 工具 - 开发板 - 开发板管理器 - 搜索 8266 并安装
    • 项目 - 加载库 - 加载 .ZIP 库 - 选择下载的 Blinker SDK
    • 安装 CH340 驱动
    • 工具 - 开发板 - ESP8266 Boards - 选择 Generic ESP8266 Module
    • ESP 8266 插烧录器,烧录器插 USB
    • 工具 - 端口 - 选择烧录器所使用的的端口

    需要的工具

    • 螺丝刀
    • 脑子和手

    其他

    需要先在点灯的 App 中参照下图添加设备:

    0x3

    获取到 Secret Key 并且添加功能按钮结束后参照如下代码(代码写的烂请多见谅;其中包括硬件启动和 WOL ):

    #define BLINKER_WIFI
    // 不加密通信,减小固件体积,我提供的固件编译后较小可以去掉这一行
    #define BLINKER_WITHOUT_SSL
    // 继电器为 ESP 8266 的 GPIO 0 控制
    #define RELAY 0
    
    #include <Blinker.h>
    
    const char *auth = "{申请的 Secret Key}";
    const char *ssid = "{2.4G WiFi 名称}";
    const char *pwd = "{WiFi 密码}";
    
    WiFiUDP UDP;
    char wolBuffer[102];
    // 目标主机 MAC 地址
    const char mac[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    
    // 绑定 Button
    BlinkerButton PowerButton("btnTogglePower");
    BlinkerButton HardShutButton("btnHardShut");
    BlinkerButton WakeOnLANButton("btnWakeOnLAN");
    
    void setup() {
      Serial.begin(115200);
    
      BLINKER_DEBUG.stream(Serial);
    
      // 定义 GPIO 0 为输出端
      pinMode(RELAY, OUTPUT);
      // 默认 GPIO 0 高电平,继电器模块为低电平激活
      digitalWrite(RELAY, HIGH);
    
      Blinker.begin(auth, ssid, pwd);
    
      // 绑定事件
      PowerButton.attach(OnPowerButtonTap);
      HardShutButton.attach(OnHardShutButtonTap);
      WakeOnLANButton.attach(OnWakeOnLANButtonTap);
      
      UDP.begin(9);
      WOLPacketInit();
    }
    
    void loop() {
      Blinker.run();
    }
    
    // 生成 WOL 数据包
    void WOLPacketInit(){
      int i, j;
      
      for(i = 0; i < 6; i++){
        wolBuffer[i] = 0xFF;  
      }
      
      for(i = 0; i < 16; i++){
        for(j = 0; j < 6; j++){
          wolBuffer[6 + i * 6 + j] = mac[j];  
        }
      }
    }
    
    void SendWOLPacket(){
      // 向指定广播地址播报 WOL 数据包
      // Broadcast 可以通过 ifconfig 查看,WOL 端口是 7 或 9 可以自己尝试
      UDP.beginPacket("{Broadcast (广播地址)}", 9);
      UDP.write(wolBuffer);
      UDP.endPacket();
    }
    
    void OnPowerButtonTap(const String & state) {
      digitalWrite(RELAY, LOW);
      // 200ms 短按开机
      Blinker.delay(200);
      digitalWrite(RELAY, HIGH);
    }
    
    void OnHardShutButtonTap(const String & state) {
      digitalWrite(RELAY, LOW);
      // 5000ms 长按强制关机
      Blinker.delay(5000);
      digitalWrite(RELAY, HIGH);
    }
    
    void OnWakeOnLANButtonTap(const String & state){
      SendWOLPacket();
    }
    
    

    将上述代码通过 CH340C 烧录到 ESP 8266 中,等待烧录成功

    可以提前打开 工具 - 串口监视器 查看,出现下面这些信息即为烧录成功,可以在点灯 App 上点击按钮操作一下看一下是否正常(在代码里相应位置写一下日志输出,我没写……)。

    0x4

    软件和烧录部分准备结束,下面要把模块接入到机箱里面。首先一个问题是模块的供电从哪里来,第一想到的是改一个 USB 接口然后通过外接电源供电,但是这样就要额外拖一条线在外面总感觉很蠢。突然想起来电脑的电源肯定是有持续供电的,否则一些电脑的关机后 USB 口持续供电功能怎么来的。查阅了一下 24 PIN 电源针脚定义,发现的确是有持续供电的针脚( PIN 9,5V SB ),刚好满足继电器模块的工作电压范围( DC 5V - 12V )。

    所以我们只需将供电正极接在 PIN 9,负极接在随便一个 GND (接地)针脚即可(距离 PIN 9 最近的 GND 是 PIN 7 ),如图所示:

    继电器模块提供了 NOCOMNC 三个接口,其中 NO 是常开端(电路非闭合),NC 是常闭端(电路闭合),COM 是公共接口。所以我们只需要用到 NO 和 COM 两个接口,平常是常开状态,根据上文的代码当 ESP 8266 收到对应指令后会将 GPIO 0 口输出低电平进而控制继电器闭合,模拟开机按键的操作,GPIO 0 口输出低电平的时间就是按下电源按键的时间,短按开机长按强制关机。

    按照要求接好线:

    然后将 Power SW 线接回主板控制针脚,主机上电试一下:

    (此处假装有动图或者视频)

    可以看到手机上点击电源后伴随着继电器一声清脆的“咔哒”声,电脑成功开机~ 点击硬关机后电脑也成功强制关机,WOL 功能因为没有网线所以暂时没法测试,不过大差不差应该是没问题的。

    0x5

    最后要考虑的问题是,怎么把这个模块稳妥的放在机箱内。毕竟有很多裸露的触点机箱内又有金属部分很容易误触导致短路,轻则模块 工作异常,重则主板 GG 。

    经过慎重的考虑……我决定发挥垃圾佬的精神,用一个地上捡的自封袋把模块装起来(绝缘),然后用扎线带绑在内部的电源线上(固定),这样最低成本解决两个问题简直美哉~

    0x6

    至此,这套远程开机模块已经可以完美的初步运行,接下来可以考虑进行一系列的优化:

    • 设备运行状态判断

      • 可以通过主板上 Power LED 针脚判断,如果主板正常上电则 Power LED+ 为高电平,判断此针脚电平高低即可得知设备是否正常启动。
      • 其次可以通过 Ping 去判断设备是否运行并正常进入系统且连接网络。
    • 接入其他智能设备

      • Blinker 提供的 SDK 可以将我们的设备接入诸如“小爱同学”、“Siri”之类的智能设备 /语音助手,可以实现躺在床上手机都不用拿起来,直接来一句“Hey Siri,打开老子的电脑”
    • OTA 更新固件

      • 看了下 Blinker 的文档,似乎是支持远程更新固件,这样就不用每次更新程序都要拆开机箱拿出芯片再烧录(天知道当时我为什么要买这么个全铝闷罐子机箱,拆卸困难散热费劲简直垃圾)。不过这个功能要付费买专业版才可以( 99 一年也不贵),等心情好再去折腾。

    做完之后算了一下成本,ESP 8266 + 继电器模块大概 16 元左右,杜邦线原来用剩下的大概几毛,烧录器 10 块左右可以用到把我送走。其实这价钱可以买一个成品的远程开机设备了,但是毕竟自己瞎折腾才算是 Geeker 嘛。享受一下自己从查资料到动手最后实现目标功能的过程才是最大的乐趣。

    其他好玩的


    EnD

    Worte with ❤ by Wood.

    第 1 条附言  ·  2021-01-09 21:10:19 +08:00
    Typo
    Worte => Wrote
    第 2 条附言  ·  2021-01-09 21:59:50 +08:00

    有了远程开机模块的成功经验,我已经把门禁拆下来准备搞一波远程开门禁了,毕竟外卖小哥在楼下按门禁的时候我也不一定想从被窝里出来。。

    39 条回复    2021-08-05 09:36:59 +08:00
    ruokw
        1
    ruokw  
       2021-01-09 19:40:04 +08:00 via Android
    强还是你强,归根到底还是吃的太饱,有余力。 doge
    SilencerL
        2
    SilencerL  
    OP
       2021-01-09 19:45:36 +08:00 via iPhone
    @ruokw
    如果天气没这么冷大概我真的懒得拆机箱搞这个 /doge
    z7356995
        3
    z7356995  
       2021-01-09 19:48:47 +08:00 via Android   ❤️ 1
    曾经也和你一样吃得太饱,现在到了能用钱解决的,绝不浪费时间了
    DAPTX4869
        4
    DAPTX4869  
       2021-01-09 20:05:46 +08:00
    大佬牛逼...
    菜鸡还是选择小米智能插座吧...
    Devin
        5
    Devin  
       2021-01-09 20:06:04 +08:00 via Android   ❤️ 5
    谢谢分享,很有意思
    还好我有撑衣杆
    Osk
        6
    Osk  
       2021-01-09 20:12:52 +08:00 via Android
    我选择修好网线 /doge/
    shenyi97
        7
    shenyi97  
       2021-01-09 20:14:36 +08:00
    挺好的,但我觉得最好用电工胶带缠几圈固定一下。
    mingzhi
        8
    mingzhi  
       2021-01-09 20:35:11 +08:00
    福州人?
    lloovve
        9
    lloovve  
       2021-01-09 20:47:39 +08:00 via iPhone
    淘宝 25 搞定,开机模块,我最近这种 esp8266 做了一个电热毯恒温控制器
    wangxiaoaer
        10
    wangxiaoaer  
       2021-01-09 20:53:58 +08:00
    软文不错。

    顺便问下,原理是什么?那个继电设备持续联网,连接到 blinker 的服务器?联网怎么设置的。
    idblife
        11
    idblife  
       2021-01-09 20:57:32 +08:00   ❤️ 1
    找个女朋友吧
    SilencerL
        12
    SilencerL  
    OP
       2021-01-09 21:01:15 +08:00
    @Devin #5
    谁会在床上放撑衣杆啊我摔!!


    @mingzhi #8
    是的哈哈哈


    @wangxiaoaer #10
    虽然的确不是软文……但是经你提醒我应该去应聘下软文写手哈哈哈。原理大概是 ESP 8266 通过 MQTT 协议与服务器建立“长连接”,配网信息是硬编码在固件里的,没去研究怎么通过点灯 App 自定义配网信息


    @DAPTX4869 #4
    主要是智能插座只能通过设置“通电自动开机”,没法实现更多自定义操作(比如异常关机开机或强制关机操作)
    yanfany
        13
    yanfany  
       2021-01-09 21:44:29 +08:00   ❤️ 1
    挺好的,应该是这个月为止在 v 站看到最有趣的帖子了(狗头 ,需求痛点也戳到我了,南方人的冬天真的一言难尽,能缩在被窝是真的幸福,主要解决方案也设计的很好,让我重新想起本科硬件课程的几个实验带来的那种成就感和乐趣,可惜现在只会在坑里炼丹 hh
    zzzhen
        14
    zzzhen  
       2021-01-09 21:51:41 +08:00
    有意思
    niubee1
        15
    niubee1  
       2021-01-09 23:08:14 +08:00
    其实,你在床头放一根衣架叉子,就 OK 了
    Mountain
        16
    Mountain  
       2021-01-10 00:21:35 +08:00
    哈哈哈哈哈哈哈我也选择修网线
    SilencerL
        17
    SilencerL  
    OP
       2021-01-10 00:27:28 +08:00
    @yanfany #13
    哈哈哈哈哈哈感谢支持 祝 2021 炼丹愉快


    @Osk #6
    @Mountain #16
    口享!主要是 WOL 在有些时候会失灵,而且出了局域网就受限;之前如果我在公司想开家里的电脑,需要先通过 FCN 连到家里主路由的网络,然后 SSH 连接主路由 -> 在主路由上 SSH 到二级路由 -> 在二级路由发送 WOL Packet 。救国途径过于曲线……
    Elethom
        18
    Elethom  
       2021-01-10 01:44:21 +08:00 via iPhone
    这是家宴吃太饱了? 🐶
    wtks1
        19
    wtks1  
       2021-01-10 02:50:22 +08:00 via Android
    呃,我觉得修好网线可能更快一点...
    DoctorCat
        20
    DoctorCat  
       2021-01-10 03:45:40 +08:00
    说不支持 WOL 的网卡,那是有多老啊 😂
    nuk
        21
    nuk  
       2021-01-10 04:53:48 +08:00   ❤️ 1
    控制信号开关这种,来个 mos 管就行了啊,比继电器小多了,还少接两根线
    carlclone
        22
    carlclone  
       2021-01-10 09:16:29 +08:00
    智能插座通电开机就好了。。一星期前才搞,成本 19 元
    SilencerL
        23
    SilencerL  
    OP
       2021-01-10 13:04:48 +08:00 via iPhone
    @DoctorCat
    ……可以列举几个常见的支持 WOL 的无线网卡吗
    ysc3839
        24
    ysc3839  
       2021-01-10 13:31:36 +08:00 via Android
    @SilencerL #17 看你的描述,路由器是配置成了多层 NAT,配置正确的话两个路由器和电脑都是在同一个局域网的,直接在主路由上发送 WOL 就能唤醒。
    SilencerL
        25
    SilencerL  
    OP
       2021-01-10 15:01:25 +08:00 via iPhone
    @ysc3839
    因为装修布线限制,目前是主路由带两个二级路由( A 和 B ),然后主路由配置静态路由让两个二级路由在一定程度上互通。
    我的描述可能有误,二级路由 A 有 FCN 服务,所以我是从外部通过 FCN 连接到路由 A 的网络,然后 SSH 到路由 B 再发送 WOL 包。虽然路由 A 和路由 B 通过静态路由可以互相访问了但是 WOL 包过不去。
    本来可以把两个二级路由当交换机使用,让所有设备都在主路由网断下,但是这样两个二级路由的一些特殊服务就没法用了。。就很蛋疼,只能这么先用着
    hhyygg
        26
    hhyygg  
       2021-01-10 21:58:02 +08:00 via Android
    intel ax200 可以 wowlan😂楼主能搞出一套东西,太强了
    Kiriya
        27
    Kiriya  
       2021-01-10 21:59:51 +08:00
    你们搞的太复杂了,遥控开机了解下,开机板串联接电源按钮上
    SilencerL
        28
    SilencerL  
    OP
       2021-01-10 22:30:17 +08:00
    @hhyygg #26
    WoWLAN 只能有限的唤醒睡眠状态吧,无法和 WOL 一样打开关机状态的电脑好像?
    lili1397
        29
    lili1397  
       2021-01-10 23:05:31 +08:00
    创意不错。今年流行远程办公,公司的电脑有时候需要远程开机,做好了还是能用的上的。
    这个启动装置用树莓派来做,硬件会少很多。
    jerfoxu
        30
    jerfoxu  
       2021-01-11 09:21:38 +08:00
    牛逼呀,特别适合钉钉打卡的
    itianjing
        31
    itianjing  
       2021-01-11 17:14:17 +08:00
    我目前的方案是 BIOS 设置通电开机,然后电脑电源插在智能插座上,需要开机的时候吼一声小爱同学(大爱同学,小赖同学……昨天晚上发现主要唤醒词是 4 个字同时第二个字以“ai”结尾都能唤醒,所以以后就叫它大爱同学了)就好了。
    SilencerL
        32
    SilencerL  
    OP
       2021-01-11 17:28:06 +08:00
    @itianjing #31 对对对 我也发现小爱同学的唤醒逻辑是四个字中后面三个字匹配的哈哈哈哈哈哈哈
    pytth
        33
    pytth  
       2021-01-14 09:45:10 +08:00
    太麻烦了,可以拆开机箱,网上买一个远程开机的针脚(十几块),再买一个 Gosund 智能插座连上 wifi (官方价 39 元),接入米家 app,用手机开机即可,电脑通电就开机。
    yutou527
        34
    yutou527  
       2021-01-14 10:34:23 +08:00
    远程门禁三年前我已经实践成功了😂
    SilencerL
        35
    SilencerL  
    OP
       2021-01-14 10:42:19 +08:00
    @pytth #33
    我感觉点外卖挺方便的, 但是为啥还有人下厨自己做饭.


    @yutou527 #34
    我们这门禁是 POE 供电, 无信号的时候只有两个 1.5V 左右的点容给低负载的芯片供电, 当主动按下视频按钮或楼下按了门禁才会有 5V 的供电从 POE 交换机过来, 所以外部芯片找不到地方供电.. 拉明线又太蠢.
    目前初步准备先用 POE 分离器从 POE 线里面分离出信号和电源, 再想下一步怎么搞了...
    yutou527
        36
    yutou527  
       2021-01-14 11:35:46 +08:00
    我当时用的独立供电的树莓派,拉了超长的线到门禁,没想过在门禁偷电,随便搞搞。😂
    zacharyjia
        37
    zacharyjia  
       2021-01-17 11:12:06 +08:00
    其实应该是 written (逃
    jsgbsj
        38
    jsgbsj  
       2021-01-17 18:57:21 +08:00 via Android
    真羡慕你还有精力去倒腾
    coloz
        39
    coloz  
       2021-08-05 09:36:59 +08:00
    才看到,嘻嘻
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1141 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 18:13 · PVG 02:13 · LAX 10:13 · JFK 13:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.