基于 MicroPython 的 WOL (远程唤醒)
依赖
Python
MicroPython 是基于 Python 的 WOL 适配移植过来的,原代码在 MicroPython 中不是直接可用的。
源代码请参见:LouisJin / WakeOnLan-Python
MicroPython
Gitee 下载: Yogile / micropython-wol 。
除了 boot.py
放在根路径下。其他 .py
文件均放在 /lib
文件夹下。
U_WIFI.py
U_WIFI.py
用于连接 WIFI 。
'''
Author: Yogile
Gitee: https://gitee.com/yogile
Date: 2022-07-17 00:41:25
LastEditors: Yogile
LastEditTime: 2022-07-17 10:03:30
Description:
'''
import network
class WIFI:
WLAN = None
IP = None
SSID = b"[SSID]"
PASSWORD = b"[PASSWORD]"
def connectWiFi():
WIFI.WLAN = None
WIFI.WLAN = network.WLAN(network.STA_IF)
try:
if not WIFI.WLAN.isconnected():
WIFI.WLAN.active(True)
WIFI.WLAN.connect(WIFI.SSID, WIFI.PASSWORD)
if WIFI.WLAN.isconnected():
print('network config:', WIFI.WLAN.ifconfig())
WIFI.IP = WIFI.WLAN.ifconfig()[0]
except:
print('WIFI.WLAN network except')
WIFI.WLAN.IP = None
finally:
print('WIFI.WLAN connectWiFi finish')
使用示例:
import lib as lib
from lib import U_WIFI
def start():
while(True):
if U_WIFI.WIFI.WLAN == None:
print("WIFI Start Connect...")
U_WIFI.connectWiFi()
if U_WIFI.WIFI.WLAN.isconnected():
print("WIFI Connected...")
else:
print("WIFI Not Connect...")
U_WIFI.WIFI.WLAN = None
utime.sleep(5)
start()
U_STRING.py
U_STRING.py
用于实现 WOL 涉及到的 Python 实现了的——但 MicroPython 未实现的,有关方法。包含
replace()
、rindex()
、join()
。
方法 | 参数 | 说明 |
---|---|---|
replace(string, inStr, chgStr) |
string :被操作字符串 |
支持 "xx" ,不支持 b'xx' 或 b"xx" 格式 |
inStr :要被替换的单个字符 |
支持 "x" ,不支持 b'x' 或 b"x" 格式 |
|
chgStr :用于替换的单个字符 |
支持 "x" ,不支持 b'x' 或 b"x" 格式 |
|
rindex(string, indexStr) |
string :被查找字符串 |
支持 "xx" ,不支持 b'xx' 或 b"xx" 格式 |
indexStr :用于查找的目标单个字符 |
支持 "x" ,不支持 b'x' 或 b"x" 格式 |
|
join(string, Dict) |
string :被操作字符串 |
支持 "xx" ,不支持 b'xx' 或 b"xx" 格式 |
Dict :包含字符串的简单的一元字典 |
仅支持 ["asd"(, "asd" * 16, ...)] 格式 |
'''
Author: Yogile
Gitee: https://gitee.com/yogile
Date: 2022-06-28 23:51:30
LastEditors: Yogile
LastEditTime: 2022-07-06 18:33:32
Description:
'''
import struct
class String():
def __init__(self, string):
self.string = string
def replace(string, inStr, chgStr):
tempStr = str()
_chgStr = chgStr
for i in range(0, len(string)):
if str(string[i]) == inStr:
if chgStr == '' or chgStr == "" or chgStr == None:
pass
else:
tempStr = tempStr + _chgStr
else:
tempStr = tempStr + string[i]
return tempStr
def rindex(string, indexStr):
r_index = 0
for i in range(0, len(string)):
if string[i] == indexStr:
if i >= r_index:
r_index = i
return r_index
def join(string, Dict):
for i in range(0, len(Dict)):
string = string + Dict[i]
return string
使用示例:见 U_WOL.py
。
U_WOL.py
U_WIFI
用于获取本地 IP 。
U_STRING
用于实现字符串操作有关方法。
'''
Author: Yogile
Gitee: https://gitee.com/yogile
Date: 2022-06-28 23:51:30
LastEditors: Yogile
LastEditTime: 2022-07-06 18:33:32
Description:
'''
import usocket
import struct
import lib as lib
from lib import U_WIFI
from lib import U_STRING
class WOL():
def __init__(self, IP, MAC_ADDRESS):
self.IP = IP
self.MAC_ADDRESS = MAC_ADDRESS
self.SO_BROADCAST = 32
def do(self):
# 初始化 IP 和 MAC
try:
print('start send magic packet to ', self.MAC_ADDRESS)
host_ip = self.IP
print("host_ip: ", host_ip)
host = (host_ip[: U_STRING.String.rindex(host_ip, '.') + 1] + '255', 9)
print("host: ", host)
mac_address = self.MAC_ADDRESS
mac_address_fmt = U_STRING.String.replace(mac_address, ':', '')
mac_address_fmt = U_STRING.String.replace(mac_address_fmt, '-', '')
print("mac_address_fmt: ", mac_address_fmt)
except:
print('U_WOL Init error, String except...')
finally:
print('U_WOL Init finally')
# 编写 WOL 协议数据
try:
data = U_STRING.String.join('', ['FFFFFFFFFFFF', mac_address_fmt * 16])
send_data = b''
for i in range(0, len(data), 2):
send_data = U_STRING.String.join(b'', [send_data, struct.pack('B', int(data[i: i + 2], 16))])
print("send_data: ", send_data)
except:
print('U_WOL Code error, String except...')
finally:
print('U_WOL Code finally')
# 发送 WOL 魔术包
try:
sock = usocket.socket(usocket.AF_INET, usocket.SOCK_DGRAM, 1)
sock.setsockopt(usocket.SOL_SOCKET, self.SO_BROADCAST, 1)
sock.sendto(send_data, host)
except:
print('U_WOL Socket error, About SO_BROADCAST except...')
finally:
sock.close()
print('U_WOL Socket finally')
使用示例:
import lib as lib
from lib import U_STRING
from lib import U_WIFI
from lib import U_WOL
import utime
def start():
print("U_WIFI.WIFI.WLAN is %s" % U_WIFI.WIFI.WLAN)
while(True):
if U_WIFI.WIFI.WLAN == None:
print("WIFI Start Connect...")
U_WIFI.connectWiFi()
if U_WIFI.WIFI.WLAN.isconnected():
print("WIFI Connected...")
else:
print("WIFI Not Connect...")
U_WIFI.WIFI.WLAN = None
utime.sleep(5)
continue
# 跳过本循环后续代码,进行下一循环,直到 WIFI 连接成功
goalMAC = "xx:xx:xx:xx:xx:xx"
wol = U_WOL.WOL(U_WIFI.WIFI.IP, goalMAC)
wol.do()
start()
适配移植
MicroPython 已实现
根据文档 builtins-内置函数和异常 :得知 class str
已实现。
MicroPython 方法缺失
根据文档 MicroPython 内置类型 :没有实现类似 replace()
的功能。
根据 usocket
-- socket 模块 :得知未定义常量 usocket.SO_BROADCAST
,其值 usocket.SO_BROADCAST = 32
。
其他语言
C 语言
参见:GramThanos / WakeOnLAN
更多:Github 搜索结果