找回密码
 立即注册

QQ登录

只需一步,快速开始

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

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



148.jpg

树莓派实验室之前已经介绍了多种方法,来获得树莓派的 IP 地址。有的利用局域网工具或登录路由器查询、有的通过OLED小屏幕自动显示、还有的使用 Python 将树莓派的 IP 发到邮箱的。
下面我们再来多介绍一种,使用 Python 脚本配合 Android 手机通过 UDP 方式,让手机获取树莓派的 IP 地址。并且允许手机端远程对树莓派进行重启、关机等操作。
本文提供了全部的代码文件,有兴趣的朋友可以测试、完善。
每次要 SSH 到树莓派都很麻烦,我是没找什么办法,每次都得连上显示器鼠标键盘。才能知道IP地址。看了点 Python,写了个脚本来发出 IP 地址,这样就省事多了。
发现启动时有可能早于树莓派网络初始化,会导致 UDP 服务初始化出现问题。脚本里面延时 30 秒执行。在树莓派4测试通过。

创建 Python 脚本

创建的代码文件名FindIPUDPServer.py,保存在 /home/pi 目录下或者其他你指定的位置。

  1. import socket
  2. import uuid
  3. import time
  4. import os
  5. import time
  6. import logging
  7. from logging import handlers
  8. # 获取MAC地址
  9. def get_mac_address():
  10.     mac = uuid.UUID(int=uuid.getnode()).hex[-12:]
  11.     return ":".join([mac[e:e + 2] for e in range(0, 11, 2)])
  12. # 获取IP地址
  13. def get_host_ip():
  14.     try:
  15.         my = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  16.         my.connect(('8.8.8.8', 80))
  17.         # ip = my.getsockname()[0]
  18.         ipList = my.getsockname()
  19.     finally:
  20.         my.close()
  21.     return ipList
  22. def _logging(**kwargs):
  23.     level = kwargs.pop('level', None)
  24.     filename = kwargs.pop('filename', None)
  25.     datefmt = kwargs.pop('datefmt', None)
  26.     format = kwargs.pop('format', None)
  27.     if level is None:
  28.         level = logging.DEBUG
  29.     if filename is None:
  30.         filename = 'default.log'
  31.     if datefmt is None:
  32.         datefmt = '%Y-%m-%d %H:%M:%S'
  33.     if format is None:
  34.         format = '%(asctime)s [%(module)s] %(levelname)s [%(lineno)d] %(message)s'
  35.     log = logging.getLogger(filename)
  36.     format_str = logging.Formatter(format, datefmt)
  37.     # backupCount 保存日志的数量,过期自动删除
  38.     # when 按什么日期格式切分(这里方便测试使用的秒)
  39.     th = handlers.TimedRotatingFileHandler(filename=filename, when='H', backupCount=3, encoding='utf-8')
  40.     th.setFormatter(format_str)
  41.     th.setLevel(logging.DEBUG)
  42.     ch = logging.StreamHandler()
  43.     ch.setLevel(logging.DEBUG)
  44.     #  ch.setFormatter(format)
  45.     log.addHandler(ch)
  46.     log.addHandler(th)
  47.     log.setLevel(level)
  48.     return log
  49. os.makedirs("logs", exist_ok=True)
  50. mylog = _logging(filename='logs/udpserver.log')
  51. print("等待30秒")
  52. mylog.debug("等待30秒")
  53. time.sleep(30)
  54. print("等待结束")
  55. mylog.debug("等待结束")
  56. HOST = ''
  57. PORT = 9999
  58. BUFSIZ = 1024
  59. ADDRESS = (HOST, PORT)
  60. udpServerSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  61. udpServerSocket.bind(ADDRESS)  # 绑定客户端口和地址
  62. myname = socket.gethostname()
  63. print("myname:" + myname)
  64. mylog.debug("myname:" + myname)
  65. myIPList = get_host_ip()
  66. print("myIPList:" + str(myIPList))
  67. mylog.debug("myIPList:" + str(myIPList))
  68. macAddress = get_mac_address()
  69. print("macAddress:" + macAddress)
  70. mylog.debug("macAddress:" + macAddress)
  71. while True:
  72.     print("waiting for message...")
  73.     mylog.debug("waiting for message...")
  74.     data, addr = udpServerSocket.recvfrom(BUFSIZ)
  75.     currCode = data.decode('utf-8')
  76.     print("接收到数据:" +currCode)
  77.     mylog.debug("接收到数据:"+currCode)
  78.     # content = '[%s] %s' % (bytes(ctime(), 'utf-8'), data.decode('utf-8'))
  79.     # 发送服务器时间
  80.     if currCode == "TIME":
  81.         content = "Time:" + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
  82.         udpServerSocket.sendto(content.encode('utf-8'), addr)
  83.     # 发送IP地址
  84.     elif currCode == "IP":
  85.         content = "IP:" + str(myIPList)
  86.         udpServerSocket.sendto(content.encode('utf-8'), addr)
  87.     # 发送mac地址
  88.     elif currCode == "MAC":
  89.         content = "MAC:" + macAddress
  90.         udpServerSocket.sendto(content.encode('utf-8'), addr)
  91.     # 发送ip mac地址
  92.     elif currCode == "IP_MAC":
  93.         content = "IP:" + str(myIPList) + "|MAC:" + macAddress
  94.         udpServerSocket.sendto(content.encode('utf-8'), addr)
  95.     # 退出UDP服务端
  96.     elif currCode == "EXIT":
  97.         content = "服务端退出"
  98.         udpServerSocket.sendto(content.encode('utf-8'), addr)
  99.         # print(content)
  100.         break
  101.     # 重启
  102.     elif currCode == "REBOOT":
  103.         content = "服务端重启"
  104.         udpServerSocket.sendto(content.encode('utf-8'), addr)
  105.         print("服务端开始重启")
  106.         mylog.debug("服务端开始重启")
  107.         os.system('shutdown -r now')
  108.         break
  109.     # 关机
  110.     elif currCode == "SHUTDOWN":
  111.         content = "服务端关机"
  112.         udpServerSocket.sendto(content.encode('utf-8'), addr)
  113.         print("服务端开始关机")
  114.         mylog.debug("服务端开始关机")
  115.         os.system('sudo shutdown -h now')
  116.         break
  117.     else:
  118.         udpServerSocket.sendto("Bad Key".encode('utf-8'), addr)
  119.     # content = '[%s] %s %s' % (bytes(ctime(), 'utf-8'), str(myIPList), macAddress)
  120.     # udpServerSocket.sendto(content.encode('utf-8'), addr)
  121.     print('...received from and returned to:', addr)
  122.     mylog.debug('...received from and returned to:', addr)
  123. udpServerSocket.close()
  124. print("服务端退出")
  125. mylog.debug('服务端退出')
复制代码

配置树莓派

SSH 登录树莓派运行下面的命令配置开机启动项:

  1. sudo nano /etc/rc/local
复制代码

如图:

149.png

注意修改其中脚本文件的路径为脚本实际存放的路径。

重启树莓派

这个时候怎么看我们的程序是否自启动了呢。登录树莓派执行  sudo systemctlstatus rc-local 看看 FindIPUDPServer 是否已经起来了。

Android 客户端和源码

150.png

树莓派Python 脚本配置好以后重启。打开 APP 就能搜到树莓派的IP地址
搜索按钮:点击后等待返回结果。搜索到IP地址后,输入到文本框内。
重启、关机、关闭服务,功能就能用啦。
关闭服务功能可以关闭树莓派的搜索服务。点搜索树莓派就不会发送IP地址了。除非重启树莓派。
APK文件及源代码链接: https://pan.baidu.com/s/1gKl-XEqDfZA3fky7rGljwA 提取码: mxdn
分享至 : QQ空间
收藏

0 个回复

您需要登录后才可以回帖 登录 | 立即注册