mirror of
https://github.com/kxgx/2.13-Ink-screen-clock.git
synced 2026-03-15 07:03:16 +08:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0d776da36 | ||
|
|
7a76aef402 | ||
|
|
c3666059ce | ||
|
|
dfae4181cb | ||
|
|
0085656d20 | ||
|
|
f8857cbd17 | ||
|
|
90b6ae1403 | ||
|
|
e9b284a9b3 | ||
|
|
7405aabf2c | ||
|
|
ca450afb14 | ||
|
|
c82aadd4e7 | ||
|
|
0a96f265f7 | ||
|
|
298a3f43f1 | ||
|
|
17544b607a |
12
bin/clean.sh
12
bin/clean.sh
@@ -4,8 +4,7 @@ f_name="clean.py"
|
||||
dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
logdir="${dir%/*}/log"
|
||||
service_name="raspi_e-Paper.service"
|
||||
hold_time_seconds=5 # 设置维持时间,例如300秒(5分钟)
|
||||
|
||||
|
||||
# 停止raspi_e-Paper服务
|
||||
echo "正在停止$service_name服务..."
|
||||
sudo systemctl stop "$service_name"
|
||||
@@ -19,9 +18,6 @@ if [ -n "$pids" ]; then
|
||||
kill -9 $pids
|
||||
fi
|
||||
|
||||
# 使用nohup在后台运行Python脚本,并将输出重定向到日志文件
|
||||
nohup /usr/bin/python3 -u "$dir/$f_name" > "${logdir}/info-clean.log" 2>&1 &
|
||||
|
||||
# 等待维持时间
|
||||
echo "正在运行脚本,将在 ${hold_time_seconds} 秒后停止服务..."
|
||||
sleep $hold_time_seconds
|
||||
echo "正在清除屏幕内容"
|
||||
# 运行Python脚本,并将输出重定向到日志文件
|
||||
/usr/bin/python3 -u "$dir/$f_name" > "${logdir}/info-clean.log" 2>&1
|
||||
|
||||
164
bin/main.py
164
bin/main.py
@@ -5,6 +5,7 @@ import os,sys,re,json,time,datetime #引入系统相关库
|
||||
from borax.calendars.lunardate import LunarDate #农历日期以及天干地支纪年法的 Python 库
|
||||
import logging #日志库
|
||||
import subprocess
|
||||
import os
|
||||
from threading import Timer
|
||||
import requests
|
||||
import socket
|
||||
@@ -19,7 +20,7 @@ if os.path.exists(libdir):
|
||||
sys.path.append(libdir)#将引入文件添加到环境变量
|
||||
from waveshare_epd import epd2in13_V4 #引入墨水屏驱动文件
|
||||
logging.debug("Loading Fonts")
|
||||
font01 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 19) #字体文件
|
||||
font01 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 20) #字体文件
|
||||
font02 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 15) #字体文件
|
||||
font03 = ImageFont.truetype(os.path.join(picdir, 'DSEG7Modern-Bold.ttf'), 38) #字体文件
|
||||
font04 = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 10) #字体文件
|
||||
@@ -45,16 +46,21 @@ def Get_ipv4_address(): # 获取当前的IP地址
|
||||
try:
|
||||
# 执行命令获取IP地址,并处理输出以仅返回IPv4地址
|
||||
ip_output = subprocess.check_output("hostname -I | grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}'", shell=True).decode('utf-8').strip()
|
||||
# 检查是否为IPv4地址
|
||||
if ip_output and not ip_output.startswith("127."):
|
||||
return ip_output
|
||||
# 分割输出以获取单个IP地址列表
|
||||
ip_list = ip_output.split()
|
||||
# 过滤掉以172开头的IP地址
|
||||
filtered_ips = [ip for ip in ip_list if not ip.startswith("172.")]
|
||||
# 如果有有效的IP地址,返回第一个,否则返回获取失败
|
||||
if filtered_ips:
|
||||
return filtered_ips[0]
|
||||
else:
|
||||
return "IPv4获取失败"
|
||||
return "地址获取失败"
|
||||
except subprocess.CalledProcessError as e:
|
||||
return f"获取失败"
|
||||
logging.error("获取IPv4地址失败: %s", e)
|
||||
return "获取失败"
|
||||
def CPU_temperature():#CPU温度获取
|
||||
temperatura = os.popen('vcgencmd measure_temp').readline()
|
||||
temperatura = temperatura.replace('temp=','').replace('\'C', '').strip()
|
||||
temperatura = temperatura.replace('temp=','').strip()
|
||||
return str(temperatura)
|
||||
def Memory_footprint():#显示内存占用百分比
|
||||
return(subprocess.check_output(u"free -m | awk -F '[ :]+' 'NR==2{printf \"%d\", ($3)/$2*100}'", shell = True ).decode('gbk'))
|
||||
@@ -103,14 +109,14 @@ def Weather(): #在图片中添加天气内容
|
||||
weather_update = Weather_text['time'] #天气更新时间
|
||||
weather_date = Weather_text['date'] #日期
|
||||
humidity = Weather_text['SD'] #湿度
|
||||
draw.text((175,25),"天气:",font = font06,fill =0)#显示当前天气前缀
|
||||
draw.text((175,45),"温度:",font = font06,fill =0)#显示当前温度前缀
|
||||
draw.text((175,65),"湿度:",font = font06,fill =0)#显示当前湿度前缀
|
||||
draw.text((175,85),"城市:",font = font06,fill =0)#显示当前城市前缀
|
||||
draw.text((205,25),weather,font = font06,fill =0)
|
||||
draw.text((205,45),temperature,font = font06,fill =0)
|
||||
draw.text((205,65),humidity,font = font06,fill =0)
|
||||
draw.text((205,85),Weather_position,font = font06,fill =0)
|
||||
draw.text((150,25),"天气:",font = font06,fill =0)#显示当前天气前缀
|
||||
draw.text((150,45),"温度:",font = font06,fill =0)#显示当前温度前缀
|
||||
draw.text((150,65),"湿度:",font = font06,fill =0)#显示当前湿度前缀
|
||||
draw.text((150,85),"城市:",font = font06,fill =0)#显示当前城市前缀
|
||||
draw.text((191,25),weather,font = font06,fill =0)
|
||||
draw.text((191,45),temperature,font = font06,fill =0)
|
||||
draw.text((191,65),humidity,font = font06,fill =0)
|
||||
draw.text((191,85),Weather_position,font = font06,fill =0)
|
||||
draw.text((211,107),weather_update,font = font05,fill =255) #显示天气更新时间
|
||||
|
||||
def Basic_refresh(): #全刷函数
|
||||
@@ -121,18 +127,6 @@ def Basic_refresh(): #全刷函数
|
||||
global local_time
|
||||
local_time=get_time()
|
||||
draw.text((5,40),local_time,font = font03,fill =0)#显示当前时间
|
||||
global cpu_temp
|
||||
cpu_temp = str(CPU_temperature()) # 调用函数并转换为字符串
|
||||
text_to_display = "CPU温度:" + cpu_temp + "°C"
|
||||
draw.text((4, 19), text_to_display, font=font06, fill=0) # 绘制文本
|
||||
global cpu_use
|
||||
cpu_use = str(CPU_usage()) # 调用函数并转换为字符串
|
||||
text_to_display = "CPU占用:" + cpu_use + "%"
|
||||
draw.text((4, 84), text_to_display, font=font06, fill=0) # 绘制文本
|
||||
global mem_use
|
||||
mem_use = str(Memory_footprint()) # 调用函数并转换为字符串
|
||||
text_to_display = "内存占用:" + mem_use + "%" # 连接字符串
|
||||
draw.text((86, 84), text_to_display, font=font06, fill=0) # 绘制文本
|
||||
Bottom_edge() #添加底边内容
|
||||
Weather() #天气内容
|
||||
epd.display(epd.getbuffer(info_image.rotate(180)))
|
||||
@@ -187,26 +181,26 @@ def Partial_refresh():#局刷函数
|
||||
weather_date1 = Weather_text['date'] #日期
|
||||
humidity1 = Weather_text['SD'] #湿度
|
||||
if (weather11==weather) ==False:
|
||||
draw.rectangle((205, 25, 250, 38), fill = 255) #天气局刷区域
|
||||
draw.text((205,25),weather11,font = font06,fill =0)
|
||||
draw.rectangle((191, 25, 249, 38), fill = 255) #天气局刷区域
|
||||
draw.text((191,25),weather11,font = font06,fill =0)
|
||||
weather=weather11
|
||||
logging.info("天气局部刷新")
|
||||
Local_strong_brush() #局部强刷
|
||||
if (temperature1==temperature) ==False:
|
||||
draw.rectangle((205, 45, 250, 57), fill = 255) #局刷区域
|
||||
draw.text((205,45),temperature1,font = font06,fill =0)
|
||||
draw.rectangle((191, 45, 249, 57), fill = 255) #局刷区域
|
||||
draw.text((191,45),temperature1,font = font06,fill =0)
|
||||
temperature=temperature1
|
||||
logging.info("温度局部刷新")
|
||||
Local_strong_brush() #局部强刷
|
||||
if (humidity1==humidity) ==False:
|
||||
draw.rectangle((205, 65, 250, 77), fill = 255) #局刷区域
|
||||
draw.text((205,65),humidity1,font = font06,fill =0)
|
||||
draw.rectangle((191, 65, 249, 77), fill = 255) #局刷区域
|
||||
draw.text((191,65),humidity1,font = font06,fill =0)
|
||||
humidity = humidity1
|
||||
logging.info("湿度局部刷新")
|
||||
Local_strong_brush() #局部强刷
|
||||
if (Weather_position1==Weather_position) ==False:
|
||||
draw.rectangle((205, 85, 250, 98), fill = 255) #局刷区域
|
||||
draw.text((205,85),Weather_position1,font = font06,fill =0)
|
||||
draw.rectangle((191, 85, 249, 98), fill = 255) #局刷区域
|
||||
draw.text((191,85),Weather_position1,font = font06,fill =0)
|
||||
Weather_position = Weather_position1
|
||||
logging.info("城市局部刷新")
|
||||
Local_strong_brush() #局部强刷
|
||||
@@ -224,77 +218,43 @@ def Partial_refresh():#局刷函数
|
||||
draw.text((129,108),power_battery(),font = font04,fill =255) #显示当前电量百分比
|
||||
power_str=power_str1
|
||||
Local_strong_brush() #局部强刷
|
||||
#logging.info("电源电量局部刷新")
|
||||
'''CPU温度显示'''
|
||||
global cpu_temp
|
||||
cpu_temp1 =CPU_temperature()
|
||||
if (cpu_temp1==cpu_temp) ==False:
|
||||
draw.rectangle((1, 19, 130, 38), fill = 255)
|
||||
cpu_temp = str(CPU_temperature()) # 调用函数并转换为字符串
|
||||
text_to_display = "CPU温度:" + cpu_temp + "°C"
|
||||
draw.text((4, 19), text_to_display, font=font06, fill=0) # 绘制文本
|
||||
cpu_temp1=cpu_temp
|
||||
Local_strong_brush() #局部强刷
|
||||
#logging.info("CPU温度局部刷新")
|
||||
'''CPU温度显示'''
|
||||
'''CPU占用显示'''
|
||||
global cpu_use
|
||||
cpu_use1 =CPU_usage()
|
||||
if (cpu_use1==cpu_use) ==False:
|
||||
draw.rectangle((1, 84, 85, 98), fill = 255)
|
||||
cpu_use = str(CPU_usage()) # 调用函数并转换为字符串
|
||||
text_to_display = "CPU占用:" + cpu_use + "%"
|
||||
draw.text((4, 84), text_to_display, font=font06, fill=0) # 绘制文本
|
||||
cpu_use1=cpu_use
|
||||
Local_strong_brush() #局部强刷
|
||||
#logging.info("CPU温度局部刷新")
|
||||
'''CPU占用显示'''
|
||||
'''内存百分比显示'''
|
||||
global mem_use
|
||||
mem_use1 =Memory_footprint()
|
||||
if (mem_use1==mem_use) ==False:
|
||||
draw.rectangle((86, 84, 170, 98), fill = 255)
|
||||
mem_use = str(Memory_footprint()) # 调用函数并转换为字符串
|
||||
text_to_display = "内存占用:" + mem_use + "%" # 连接字符串
|
||||
draw.text((86, 84), text_to_display, font=font06, fill=0) # 绘制文本
|
||||
mem_use1=mem_use
|
||||
Local_strong_brush() #局部强刷
|
||||
#logging.info("内存百分比局部刷新")
|
||||
'''内存百分比显示'''
|
||||
# logging.info("电源电量局部刷新")
|
||||
try:
|
||||
##################屏幕初始化#########################
|
||||
epd = epd2in13_V4.EPD() #初始化
|
||||
epd.init()#设定屏幕刷新模式
|
||||
#epd.Clear(0xFF) #清除屏幕内容
|
||||
##################屏幕初始化#########################
|
||||
logging.info("Width = %s, Height = %s", format(epd.width), format(epd.height)) #打印屏幕高度及宽度
|
||||
logging.info("初始化并清空显示屏")#屏幕开始准备相关展示
|
||||
info_image = Image.new('1', (epd.height, epd.width), 255) #画布创建准备
|
||||
draw = ImageDraw.Draw(info_image)
|
||||
Basic_refresh() #全局刷新
|
||||
Partial_refresh() #局部刷新
|
||||
epd.init()
|
||||
epd.Clear(0xFF)
|
||||
epd.sleep()
|
||||
except OSError as e:
|
||||
logging.info(e)
|
||||
except KeyboardInterrupt:
|
||||
logging.info("检测到键盘中断,正在清理并退出")
|
||||
epd.init()
|
||||
epd.Clear(0xFF) # 清除屏幕内容
|
||||
epd.sleep() # 使屏幕进入休眠状态
|
||||
epd2in13_V4.epdconfig.module_exit() # 清理资源
|
||||
exit()
|
||||
|
||||
retry_interval = 180 # 设置重试间隔时间(秒)
|
||||
while True:
|
||||
try:
|
||||
##################屏幕初始化#########################
|
||||
epd = epd2in13_V4.EPD() #初始化
|
||||
epd.init()#设定屏幕刷新模式
|
||||
#epd.Clear(0xFF) #清除屏幕内容
|
||||
##################屏幕初始化#########################
|
||||
logging.info("Width = %s, Height = %s", format(epd.width), format(epd.height)) #打印屏幕高度及宽度
|
||||
logging.info("初始化并清空显示屏")#屏幕开始准备相关展示
|
||||
info_image = Image.new('1', (epd.height, epd.width), 255) #画布创建准备
|
||||
draw = ImageDraw.Draw(info_image)
|
||||
Basic_refresh() #全局刷新
|
||||
Partial_refresh() #局部刷新
|
||||
epd.init()
|
||||
epd.Clear(0xFF)
|
||||
epd.sleep()
|
||||
time.sleep(300)
|
||||
break # 如果脚本执行成功,则退出循环
|
||||
except (OSError, Exception) as e: # 捕获你提到的异常
|
||||
logging.error("发生了错误: %s", e)
|
||||
time.sleep(retry_interval) # 等待一段时间后重试
|
||||
except KeyboardInterrupt:
|
||||
logging.info("检测到键盘中断,正在清理并退出")
|
||||
epd.init()
|
||||
epd.Clear(0xFF) # 清除屏幕内容
|
||||
epd.sleep() # 使屏幕进入休眠状态
|
||||
epd2in13_V4.epdconfig.module_exit() # 清理资源
|
||||
exit()
|
||||
except Exception as e:
|
||||
logging.error("发生了意外的错误: %s", e)
|
||||
epd.init()
|
||||
epd.Clear(0xFF) # 清除屏幕内容
|
||||
epd.sleep() # 使屏幕进入休眠状态
|
||||
epd2in13_V4.epdconfig.module_exit() # 清理资源
|
||||
exit()
|
||||
|
||||
# 脚本正常结束后的清理操作
|
||||
epd.init()
|
||||
epd.Clear(0xFF) # 清除屏幕内容
|
||||
epd.sleep() # 使屏幕进入休眠状态
|
||||
epd2in13_V4.epdconfig.module_exit() # 清理资源
|
||||
exit()
|
||||
exit()
|
||||
@@ -4,12 +4,11 @@ After=network.target
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
# 等待网络完全启动
|
||||
ExecStartPre=/bin/bash -c 'until ping -c1 baidu.com &>/dev/null; do sleep 1; done'
|
||||
ExecStart=/root/2.13-Ink-screen-clock/bin/start.sh
|
||||
ExecStop=/usr/bin/screen -S main_screen -X quit
|
||||
Restart=on-failure
|
||||
ExecStop=/bin/bash -c "pkill -f /root/2.13-Ink-screen-clock/bin/main.py; pkill -f /root/2.13-Ink-screen-clock/bin/weather.py"
|
||||
WorkingDirectory=/root/2.13-Ink-screen-clock/bin
|
||||
Restart=always
|
||||
User=root
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
WantedBy=multi-user.target
|
||||
@@ -60,10 +60,15 @@ def get_current_city():
|
||||
time.sleep(180) # 重试前等待
|
||||
# 注意:无限重试可能会在特定情况下导致程序无法终止,请确保在实际使用中考虑适当的退出条件或限制重试次数。
|
||||
|
||||
def schedule_getWeath():
|
||||
"""调度 getWeath 函数每3分钟执行一次"""
|
||||
getWeath()
|
||||
Timer(180, schedule_getWeath).start() # 重新设置定时器
|
||||
|
||||
def getWeath(city='101060101'):
|
||||
headers = {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
|
||||
'Referer': 'http://www.weather.com.cn/'
|
||||
'Referer': 'https://www.weather.com.cn/'
|
||||
}
|
||||
current_city = get_current_city()
|
||||
if current_city:
|
||||
@@ -71,14 +76,13 @@ def getWeath(city='101060101'):
|
||||
if area_id:
|
||||
city = area_id
|
||||
try:
|
||||
response = requests.get('http://d1.weather.com.cn/sk_2d/'+city+'.html',headers=headers)
|
||||
response = requests.get('https://d1.weather.com.cn/sk_2d/'+city+'.html',headers=headers)
|
||||
response.raise_for_status() # 检查请求是否成功
|
||||
response.encoding = 'utf-8'
|
||||
Weath = response.text[11:]
|
||||
fileHandle = open('/root/2.13-Ink-screen-clock/bin/weather.json', 'w')
|
||||
fileHandle.write(str(Weath))
|
||||
fileHandle.close()
|
||||
Timer(180, getWeath).start() # 定时器函数,间隔三分钟下载文件至本地
|
||||
print("天气文件更新")
|
||||
except requests.RequestException as e:
|
||||
logging.error("获取天气数据时出现网络错误: %s", e)
|
||||
@@ -86,7 +90,7 @@ def getWeath(city='101060101'):
|
||||
logging.error("发生了意外错误: %s", e)
|
||||
|
||||
try:
|
||||
getWeath() # 天气获取函数开始运行
|
||||
schedule_getWeath() # 开始调度天气获取函数
|
||||
except OSError as e:
|
||||
logging.info(e)
|
||||
except KeyboardInterrupt:
|
||||
|
||||
Reference in New Issue
Block a user