lou 发表于 2020-4-29 16:23:47

Python + Android APP 方式获取树莓派的 IP

本帖最后由 lou 于 2020-4-29 16:27 编辑

Python + Android APP 方式获取树莓派的 IP



树莓派实验室之前已经介绍了多种方法,来获得树莓派的 IP 地址。有的利用局域网工具或登录路由器查询、有的通过OLED小屏幕自动显示、还有的使用 Python 将树莓派的 IP 发到邮箱的。下面我们再来多介绍一种,使用 Python 脚本配合 Android 手机通过 UDP 方式,让手机获取树莓派的 IP 地址。并且允许手机端远程对树莓派进行重启、关机等操作。本文提供了全部的代码文件,有兴趣的朋友可以测试、完善。每次要 SSH 到树莓派都很麻烦,我是没找什么办法,每次都得连上显示器鼠标键盘。才能知道IP地址。看了点 Python,写了个脚本来发出 IP 地址,这样就省事多了。发现启动时有可能早于树莓派网络初始化,会导致 UDP 服务初始化出现问题。脚本里面延时 30 秒执行。在树莓派4测试通过。
创建 Python 脚本
创建的代码文件名FindIPUDPServer.py,保存在 /home/pi 目录下或者其他你指定的位置。
import socket
import uuid
import time
import os
import time
import logging
from logging import handlers
# 获取MAC地址
def get_mac_address():
    mac = uuid.UUID(int=uuid.getnode()).hex[-12:]
    return ":".join( for e in range(0, 11, 2)])
# 获取IP地址
def get_host_ip():
    try:
      my = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
      my.connect(('8.8.8.8', 80))
      # ip = my.getsockname()
      ipList = my.getsockname()
    finally:
      my.close()
    return ipList
def _logging(**kwargs):
    level = kwargs.pop('level', None)
    filename = kwargs.pop('filename', None)
    datefmt = kwargs.pop('datefmt', None)
    format = kwargs.pop('format', None)
    if level is None:
      level = logging.DEBUG
    if filename is None:
      filename = 'default.log'
    if datefmt is None:
      datefmt = '%Y-%m-%d %H:%M:%S'
    if format is None:
      format = '%(asctime)s [%(module)s] %(levelname)s [%(lineno)d] %(message)s'
    log = logging.getLogger(filename)
    format_str = logging.Formatter(format, datefmt)
    # backupCount 保存日志的数量,过期自动删除
    # when 按什么日期格式切分(这里方便测试使用的秒)
    th = handlers.TimedRotatingFileHandler(filename=filename, when='H', backupCount=3, encoding='utf-8')
    th.setFormatter(format_str)
    th.setLevel(logging.DEBUG)
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    #ch.setFormatter(format)
    log.addHandler(ch)
    log.addHandler(th)
    log.setLevel(level)
    return log
os.makedirs("logs", exist_ok=True)
mylog = _logging(filename='logs/udpserver.log')
print("等待30秒")
mylog.debug("等待30秒")
time.sleep(30)
print("等待结束")
mylog.debug("等待结束")
HOST = ''
PORT = 9999
BUFSIZ = 1024
ADDRESS = (HOST, PORT)
udpServerSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udpServerSocket.bind(ADDRESS)# 绑定客户端口和地址
myname = socket.gethostname()
print("myname:" + myname)
mylog.debug("myname:" + myname)
myIPList = get_host_ip()
print("myIPList:" + str(myIPList))
mylog.debug("myIPList:" + str(myIPList))
macAddress = get_mac_address()
print("macAddress:" + macAddress)
mylog.debug("macAddress:" + macAddress)
while True:
    print("waiting for message...")
    mylog.debug("waiting for message...")
    data, addr = udpServerSocket.recvfrom(BUFSIZ)
    currCode = data.decode('utf-8')
    print("接收到数据:" +currCode)
    mylog.debug("接收到数据:"+currCode)
    # content = '[%s] %s' % (bytes(ctime(), 'utf-8'), data.decode('utf-8'))
    # 发送服务器时间
    if currCode == "TIME":
      content = "Time:" + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
      udpServerSocket.sendto(content.encode('utf-8'), addr)
    # 发送IP地址
    elif currCode == "IP":
      content = "IP:" + str(myIPList)
      udpServerSocket.sendto(content.encode('utf-8'), addr)
    # 发送mac地址
    elif currCode == "MAC":
      content = "MAC:" + macAddress
      udpServerSocket.sendto(content.encode('utf-8'), addr)
    # 发送ip mac地址
    elif currCode == "IP_MAC":
      content = "IP:" + str(myIPList) + "|MAC:" + macAddress
      udpServerSocket.sendto(content.encode('utf-8'), addr)
    # 退出UDP服务端
    elif currCode == "EXIT":
      content = "服务端退出"
      udpServerSocket.sendto(content.encode('utf-8'), addr)
      # print(content)
      break
    # 重启
    elif currCode == "REBOOT":
      content = "服务端重启"
      udpServerSocket.sendto(content.encode('utf-8'), addr)
      print("服务端开始重启")
      mylog.debug("服务端开始重启")
      os.system('shutdown -r now')
      break
    # 关机
    elif currCode == "SHUTDOWN":
      content = "服务端关机"
      udpServerSocket.sendto(content.encode('utf-8'), addr)
      print("服务端开始关机")
      mylog.debug("服务端开始关机")
      os.system('sudo shutdown -h now')
      break
    else:
      udpServerSocket.sendto("Bad Key".encode('utf-8'), addr)
    # content = '[%s] %s %s' % (bytes(ctime(), 'utf-8'), str(myIPList), macAddress)
    # udpServerSocket.sendto(content.encode('utf-8'), addr)
    print('...received from and returned to:', addr)
    mylog.debug('...received from and returned to:', addr)
udpServerSocket.close()
print("服务端退出")
mylog.debug('服务端退出')

配置树莓派
SSH 登录树莓派运行下面的命令配置开机启动项:
sudo nano /etc/rc/local
如图:

注意修改其中脚本文件的路径为脚本实际存放的路径。
重启树莓派
这个时候怎么看我们的程序是否自启动了呢。登录树莓派执行sudo systemctlstatus rc-local 看看 FindIPUDPServer 是否已经起来了。
Android 客户端和源码

树莓派Python 脚本配置好以后重启。打开 APP 就能搜到树莓派的IP地址 搜索按钮:点击后等待返回结果。搜索到IP地址后,输入到文本框内。重启、关机、关闭服务,功能就能用啦。关闭服务功能可以关闭树莓派的搜索服务。点搜索树莓派就不会发送IP地址了。除非重启树莓派。 APK文件及源代码链接: https://pan.baidu.com/s/1gKl-XEqDfZA3fky7rGljwA 提取码: mxdn
页: [1]
查看完整版本: Python + Android APP 方式获取树莓派的 IP