micropython - espnow

espnow这个东西可以很简单的进行多设备近距离互联,连握手都不用注册一下就能发信息
目前8266那个8角的刷20231105的1M的固件可以运行
8266目前没有信号强度功能所以我自己写的类强度返回为0
我写的类实例化后最后注册谁发消息就是给谁而接收端则是什么都接,只不过接的时候是带着发送设备MAC的
所以具体接收业务逻辑要主程序中再写。

import network
import espnow,time
import json,binascii
class esp_now_rs(object):
    def __init__(self):
        self.sta=network.WLAN(network.STA_IF)
        self.sta.active(True)
        self.sta.disconnect()
        self.e=espnow.ESPNow()
        self.e.active(True)
        self.host_mac=self.sta.config('mac')
    def send_msg (self,data): #发送消息,这里只会发给实例化以后注册的最后一个设备地址
        self.e.send(self.peer, data)
    def send_dict_msg(self,key,value):
        data=self.bytes_dictjson_bytes(key,value)
        self.e.send(self.peer, data)
        return data
    def recv_dict_msg (self): #接收数据啥都接收,具体业务要二次开发
        if self.e.any()>0:
            host_adr, recv_msg = self.e.recv()
            try:
                host_adr,recv_msg=self.bytes_dictjson_dict(recv_msg)
            except:
                pass
            try:
                for peer, info in self.e.peers_table.items():
                    mac_address = ':'.join('{:02x}'.format(b) for b in peer)
                    rssi = info[0]
                    time_ms = info[1]
                    #print(f"MAC: {mac_address}, RSSI: {rssi} dBm, Time: {time_ms} ms")
                    #print(rssi)
                return host_adr,recv_msg,rssi
            except: #8266没有检测信号的功能,所以这里如果出错那就是8266设备为了兼容写个出错例外
                return host_adr,recv_msg,0

    def add_peer(self,addr): #注册设备,最后一个是有效的
        self.peer = addr
        self.e.add_peer(addr) 
    def hex_to_bytes(self,b_data):#因为字节码传输JSON封装有出错可能所以可以字节化一下,只是备用放这里
        hex_key=binascii.hexlify(b_data).decode('ascii')
        return hex_key
    def bytes_to_hex(self,b_data):
        b_hex=binascii.unhexlify(b_data)
        return b_hex
    def bytes_dictjson_bytes(self,key,value):#这个是将字典里边建和值包装成一个字典字节化发出去
        key=self.hex_to_bytes(key)
        value=self.hex_to_bytes(value)
        b_data=json.dumps({key:value}).encode('utf-8')
        return  b_data
    def bytes_dictjson_dict(self,b_data):#解码恢复成字典键值
        b_dict=json.loads(b_data.decode('utf-8'))
        key= binascii.unhexlify(list(b_dict.keys())[0])
        value=binascii.unhexlify(b_dict[list(b_dict.keys())[0]])
        return key,value
    def recv_msg (self): #接收数据啥都接收,具体业务要二次开发
        if self.e.any()>0:
            host_adr, recv_msg = self.e.recv()
            try:
                for peer, info in self.e.peers_table.items():
                    mac_address = ':'.join('{:02x}'.format(b) for b in peer)
                    rssi = info[0]
                    time_ms = info[1]
                    #print(f"MAC: {mac_address}, RSSI: {rssi} dBm, Time: {time_ms} ms")
                    #print(rssi)
                return host_adr,recv_msg,rssi
            except: #8266没有检测信号的功能,所以这里如果出错那就是8266设备为了兼容写个出错例外
                return host_adr,recv_msg,0
if __name__=='__main__':
    aa=esp_now_rs()
    aa.add_peer(b'\xe0Z\x1bu\xed\x0c')#注册要去连接通信的设备MAC
    #####################################################
    xxx=aa.recv_msg()  #收
    aa.send_msg('nihao') #发
    ##如果是8266设备则使用下面这个以字典的方式传递设备MAC#####
    aa.send_dict_msg(aa.host_mac,'nihao')  #发
    xxx=aa.recv_dict_msg()                 #收
    #####################################################
    print(aa.host_mac) #看本机MAC
    adddd=0
    while 1:
        adddd+=1
        xxx=aa.recv_dict_msg()
        if xxx :
            print(xxx)
        time.sleep(0.5)
        aa.send_msg(b'%d'%adddd)

补充更新:这个类使用时是在ESP32下开发的,后续测试了8266发现类输出的地址与实际地址不一致,例如:b’Z\xbf%\xdcl\xea’与b’X\xbf%\xdcl\xea’这样的差别只在第一个字符不同,经调查是8266的地址会根据不同的WIFI模式进行变化,为了保证使用可靠,用两块8266通信测试,最终确定绑定地址为:

print(aa.host_mac) #看本机MAC

并用类中字典方法传送8266的MAC地址则可以正常可靠通信

你可能感兴趣的:(python,开发语言)