0.前言
最近给树莓派安装了kali系统,想在闲余时间在树莓派上跑些脚本。ssh实时查看太麻烦,想到手头有OLED(SSD1306) 和几个RGB灯,便想着给树莓派做个实时显示系统,可以直观的查看到树莓派运行的状态。说干就干。
0.1设计目标
- 开机自启动
- OLED实时显示树莓派运行信息
- IP地址
- CPU使用率
- 内存大小与使用率
- 硬盘大小与使用率
- RGB灯根据CPU的使用率变换颜色,由低到高为 绿->蓝->黄->红
0.2 准备材料
- 安装好系统的树莓派3B+(我安装的是kali系统)
- RGB等一个
- SSD1306 128*32 OLED显示屏
- 杜邦线若干
- 热熔胶(真是个好东西),支架材料若干
0.3 前期准备
-
树莓派安装kali系统 不懂看这里
-
kali系统打开i2c功能 不懂看这里
-
python相关库安装 (pip 安装不成功 建议直接下载安装 python setup.py)
库名 作用 下载地址 RPi.GPIO 树莓派的GPIO库 控制RGB灯 https://sourceforge.net/projects/raspberry-gpio-python/files/latest/download Adafruit-SSD1306 ssd1306的使用库 https://github.com/adafruit/Adafruit_Python_SSD1306.git psutil python 的性能查看工具
0.4 相关资料
GPIO接口图
1. OLED显示信息
1.1连接图
1.2 编写OLED显示类
在github的example https://github.com/adafruit/Adafruit_Python_SSD1306/tree/master/examples 里看到许多例子,其中的state.py与我设想的最类似。于是修改封装成OLED显示类 ssd1306show.py
#! /usr/bin/python
# -*- coding:utf-8 -*-
import Adafruit_GPIO.SPI as SPI
import Adafruit_SSD1306
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
class ssd1306():
''' ssd1306'''
def __init__(self,padding=-2):
RST = None # pin isnt used
# init disp
self.disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST)
self.disp.begin() #init lib
# clear display
self.disp.clear()
self.disp.display()
# creat image with mode '1' for 1-bit color and draw object
self.image=Image.new('1',(self.disp.width,self.disp.height))
self.draw = ImageDraw.Draw(self.image)
# top bottom
self.top,self.bottom=padding,self.disp.height-padding
# load font
self.font=ImageFont.load_default()
def clear_image(self):
''' fill black box to clear'''
self.draw.rectangle((0,0,self.disp.width,self.disp.height), outline=0, fill=0)
def show_info(self,IP,cpu,mem,disk):
''' draw info '''
self.draw.text((0,self.top),"IP:"+str(IP),font=self.font,fill=255)
self.draw.text((0,self.top+8),"CPU load:"+str(cpu),font=self.font,fill=255)
self.draw.text((0,self.top+16),"Mem:"+str(mem),font=self.font,fill=255)
self.draw.text((0,self.top+25),"Disk:"+str(disk),font=self.font,fill=255)
self.disp.image(self.image)
self.disp.display()
if __name__ == "__main__":
test=ssd1306()
test.show_info("x","x","x","x")
1.3 测试
使用python 启动 可以看到OLED屏幕显示,测试成功
python ssd1306show.py
2.RGB灯显示状态
2.1 连接图
2.1编写RGB 显示类
mport RPi.GPIO as GPIO
class rgbState(Object):
''' 显示状态的rgb灯 '''
#简单的颜色映射
color_map={
'red': (True,False,False),
'green':(False,True,False),
'blue': (False,False,True),
'white':(True,True,True),
'yellow':(True,True,False),
}
def __init__(self,R=27,G=28,B=29):
# set mode
GPIO.setmode(GPIO.BCM) # 注意GPIO的编码方式
# set out
GPIO.setup(R, GPIO.OUT)
GPIO.setup(G, GPIO.OUT)
GPIO.setup(B, GPIO.OUT)
# save rgb
self.RGB=(R,G,B)
def color_display(self,color):
''' 根据颜色进行显示 '''
rgb=color_map.get(color,(False,False,False))
for i in range(3):
GPIO.output(self.RGB[i],rgb[i])
if __name__=="__main__":
test=rgbState()
import time
test.color_display('red')
time.sleep(2)
test.color_display('green')
time.sleep(2)
test.color_display('blue')
time.sleep(2)
test.color_display('yellow')
time.sleep(2)
test.color_display('white')
注意事项:
注意GPIO的编码方式,分为BCM和Board两种 不同编码不同,我就在这里摔了一个坑。
2.3 测试
python 启动文件 可以看到RGB 颜色变化 测试成功
3. 状态监控
状态监控使用了cmd命令与psutil相结合的方法。对于IP来说,变数不大,获取一次就行。其他的数据每隔一段时间获取。
psutil资料:https://www.liaoxuefeng.com/wiki/1016959663602400/1183565811281984
综合显示模块,写出综合模块 stateMonitor.py
#! /usr/bin/python
# -*- coding:utf-8 -*-
import psutil
import subprocess
import time
import ssd1306show,rgbStateshow
class stateMonitor():
def __init__(self,interval=20):
# other unit
self.ssd1306=ssd1306show.ssd1306()
self.rgbstate=rgbStateshow.rgbState()
self.interval=interval if interval>1 else 2
def begin_monitor(self):
while True:
cmd = "hostname -I | cut -d\' \' -f1"
IP = subprocess.check_output(cmd, shell = True )
cpu=psutil.cpu_percent(interval=1)
mem=psutil.virtual_memory()
mem_str="{}/{}M {}%".format(
round(mem.used/(1024*1024),2),
round(mem.total/(1024*1024),2),
mem.percent)
disk=psutil.disk_usage("/")
disk_str="{}/{}G {}%".format(
round(disk.used/(1024*1024*1024),2),
round(disk.total/(1024*1024*1024),2),
disk.percent)
self.ssd1306.clear_image() # clear
self.ssd1306.show_info(IP,cpu,mem_str,disk_str)
if cpu >90:
self.rgbstate.color_display('red')
elif cpu >50:
self.rgbstate.color_display('yellow')
elif cpu >10:
self.rgbstate.color_display('blue')
else:
self.rgbstate.color_display('green')
time.sleep(self.interval)
if __name__ == "__main__":
stateMonitor=stateMonitor()
stateMonitor.begin_monitor()
经过测试可以实现,效果还不错,哈哈哈。
4.终极:设置开机启动
查阅了资料,设置开机启动的方法有三种:
- /etc/init.d/
- /etc/profile.d/
- crontab定时脚本
经过本人测试,还是第3个有效,所以选择第三个。
4.1 编写bash 允许脚本
python xxxx/xxx/stateMonitor.py&
- 路径使用绝对路径
- & 让python脚本后台允许
保存为run.sh
4.2 修改crontab任务
1. 打开定时任务
crontab -e # 编辑
2. 添加定时任务
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
@reboot xxx/xxx/run.sh #添加此条 路径为绝对路径
4.3 开机重启即可
最终效果图
上一个最终效果图,用支架搭了一个手臂架,这样就可以随时调整方向,哈哈哈。