WIP: Package waveshare CM4-NAS-Double-Deck demo app #49

Closed
lee.miller wants to merge 5 commits from lee.miller/openwrt:packages into main
13 changed files with 1176 additions and 1 deletions
Showing only changes of commit 9bad036498 - Show all commits

View File

@ -47,6 +47,7 @@ make package/ansible-core/compile
make package/asterisk-chan-quectel/compile
make package/collectd/compile
make package/python3-packages/compile
make package/waveshare-demo/compile
sdkdir=$(pwd)
cd ${pwd}
@ -153,7 +154,7 @@ make image PROFILE=${PROFILE} EXTRA_IMAGE_NAME="waveshare" \
${PACKAGES} cryptsetup kmod-ata-ahci smartmontools hdparm fdisk parted \
kmod-hwmon-drivetemp btrfs-progs kmod-fs-btrfs kmod-nvme nvme-cli \
docker dockerd docker-compose block-mount \
python3-packages python3-spidev" \
python3-packages python3-spidev python3-waveshare-demo" \
DISABLED_SERVICES="dropbear" FILES="files" || exit 1

View File

@ -0,0 +1,32 @@
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=waveshare-demo
PKG_VERSION:=0.0.2
PKG_RELEASE:=1
PKG_MAINTAINER:=Lee Miller <lee.miller@tutanota.com>
PKG_LICENSE:=BSD
include $(INCLUDE_DIR)/package.mk
include $(TOPDIR)/feeds/packages/lang/python/python3-package.mk
define Package/python3-$(PKG_NAME)
SECTION:=lang
CATEGORY:=Languages
SUBMENU:=Python
TITLE:=CM4-NAS-Double-Deck Demo
URL:=https://www.waveshare.com/wiki/CM4-NAS-Double-Deck
DEPENDS:=+python3 +python3-setuptools +python3-numpy +python3-pillow \
+python3-spidev +lsblk +procps-ng
endef
define Package/python3-$(PKG_NAME)/description
CM4-NAS-Double-Deck Demo
endef
$(eval $(call Py3Package,python3-$(PKG_NAME)))
$(eval $(call BuildPackage,python3-$(PKG_NAME)))

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -0,0 +1,15 @@
from setuptools import setup
setup(
name='waveshare',
version='0.0.2',
description='CM4-NAS-Double-Deck Demo packaged',
url='https://www.waveshare.com/wiki/CM4-NAS-Double-Deck',
install_requires=['spidev', 'RPi.GPIO', 'numpy'],
packages=['waveshare', 'waveshare.lib'],
package_data={
'waveshare': ['Font/*.ttf', 'pic/*.jpg']},
entry_points={'console_scripts': ['waveshare-demo = waveshare.main']}
)

View File

@ -0,0 +1,572 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import time
import logging
import math
import re
import threading
from PIL import Image, ImageDraw, ImageFont
import RPi.GPIO as GPIO
from .lib import LCD_2inch
from .lib import Gain_Param
logging.basicConfig(level=logging.DEBUG)
app_dir = os.path.dirname(os.path.realpath(__file__))
class image():
flgh = True
def __init__(self):
# display with hardware SPI:
''' Warning!!!Don't creation of multiple displayer objects!!! '''
self.gain = Gain_Param.Gain_Param()
GPIO.setmode(GPIO.BCM)
GPIO.setup(20, GPIO.IN)
GPIO.setup(20, GPIO.IN, pull_up_down=GPIO.PUD_UP)
t1 = threading.Thread(target=self.gain.Hard_data, name="thread1")
t2 = threading.Thread(target=self.key, name="thread2")
t1.daemon = True
t2.daemon = True
t1.start()
t2.start()
self.disp = LCD_2inch.LCD_2inch()
# Initialize library.
self.disp.Init()
# Clear display.
self.disp.clear()
# Create blank image for drawing.
self.image1 = Image.new(
"RGB", (self.disp.height, self.disp.width), "WHITE")
self.draw = ImageDraw.Draw(self.image1)
def key(self):
count = 0
while True:
if GPIO.input(20) == 0:
count = count + 1
else:
if count > 5:
self.flgh = not self.flgh
count = 0
def HMI1(self):
try:
self.image = Image.open(os.path.join(app_dir, "pic", "BL.jpg"))
self.draw = ImageDraw.Draw(self.image)
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 28)
self.draw.text((90, 2), 'Device Status', fill=0xf7ba47, font=Font1)
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 15)
self.draw.text((267, 141), 'TEMP', fill=0xf7ba47, font=Font1)
self.draw.text((190, 141), 'RAM', fill=0xf7ba47, font=Font1)
self.draw.text((267, 141), 'TEMP', fill=0xf7ba47, font=Font1)
self.draw.text((30, 141), 'CPU', fill=0xf7ba47, font=Font1)
self.draw.text((107, 141), 'Disk', fill=0xf7ba47, font=Font1)
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 10)
self.draw.text(
(205, 170), 'R X', fill=0xffffff, font=Font1, stroke_width=1)
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 10)
self.draw.text(
(270, 170), 'T X', fill=0xffffff, font=Font1, stroke_width=1)
# TIME 时间
time_t = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 15)
self.draw.text((5, 50), time_t, fill=0xf7ba47, font=Font1)
# IP
ip = self.gain.GET_IP()
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 15)
self.draw.text((170, 50), 'IP : ' + ip, fill=0xf7ba47, font=Font1)
# CPU usage CPU使用率
self.CPU_usage = os.popen(
'top -bi -n 2 -d 0.02'
).read().split('\n\n\n')[0].split('\n')[2]
self.CPU_usage = re.sub('[a-zA-z%(): ]', '', self.CPU_usage)
self.CPU_usage = self.CPU_usage.split(',')
self.CPU_usagex = 100 - eval(self.CPU_usage[3])
if self.CPU_usagex >= 100:
self.draw.text(
(27, 100), str(math.floor(self.CPU_usagex)) + '%',
fill=0xf1b400, font=Font1)
elif self.CPU_usagex >= 10:
self.draw.text(
(30, 100), str(math.floor(self.CPU_usagex)) + '%',
fill=0xf1b400, font=Font1)
else:
self.draw.text(
(34, 100), str(math.floor(self.CPU_usagex)) + '%',
fill=0xf1b400, font=Font1)
self.draw.arc((10, 80, 70, 142), 0, 360, fill=0xffffff, width=8)
self.draw.arc(
(10, 80, 70, 142), -90, -90 + self.CPU_usagex * 360 / 100,
fill=0x60ad4c, width=8)
# System disk usage 系统磁盘使用率
x = os.popen('df -h /')
i2 = 0
while 1:
i2 = i2 + 1
line = x.readline()
if i2 == 2:
# Memory usage (%) 使用内存(百分值)
self.Capacity_usage = line.split()[4]
self.Hard_capacity = int(
re.sub('[%]', '', self.Capacity_usage))
break
if self.Hard_capacity >= 100:
self.draw.text(
(107, 100), str(math.floor(self.Hard_capacity)) + '%',
fill=0xf1b400, font=Font1)
elif self.Hard_capacity >= 10:
self.draw.text(
(111, 100), str(math.floor(self.Hard_capacity)) + '%',
fill=0xf1b400, font=Font1)
else:
self.draw.text(
(114, 100), str(math.floor(self.Hard_capacity)) + '%',
fill=0xf1b400, font=Font1)
self.draw.arc((90, 80, 150, 142), 0, 360, fill=0xffffff, width=8)
self.draw.arc(
(90, 80, 150, 142), -90, -90 + self.Hard_capacity * 360 / 100,
fill=0x7f35e9, width=8)
# TEMP 温度
self.temp_t = self.gain.GET_Temp()
if self.temp_t < 45:
self.disp._pwm1.ChangeDutyCycle(50)
elif self.temp_t < 50:
self.disp._pwm1.ChangeDutyCycle(70)
elif self.temp_t < 55:
self.disp._pwm1.ChangeDutyCycle(80)
else:
self.disp._pwm1.ChangeDutyCycle(100)
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 18)
self.draw.text(
(268, 100), str(math.floor(self.temp_t)) + '',
fill=0x0088ff, font=Font1)
self.draw.arc((253, 80, 313, 142), 0, 360, fill=0xffffff, width=8)
self.draw.arc(
(253, 80, 313, 142), -90, -90 + self.temp_t * 360 / 100,
fill=0x0088ff, width=8)
# speed 网速
TX = self.gain.TX_speed() * 1024
if TX < 1024: # B
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 18)
self.draw.text(
(250, 190), str(math.floor(TX)) + 'B/s',
fill=0x00ff00, font=Font1)
elif TX < 1024 * 1024: # K
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 17)
self.draw.text(
(249, 190), str(math.floor(TX/1024)) + 'KB/s',
fill=0x00ffff, font=Font1)
else: # M
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 18)
self.draw.text(
(250, 190), str(math.floor(TX/1024/1024)) + 'M/s',
fill=0x008fff, font=Font1)
TX = self.gain.RX_speed() * 1024
if TX < 1024: # B
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 18)
self.draw.text(
(183, 190), str(math.floor(TX)) + 'B/s',
fill=0x00ff00, font=Font1)
elif TX < 1024 * 1024: # K
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 17)
self.draw.text(
(180, 190), str(math.floor(TX/1024)) + 'KB/s',
fill=0x008fff, font=Font1)
else: # M
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 18)
self.draw.text(
(181, 190), str(math.floor(TX/1024/1024)) + 'M/s',
fill=0x008fff, font=Font1)
# memory_percentage 内存百分比
tot_m, used_m, free_m = map(
int, os.popen('free -t -m').readlines()[-1].split()[1:])
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 18)
memory_percentage = 100 - free_m / tot_m * 100
if memory_percentage >= 100:
self.draw.text(
(186, 100), str(math.floor(memory_percentage)) + '%',
fill=0xf1b400, font=Font1)
elif memory_percentage >= 10:
self.draw.text(
(189, 100), str(math.floor(memory_percentage)) + '%',
fill=0xf1b400, font=Font1)
else:
self.draw.text(
(195, 100), str(math.floor(memory_percentage)) + '%',
fill=0xf1b400, font=Font1)
self.draw.arc((173, 80, 233, 142), 0, 360, fill=0xffffff, width=8)
self.draw.arc(
(173, 80, 233, 142), -90, -90 + memory_percentage * 360 / 100,
fill=0xf1b400, width=8)
# Disk 使用情况
if self.gain.Get_back[0] == 0:
self.draw.rectangle((40, 177, 142, 190))
self.draw.rectangle((41, 178, 141, 189), fill=0x000000)
else:
self.draw.rectangle((40, 177, 142, 190))
self.draw.rectangle(
(41, 178, 41 + self.gain.Get_back[2], 189), fill=0x7f35e9)
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 13)
self.draw.text(
(80, 176), str(math.floor(self.gain.Get_back[2])) + '%',
fill=0xf1b400, font=Font1)
if self.gain.Get_back[1] == 0:
self.draw.rectangle((40, 197, 142, 210))
self.draw.rectangle((41, 198, 141, 209), fill=0x000000)
else:
self.draw.rectangle((40, 197, 142, 210))
self.draw.rectangle(
(41, 198, 41 + self.gain.Get_back[3], 209), fill=0x7f35e9)
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 13)
self.draw.text(
(80, 196), str(math.floor(self.gain.Get_back[3])) + '%',
fill=0xf1b400, font=Font1)
if self.gain.Get_back[4] == 1:
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 15)
self.draw.text((40, 161), 'RAID', fill=0xf7ba47, font=Font1)
if (
(self.gain.Get_back[0] == 0 and self.gain.Get_back[1] == 0)
or (self.gain.Get_back[0] != 0 and self.gain.Get_back[1] == 0)
or (self.gain.Get_back[0] == 0 and self.gain.Get_back[1] != 0)
):
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 15)
if self.gain.flag > 0:
self.draw.text(
(30, 210), 'Detected but not installed',
fill=0xf7ba47, font=Font1)
else:
self.draw.text(
(50, 210), 'Unpartitioned/NC',
fill=0xf7ba47, font=Font1)
self.image = self.image.rotate(180)
self.disp.ShowImage(self.image)
# time.sleep(0.5)
except IOError as e:
logging.info(e)
except KeyboardInterrupt:
self.disp.module_exit()
logging.info("quit:")
exit()
def HMI2(self):
try:
self.image = Image.open(os.path.join(app_dir, "pic", 'Disk.jpg'))
self.draw = ImageDraw.Draw(self.image)
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 20)
self.draw.text((60, 55), 'CPU Used', fill=0xC1C0BE, font=Font1)
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 13)
self.draw.text((45, 140), 'Used', fill=0xC1C0BE, font=Font1)
self.draw.text((45, 163), 'Free', fill=0xC1C0BE, font=Font1)
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 14)
self.draw.text((185, 93), 'Disk0:', fill=0xC1C0BE, font=Font1)
self.draw.text((185, 114), 'Disk1:', fill=0xC1C0BE, font=Font1)
self.draw.text((188, 155), 'TX:', fill=0xC1C0BE, font=Font1)
self.draw.text((188, 175), 'RX:', fill=0xC1C0BE, font=Font1)
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 15)
self.draw.text((133, 205), 'TEMP:', fill=0x0088ff, font=Font1)
# TIME 时间
time_t = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 15)
self.draw.text((40, 10), time_t, fill=0xffffff, font=Font1)
# IP
ip = self.gain.GET_IP()
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 17)
self.draw.text((155, 58), 'IP : ' + ip, fill=0xC1C0BE, font=Font1)
# CPU usage CPU使用率
self.CPU_usage = os.popen(
'top -bi -n 2 -d 0.02'
).read().split('\n\n\n')[0].split('\n')[2]
self.CPU_usage = re.sub('[a-zA-z%(): ]', '', self.CPU_usage)
self.CPU_usage = self.CPU_usage.split(',')
self.CPU_usagex = 100 - eval(self.CPU_usage[3])
if self.CPU_usagex >= 100:
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 10)
self.draw.text(
(80, 107), str(math.floor(self.CPU_usagex)) + '%',
fill=0xf1b400, font=Font1)
elif self.CPU_usagex >= 10:
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 13)
self.draw.text(
(79, 105), str(math.floor(self.CPU_usagex)) + '%',
fill=0xf1b400, font=Font1)
else:
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 15)
self.draw.text(
(81, 104), str(math.floor(self.CPU_usagex)) + '%',
fill=0xf1b400, font=Font1)
self.draw.arc(
(66, 90, 111, 135), -90, -90 + self.CPU_usagex * 360 / 100,
fill=0x7f35e9, width=3)
# System disk usage 系统磁盘使用率
x = os.popen('df -h /')
i2 = 0
while 1:
i2 = i2 + 1
line = x.readline()
if i2 == 2:
self.Capacity_Used = line.split()[2]
self.Capacity_Avail = line.split()[3]
if (
self.Capacity_Used.count('G')
and self.Capacity_Avail.count('G')
):
self.Used_capacity = float(
re.sub('[A-Z]', '', self.Capacity_Used)) * 1024
self.Avail_capacity = float(
re.sub('[A-Z]', '', self.Capacity_Avail)) * 1024
elif (
self.Capacity_Used.count('G')
and self.Capacity_Avail.count('M')
):
self.Used_capacity = float(
re.sub('[A-Z]', '', self.Capacity_Used)) * 1024
self.Avail_capacity = float(
re.sub('[A-Z]', '', self.Capacity_Avail))
elif (
self.Capacity_Used.count('M')
and self.Capacity_Avail.count('G')
):
self.Used_capacity = float(
re.sub('[A-Z]', '', self.Capacity_Used))
self.Avail_capacity = float(
re.sub('[A-Z]', '', self.Capacity_Avail)) * 1024
else:
self.Used_capacity = float(
re.sub('[A-Z]', '', self.Capacity_Used))
self.Avail_capacity = float(
re.sub('[A-Z]', '', self.Capacity_Avail))
break
if(self.Used_capacity > 1024 and self.Avail_capacity > 1024):
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 13)
self.draw.text((125, 140), 'G', fill=0xC1C0BE, font=Font1)
self.draw.text((125, 163), 'G', fill=0xC1C0BE, font=Font1)
self.Used_capacity = self.Used_capacity / 1024
self.Avail_capacity = self.Avail_capacity / 1024
self.Disk_always = self.Used_capacity + self.Avail_capacity
if self.Disk_always <= 99:
self.draw.text(
(100, 140), str(round(self.Used_capacity, 2)),
fill=0xC1C0BE, font=Font1)
self.draw.text(
(100, 163), str(round(self.Avail_capacity, 2)),
fill=0xC1C0BE, font=Font1,)
elif self.Disk_always > 99:
self.draw.text(
(85, 140), str(round(self.Used_capacity, 2)),
fill=0xC1C0BE, font=Font1)
self.draw.text(
(85, 163), str(round(self.Avail_capacity, 2)),
fill=0xC1C0BE, font=Font1)
else:
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 13)
self.draw.text((125, 140), 'M', fill=0xC1C0BE, font=Font1)
self.draw.text((125, 163), 'M', fill=0xC1C0BE, font=Font1)
self.Disk_always = self.Used_capacity + self.Avail_capacity
self.draw.text(
(80, 140), str(round(self.Used_capacity, 2)),
fill=0xC1C0BE, font=Font1)
self.draw.text(
(80, 163), str(round(self.Avail_capacity, 2)),
fill=0xC1C0BE, font=Font1)
self.draw.rectangle((
45, 157, 45 + self.Used_capacity / self.Disk_always * 87, 160
), fill=0x7f35e9)
self.draw.rectangle((
45, 180, 45 + self.Avail_capacity / self.Disk_always * 87, 183
), fill=0x7f35e9)
# TEMP 温度
temp_t = self.gain.GET_Temp()
if self.temp_t < 45:
self.disp._pwm1.ChangeDutyCycle(50)
elif self.temp_t < 50:
self.disp._pwm1.ChangeDutyCycle(70)
elif self.temp_t < 55:
self.disp._pwm1.ChangeDutyCycle(80)
else:
self.disp._pwm1.ChangeDutyCycle(100)
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 15)
self.draw.text(
(170, 205), str(math.floor(temp_t))+'',
fill=0x0088ff, font=Font1)
# speed 网速
TX = self.gain.TX_speed() * 1024
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 15)
if TX < 1024: # B
self.draw.text(
(210, 154), str(math.floor(TX)) + 'B/s',
fill=0x00ff00, font=Font1)
elif TX < 1024*1024: # K
self.draw.text(
(210, 154), str(math.floor(TX/1024)) + 'KB/s',
fill=0x00ffff, font=Font1)
else: # M
self.draw.text(
(210, 154), str(math.floor(TX/1024/1024)) + 'M/s',
fill=0x008fff, font=Font1)
TX = self.gain.RX_speed() * 1024
if TX < 1024: # B
self.draw.text(
(210, 174), str(math.floor(TX)) + 'B/s',
fill=0x00ff00, font=Font1)
elif TX < 1024*1024: # K
self.draw.text(
(210, 174), str(math.floor(TX/1024)) + 'KB/s',
fill=0x008fff, font=Font1)
else: # M
self.draw.text(
(210, 174), str(math.floor(TX/1024/1024)) + 'M/s',
fill=0x008fff, font=Font1)
# Disk 使用情况
self.Disk0_Avail = self.gain.Get_back[0] - (
self.gain.Get_back[0] * self.gain.Get_back[2] // 100)
self.Disk1_Avail = self.gain.Get_back[1] - (
self.gain.Get_back[1] * self.gain.Get_back[3] // 100)
self.draw.text(
(240, 93), str(math.floor(self.Disk0_Avail)) + 'G',
fill=0xC1C0BE, font=Font1)
self.draw.text(
(240, 114), str(math.floor(self.Disk1_Avail)) + 'G',
fill=0xC1C0BE, font=Font1)
if self.gain.Get_back[0] == 0:
self.draw.rectangle((186, 110, 273, 113), fill=0x000000)
else:
self.draw.rectangle(
(186, 110, 186 + self.gain.Get_back[2] * 87 / 100, 113),
fill=0x7f35e9)
if self.gain.Get_back[1] == 0:
self.draw.rectangle((186, 131, 273, 134), fill=0x000000)
else:
self.draw.rectangle(
(186, 131, 186 + self.gain.Get_back[3] * 87 / 100, 134),
fill=0x7f35e9)
if self.gain.Get_back[4] == 1:
self.draw.text((160, 78), 'RAID', fill=0xC1C0BE, font=Font1)
if (
(self.gain.Get_back[0] == 0 and self.gain.Get_back[1] == 0)
or (self.gain.Get_back[0] != 0 and self.gain.Get_back[1] == 0)
or (self.gain.Get_back[0] == 0 and self.gain.Get_back[1] != 0)
):
Font1 = ImageFont.truetype(
os.path.join(app_dir, "Font", "Font02.ttf"), 14)
if self.gain.flag > 0:
self.draw.text(
(155, 135), 'Detected but not installed',
fill=0xC1C0BE, font=Font1)
else:
self.draw.text(
(190, 135), 'Unpartitioned/NC',
fill=0xC1C0BE, font=Font1)
self.image = self.image.rotate(180)
self.disp.ShowImage(self.image)
# time.sleep(0.5)
except IOError as e:
logging.info(e)
except KeyboardInterrupt:
self.disp.module_exit()
logging.info("quit:")
exit()

View File

@ -0,0 +1,233 @@
# -*- coding: utf-8 -*-
import os
import re
import time
import socket
class Gain_Param():
Get_back = [0, 0, 0, 0, 0] # 返回Disk的内存
flag = 0 # 未挂载还是未分区
def GET_IP(self):
# 会存在异常 卡死 谨慎获取
# There will be exceptions, get stuck, get it carefully
# Threading is better
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect_ex(('8.8.8.8', 80))
ip = s.getsockname()[0]
s.close()
return ip
def GET_Temp(self):
with open('/sys/class/thermal/thermal_zone0/temp', 'rt') as f:
temp = int(f.read()) / 1000.0
# print(temp)
return temp
def net_speed(self, interface, is_download):
# Get the corresponding value 获取对应值
which_num = 0 if is_download else 8
# Read the file 读取文件
with open('/proc/net/dev') as f:
lines = f.readlines()
# Get result value 获取结果值
for line in lines:
if line.rstrip().split(':')[0].strip() == interface:
return line.rstrip().split(':')[1].split()[which_num]
def RX_speed(self):
interface = 'eth0'
is_upload = True # False
get_time = 0.1
# Computation part 计算部分
begin = int(self.net_speed(interface, is_upload))
time.sleep(get_time)
end = int(self.net_speed(interface, is_upload))
return ((end - begin) / get_time / 1024)
def TX_speed(self):
interface = 'eth0'
is_upload = False
get_time = 0.1
# Computation part 计算部分
begin = int(self.net_speed(interface, is_upload))
time.sleep(get_time)
end = int(self.net_speed(interface, is_upload))
return ((end - begin) / get_time / 1024)
def Hard_data(self):
while True:
Hard_capacity1 = os.popen('lsblk -f ').read().split('\n\n\n')[0]
Disk_number = sum(
1 for i in re.finditer(r'^[a-z]', Hard_capacity1, re.MULTILINE)
)
Hard_segmentation = Hard_capacity1.split('\n\n\n')[0].split('\n')
k = 0 # Counting migration 计数偏移
j = 0 # 连接盘的数量
Disk0_capacity = 0 # total capacity 总容量
Disk0_usege = 0 # have been used 已使用
Disk1_capacity = 0
Disk1_usege = 0
for i in range(0, Disk_number):
if i == 0:
a = Hard_segmentation[k+1].strip().split()
if len(a) != 1:
if a[1].count('raid') == 1:
self.Get_back[4] = 1 # 检测是否组RAID '1'表示组了
else:
self.Get_back[4] = 0
if(a[0].count('mmcblk') == 1):
continue
name0 = a[0]
else:
a = Hard_segmentation[k+1].strip().split()
if a[0].count('mmcblk') == 1:
continue
if len(a) != 1:
if a[1].count('raid') == 1:
self.Get_back[4] = 1 # 检测是否组RAID '1'表示组了
else:
self.Get_back[4] = 0
flgh = 0
j = j + 1
if len(a) == 1:
disk_partition_Number = Hard_capacity1.count(''+a[0])
self.Get_back[4] = 0
else:
if a[1].count('raid') == 0:
self.Get_back[4] = 0
disk_partition_Number = Hard_capacity1.count(''+a[0])
else:
disk_partition_Number = 1
self.Get_back[4] = 1
if(disk_partition_Number == 0):
disk_partition_Number = 1
flgh = 1
for i1 in range(0, disk_partition_Number):
if (disk_partition_Number > 0 and flgh == 0):
Partition_data_split = ' '.join(
Hard_segmentation[i1+2+k].split()).split(' ')
else:
Partition_data_split = ' '.join(
Hard_segmentation[i1+1+k].split()).split(' ')
if (
len(Partition_data_split) <= 5
and len(Partition_data_split) > 0
):
# name = re.sub('[├─└]', '', Partition_data_split[0])
if len(Partition_data_split) == 1:
self.flag = 0
else:
# print(
# "%s This drive letter is not mounted\n"
# % name)
self.flag = 1 # 检测是否挂载盘 1表示没有挂载
# continue
else:
# print("%s The drive letter is properly mounted\n" % (
# re.sub('[├─└]', '', Partition_data_split[0])))
if (
disk_partition_Number > 0 and name0 == a[0]
or self.Get_back[4] == 1
):
p = os.popen(
"df -h " + Partition_data_split[len(
Partition_data_split) - 1])
i2 = 0
while 1:
i2 = i2 + 1
line = p.readline()
if i2 == 2:
#: Total cost of the partition 分区总值
Capacity = line.split()[1]
x = int(re.sub('[A-Za-z]', '', Capacity))
Disk0_capacity = Disk0_capacity + x
Capacity = "".join(list(filter(
str.isdigit, Capacity)))
# Partition memory usage 分区使用内存
Capacity_usage = line.split()[2]
if Capacity_usage.count('G'):
x = float(re.sub(
'[A-Z]', '', Capacity_usage))
Disk0_usege = Disk0_usege + x
break
else:
x = float(re.sub(
'[A-Z]', '', Capacity_usage)
) / 1024
Disk0_usege = Disk0_usege + x
break
else:
p = os.popen(
"df -h " + Partition_data_split[len(
Partition_data_split) - 1])
i2 = 0
while 1:
i2 = i2 + 1
line = p.readline()
if i2 == 2:
# Total cost of the partition 分区总值
Capacity = line.split()[1]
x = int(re.sub('[A-Za-z]', '', Capacity))
Disk1_capacity = Disk1_capacity + x
# Partition memory usage 分区使用内存
Capacity_usage = line.split()[2]
if(Capacity_usage.count('G')):
x = float(re.sub(
'[A-Z]', '', Capacity_usage))
Disk1_usege = Disk1_usege + x
break
else:
x = float(re.sub(
'[A-Z]', '', Capacity_usage)
) / 1024
Disk1_usege = Disk1_usege + x
break
if(flgh == 0):
k = k + disk_partition_Number + 1
else:
k = k + disk_partition_Number
if j == 1 and len(Partition_data_split) > 5:
self.flag = 0
if self.Get_back[4] == 1:
Disk1_capacity = Disk0_capacity / 2
Disk0_capacity = Disk1_capacity
Disk1_usege = Disk0_usege / 2
Disk0_usege = Disk1_usege
if Disk0_capacity == 0 and Disk1_capacity == 0:
self.Get_back = [
Disk0_capacity, Disk1_capacity, Disk0_usege, Disk1_usege,
self.Get_back[4]]
elif Disk0_capacity == 0 and Disk1_capacity != 0:
Disk1_usege = round(Disk1_usege / Disk1_capacity * 100, 0)
self.Get_back = [
Disk0_capacity, Disk1_capacity, Disk0_usege, Disk1_usege,
self.Get_back[4]]
elif Disk0_capacity != 0 and Disk1_capacity == 0:
Disk0_usege = round(Disk0_usege / Disk0_capacity * 100, 0)
self.Get_back = [
Disk0_capacity, Disk1_capacity, Disk0_usege, Disk1_usege,
self.Get_back[4]]
else:
Disk0_usege = round(Disk0_usege / Disk0_capacity * 100, 0)
Disk1_usege = round(Disk1_usege / Disk1_capacity * 100, 0)
self.Get_back = [
Disk0_capacity, Disk1_capacity, Disk0_usege, Disk1_usege,
self.Get_back[4]]
time.sleep(1.5)

View File

@ -0,0 +1,185 @@
import time
from . import lcdconfig
class LCD_2inch(lcdconfig.RaspberryPi):
width = 240
height = 320
def command(self, cmd):
self.digital_write(self.DC_PIN, self.GPIO.LOW)
self.spi_writebyte([cmd])
def data(self, val):
self.digital_write(self.DC_PIN, self.GPIO.HIGH)
self.spi_writebyte([val])
def reset(self):
"""Reset the display"""
self.GPIO.output(self.RST_PIN, self.GPIO.HIGH)
time.sleep(0.01)
self.GPIO.output(self.RST_PIN, self.GPIO.LOW)
time.sleep(0.01)
self.GPIO.output(self.RST_PIN, self.GPIO.HIGH)
time.sleep(0.01)
def Init(self):
"""Initialize dispaly"""
self.module_init()
self.reset()
self.command(0x36)
self.data(0x00)
self.command(0x3A)
self.data(0x05)
self.command(0x21)
self.command(0x2A)
self.data(0x00)
self.data(0x00)
self.data(0x01)
self.data(0x3F)
self.command(0x2B)
self.data(0x00)
self.data(0x00)
self.data(0x00)
self.data(0xEF)
self.command(0xB2)
self.data(0x0C)
self.data(0x0C)
self.data(0x00)
self.data(0x33)
self.data(0x33)
self.command(0xB7)
self.data(0x35)
self.command(0xBB)
self.data(0x1F)
self.command(0xC0)
self.data(0x2C)
self.command(0xC2)
self.data(0x01)
self.command(0xC3)
self.data(0x12)
self.command(0xC4)
self.data(0x20)
self.command(0xC6)
self.data(0x0F)
self.command(0xD0)
self.data(0xA4)
self.data(0xA1)
self.command(0xE0)
self.data(0xD0)
self.data(0x08)
self.data(0x11)
self.data(0x08)
self.data(0x0C)
self.data(0x15)
self.data(0x39)
self.data(0x33)
self.data(0x50)
self.data(0x36)
self.data(0x13)
self.data(0x14)
self.data(0x29)
self.data(0x2D)
self.command(0xE1)
self.data(0xD0)
self.data(0x08)
self.data(0x10)
self.data(0x08)
self.data(0x06)
self.data(0x06)
self.data(0x39)
self.data(0x44)
self.data(0x51)
self.data(0x0B)
self.data(0x16)
self.data(0x14)
self.data(0x2F)
self.data(0x31)
self.command(0x21)
self.command(0x11)
self.command(0x29)
def SetWindows(self, Xstart, Ystart, Xend, Yend):
self.command(0x2A)
#: set the X coordinates
self.data(Xstart >> 8)
#: Set the horizontal starting point to the high octet
self.data(Xstart & 0xff)
#: Set the horizontal starting point to the low octet
self.data(Xend >> 8)
#: Set the horizontal end to the high octet
self.data((Xend - 1) & 0xff)
#: Set the horizontal end to the low octet
self.command(0x2B)
#: set the Y coordinates
self.data(Ystart >> 8)
self.data((Ystart & 0xff))
self.data(Yend >> 8)
self.data((Yend - 1) & 0xff)
self.command(0x2C)
def ShowImage(self, Image, Xstart=0, Ystart=0):
"""Set buffer to value of Python Imaging Library image."""
"""Write display buffer to physical display"""
imwidth, imheight = Image.size
if imwidth == self.height and imheight == self.width:
img = self.np.asarray(Image)
pix = self.np.zeros(
(self.width, self.height, 2), dtype=self.np.uint8)
# RGB888 >> RGB565
pix[...,[0]] = self.np.add(self.np.bitwise_and(img[...,[0]],0xF8),self.np.right_shift(img[...,[1]],5))
pix[...,[1]] = self.np.add(self.np.bitwise_and(self.np.left_shift(img[...,[1]],3),0xE0), self.np.right_shift(img[...,[2]],3))
pix = pix.flatten().tolist()
self.command(0x36)
self.data(0x70)
self.SetWindows(0, 0, self.height, self.width)
self.digital_write(self.DC_PIN, self.GPIO.HIGH)
for i in range(0, len(pix), 4096):
self.spi_writebyte(pix[i:i+4096])
else:
img = self.np.asarray(Image)
pix = self.np.zeros((imheight, imwidth, 2), dtype=self.np.uint8)
pix[...,[0]] = self.np.add(self.np.bitwise_and(img[...,[0]],0xF8),self.np.right_shift(img[...,[1]],5))
pix[...,[1]] = self.np.add(self.np.bitwise_and(self.np.left_shift(img[...,[1]],3),0xE0), self.np.right_shift(img[...,[2]],3))
pix = pix.flatten().tolist()
self.command(0x36)
self.data(0x00)
self.SetWindows(0, 0, self.width, self.height)
self.digital_write(self.DC_PIN, self.GPIO.HIGH)
for i in range(0, len(pix), 4096):
self.spi_writebyte(pix[i:i+4096])
def clear(self):
"""Clear contents of image buffer"""
_buffer = [0xff]*(self.width * self.height * 2)
self.SetWindows(0, 0, self.width, self.height)
self.digital_write(self.DC_PIN, self.GPIO.HIGH)
for i in range(0, len(_buffer), 4096):
self.spi_writebyte(_buffer[i:i+4096])

View File

@ -0,0 +1,118 @@
# /*****************************************************************************
# * | File : epdconfig.py
# * | Author : Waveshare team
# * | Function : Hardware underlying interface
# * | Info :
# *----------------
# * | This version: V1.0
# * | Date : 2019-06-21
# * | Info :
# ******************************************************************************
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
import logging
import time
import spidev
class RaspberryPi:
def __init__(
self, spi=spidev.SpiDev(0, 0), spi_freq=40000000, rst=27, dc=25, bl=18,
fan=19, bl_freq=1000, i2c=None, i2c_freq=100000
):
import RPi.GPIO
import numpy as np
self.np = np
self.RST_PIN = rst
self.DC_PIN = dc
self.BL_PIN = bl
self.FAN_PIN = fan
self.SPEED = spi_freq
self.BL_freq = bl_freq
self.GPIO = RPi.GPIO
# self.GPIO.cleanup()
self.GPIO.setmode(self.GPIO.BCM)
self.GPIO.setwarnings(False)
self.GPIO.setup(self.RST_PIN, self.GPIO.OUT)
self.GPIO.setup(self.DC_PIN, self.GPIO.OUT)
self.GPIO.setup(self.BL_PIN, self.GPIO.OUT)
self.GPIO.output(self.BL_PIN, self.GPIO.HIGH)
# Initialize SPI
self.SPI = spi
if self.SPI is not None:
self.SPI.max_speed_hz = spi_freq
self.SPI.mode = 0b00
def digital_write(self, pin, value):
self.GPIO.output(pin, value)
def digital_read(self, pin):
return self.GPIO.input(pin)
def delay_ms(self, delaytime):
time.sleep(delaytime / 1000.0)
def spi_writebyte(self, data):
if self.SPI is not None:
self.SPI.writebytes(data)
def bl_DutyCycle(self, duty):
self._pwm.ChangeDutyCycle(duty)
def bl_Frequency(self, freq):
self._pwm.ChangeFrequency(freq)
def module_init(self):
self.GPIO.setup(self.RST_PIN, self.GPIO.OUT)
self.GPIO.setup(self.DC_PIN, self.GPIO.OUT)
self.GPIO.setup(self.BL_PIN, self.GPIO.OUT)
self.GPIO.setup(self.FAN_PIN, self.GPIO.OUT)
# self.GPIO.output(self.FAN_PIN, 1)
self._pwm = self.GPIO.PWM(self.BL_PIN, self.BL_freq)
self._pwm.start(100)
self._pwm1 = self.GPIO.PWM(self.FAN_PIN, self.BL_freq)
self._pwm1.start(75)
if self.SPI is not None:
self.SPI.max_speed_hz = self.SPEED
self.SPI.mode = 0b00
return 0
def module_exit(self):
logging.debug("spi end")
if self.SPI is not None:
self.SPI.close()
logging.debug("gpio cleanup...")
self.GPIO.output(self.RST_PIN, 1)
self.GPIO.output(self.DC_PIN, 0)
self._pwm.stop()
self._pwm1.stop()
# self.GPIO.cleanup()
'''
if os.path.exists('/sys/bus/platform/drivers/gpiomem-bcm2835'):
implementation = RaspberryPi()
for func in [x for x in dir(implementation) if not x.startswith('_')]:
setattr(sys.modules[__name__], func, getattr(implementation, func))
'''

View File

@ -0,0 +1,19 @@
'''
Select images as required
True for image1
False for image2
'''
import time
from . import image
Img = image.image()
while True:
if Img.flgh:
Img.HMI1()
else:
Img.HMI2()
time.sleep(1)