copy of monitor.py
This commit is contained in:
+429
@@ -0,0 +1,429 @@
|
|||||||
|
# -*- coding:utf-8 -*-
|
||||||
|
|
||||||
|
from luma.core.interface.serial import i2c, spi
|
||||||
|
from luma.core.render import canvas
|
||||||
|
from luma.core import lib
|
||||||
|
|
||||||
|
from luma.oled.device import sh1106
|
||||||
|
import RPi.GPIO as GPIO
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import subprocess
|
||||||
|
import os
|
||||||
|
import string
|
||||||
|
|
||||||
|
from PIL import Image
|
||||||
|
from PIL import ImageDraw
|
||||||
|
from PIL import ImageFont
|
||||||
|
|
||||||
|
#GPIO define
|
||||||
|
RST_PIN = 25 #Reset
|
||||||
|
CS_PIN = 8
|
||||||
|
DC_PIN = 24
|
||||||
|
JS_U_PIN = 6 #Joystick Up
|
||||||
|
JS_D_PIN = 19 #Joystick Down
|
||||||
|
JS_L_PIN = 5 #Joystick Left
|
||||||
|
JS_R_PIN = 26 #Joystick Right
|
||||||
|
JS_P_PIN = 13 #Joystick Pressed
|
||||||
|
BTN1_PIN = 21
|
||||||
|
BTN2_PIN = 20
|
||||||
|
BTN3_PIN = 16
|
||||||
|
|
||||||
|
# Some constants
|
||||||
|
SCREEN_LINES = 4
|
||||||
|
SCREEN_SAVER = 20.0
|
||||||
|
CHAR_WIDTH = 19
|
||||||
|
font = ImageFont.load_default()
|
||||||
|
width = 128
|
||||||
|
height = 64
|
||||||
|
x0 = 0
|
||||||
|
x1 = 84
|
||||||
|
y0 = -2
|
||||||
|
y1 = 12
|
||||||
|
x2 = x1+7
|
||||||
|
x3 = x1+14
|
||||||
|
x4 = x1+9
|
||||||
|
x5 = x2+9
|
||||||
|
x6 = x3+9
|
||||||
|
|
||||||
|
choices = [
|
||||||
|
["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"],
|
||||||
|
["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"],
|
||||||
|
["0","1","2","3","4","5","6","7","8","9","!","@","#","$","%","^","&","*","(",")",",",".","?",":",";","'"]
|
||||||
|
]
|
||||||
|
|
||||||
|
# init GPIO
|
||||||
|
GPIO.setmode(GPIO.BCM)
|
||||||
|
GPIO.setup(JS_U_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up
|
||||||
|
GPIO.setup(JS_D_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up
|
||||||
|
GPIO.setup(JS_L_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up
|
||||||
|
GPIO.setup(JS_R_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up
|
||||||
|
GPIO.setup(JS_P_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up
|
||||||
|
GPIO.setup(BTN1_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up
|
||||||
|
GPIO.setup(BTN2_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up
|
||||||
|
GPIO.setup(BTN3_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up
|
||||||
|
|
||||||
|
# Initialize the display...
|
||||||
|
serial = spi(device=0, port=0, bus_speed_hz = 8000000, transfer_size = 4096, gpio_DC = DC_PIN, gpio_RST = RST_PIN)
|
||||||
|
device = sh1106(serial, rotate=2) #sh1106
|
||||||
|
draw = ImageDraw.Draw(Image.new('1', (width, height)))
|
||||||
|
draw.rectangle((0,0,width,height), outline=0, fill=0)
|
||||||
|
|
||||||
|
state = 0 #System state: 0 - scrren is off; equal to channel number (e.g. BTN2_PIN, JS_P_PIN) otherwise
|
||||||
|
horz = 1 #Selection choice: 0 - Right; 1 - Left
|
||||||
|
vert = 3 #Selection choice: 1 - Top; 2 - Middle; 3 - Bottom
|
||||||
|
stamp = time.time() #Current timestamp
|
||||||
|
start = time.time() #Start screen saver count down
|
||||||
|
iface = ""
|
||||||
|
idxWin = 0
|
||||||
|
idxLen = 0
|
||||||
|
aplist = []
|
||||||
|
apIndx = -1
|
||||||
|
pwdLst = []
|
||||||
|
pwdLen = 0
|
||||||
|
chaSel = 1 #possible values: 0, 1, 2
|
||||||
|
|
||||||
|
test = 0 # For testing!@1!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
def click_b1(channel):
|
||||||
|
global chaSel
|
||||||
|
if state == BTN1_PIN:
|
||||||
|
main_fun(channel)
|
||||||
|
else:
|
||||||
|
if apIndx < 0:
|
||||||
|
main_fun(BTN1_PIN)
|
||||||
|
else:
|
||||||
|
if chaSel > 0:
|
||||||
|
chaSel = chaSel - 1
|
||||||
|
pwdLst[horz] = choices[chaSel][vert]
|
||||||
|
main_fun(BTN2_PIN)
|
||||||
|
|
||||||
|
def click_b3(channel):
|
||||||
|
global start
|
||||||
|
global vert
|
||||||
|
global apIndx
|
||||||
|
global chaSel
|
||||||
|
if state == BTN3_PIN:
|
||||||
|
apIndx = -1
|
||||||
|
if vert == 1:
|
||||||
|
if horz == 1:
|
||||||
|
main_fun(995)
|
||||||
|
os.system("sudo shutdown -h now")
|
||||||
|
else:
|
||||||
|
main_fun(996)
|
||||||
|
os.system("sudo shutdown -r now")
|
||||||
|
elif vert == 2:
|
||||||
|
main_fun(997)
|
||||||
|
os.system("sudo usb_drive.sh refresh")
|
||||||
|
start = stamp - SCREEN_SAVER + 5
|
||||||
|
else:
|
||||||
|
main_fun(BTN1_PIN)
|
||||||
|
else:
|
||||||
|
if apIndx < 0:
|
||||||
|
vert = 3 # Default
|
||||||
|
main_fun(BTN3_PIN)
|
||||||
|
else:
|
||||||
|
if chaSel < 2:
|
||||||
|
chaSel = chaSel + 1
|
||||||
|
pwdLst[horz] = choices[chaSel][vert]
|
||||||
|
main_fun(BTN2_PIN)
|
||||||
|
|
||||||
|
def click_b2(channel):
|
||||||
|
global aplist
|
||||||
|
global idxWin
|
||||||
|
global idxLen
|
||||||
|
global start
|
||||||
|
global vert
|
||||||
|
global test
|
||||||
|
|
||||||
|
start = time.time()
|
||||||
|
|
||||||
|
if apIndx >= 0:
|
||||||
|
main_fun(998)
|
||||||
|
#print ''.join(pwdLst) #TODO change password for real...
|
||||||
|
start = stamp - SCREEN_SAVER + 5
|
||||||
|
else:
|
||||||
|
result = os.popen("iwlist {0} scan 2>/dev/null | grep '^..*ESSID:\"..*\"$' | sed 's/^.*ESSID:\"\\(..*\\)\".*$/\\1/'".format(iface)).read()
|
||||||
|
aplist = result.splitlines()
|
||||||
|
|
||||||
|
idxLen = len(aplist)
|
||||||
|
if (idxWin + SCREEN_LINES) > idxLen:
|
||||||
|
idxWin = idxLen - SCREEN_LINES
|
||||||
|
if idxWin < 0:
|
||||||
|
idxWin = 0
|
||||||
|
|
||||||
|
if vert > idxLen:
|
||||||
|
vert = idxLen
|
||||||
|
|
||||||
|
main_fun(channel)
|
||||||
|
|
||||||
|
def select_h(channel):
|
||||||
|
global apIndx
|
||||||
|
global start
|
||||||
|
global pwdLen
|
||||||
|
global horz
|
||||||
|
global vert
|
||||||
|
if state == BTN2_PIN:
|
||||||
|
if apIndx < 0: #select ssid mode
|
||||||
|
if channel == JS_L_PIN or channel == JS_R_PIN:
|
||||||
|
start = time.time()
|
||||||
|
apIndx = idxWin + vert - 1
|
||||||
|
pwdLen = len(pwdLst)
|
||||||
|
if (pwdLen > 0):
|
||||||
|
horz = pwdLen - 1
|
||||||
|
else:
|
||||||
|
horz = 0
|
||||||
|
else: #input mode
|
||||||
|
if channel == JS_L_PIN:
|
||||||
|
start = time.time()
|
||||||
|
if horz > 0:
|
||||||
|
horz = horz - 1
|
||||||
|
else:
|
||||||
|
apIndx = -1 #Exit input mode
|
||||||
|
horz = 0
|
||||||
|
vert = 1
|
||||||
|
elif channel == JS_R_PIN:
|
||||||
|
start = time.time()
|
||||||
|
if horz < pwdLen:
|
||||||
|
horz = horz + 1
|
||||||
|
else:
|
||||||
|
if channel == JS_L_PIN:
|
||||||
|
start = time.time()
|
||||||
|
horz = 1
|
||||||
|
draw_scn(state)
|
||||||
|
elif channel == JS_R_PIN:
|
||||||
|
start = time.time()
|
||||||
|
horz = 0
|
||||||
|
draw_scn(state)
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def select_v(channel):
|
||||||
|
global idxWin
|
||||||
|
global start
|
||||||
|
global vert
|
||||||
|
if state == BTN2_PIN:
|
||||||
|
if apIndx < 0: #select ssid mode
|
||||||
|
if channel == JS_U_PIN:
|
||||||
|
start = time.time()
|
||||||
|
if vert > 1:
|
||||||
|
vert = vert - 1
|
||||||
|
elif idxWin > 0:
|
||||||
|
idxWin = idxWin - 1
|
||||||
|
elif channel == JS_D_PIN:
|
||||||
|
start = time.time()
|
||||||
|
if vert < 4 and vert < idxLen:
|
||||||
|
vert = vert + 1
|
||||||
|
elif (idxWin + SCREEN_LINES) < idxLen:
|
||||||
|
idxWin = idxWin + 1
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
else: #input mode
|
||||||
|
if channel == JS_U_PIN:
|
||||||
|
start = time.time()
|
||||||
|
if vert > 0:
|
||||||
|
vert = vert - 1
|
||||||
|
else:
|
||||||
|
vert = 25
|
||||||
|
elif channel == JS_D_PIN:
|
||||||
|
start = time.time()
|
||||||
|
if vert < 25:
|
||||||
|
vert = vert + 1
|
||||||
|
else:
|
||||||
|
vert = 0
|
||||||
|
pwdLst[horz] = choices[chaSel][vert]
|
||||||
|
else:
|
||||||
|
if vert > 3:
|
||||||
|
vert = 3
|
||||||
|
if channel == JS_U_PIN:
|
||||||
|
start = time.time()
|
||||||
|
if vert > 1:
|
||||||
|
vert = vert - 1
|
||||||
|
elif channel == JS_D_PIN:
|
||||||
|
start = time.time()
|
||||||
|
if vert < 3:
|
||||||
|
vert = vert + 1
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def draw_scn(channel):
|
||||||
|
global idxLen
|
||||||
|
global pwdLen
|
||||||
|
global apIndx
|
||||||
|
with canvas(device) as draw:
|
||||||
|
LINE0 = subprocess.check_output("date +\"%Y-%m-%d %H:%M:%S\"", shell = True)
|
||||||
|
LINE1 = ""
|
||||||
|
LINE2 = ""
|
||||||
|
LINE3 = ""
|
||||||
|
LINE4 = ""
|
||||||
|
if channel == BTN1_PIN:
|
||||||
|
if horz == 1:
|
||||||
|
ssid = subprocess.check_output("iwgetid --raw | awk '{printf \"WiFi:%s\", $0}'", shell = True)
|
||||||
|
freq = subprocess.check_output("iwgetid --freq | awk '{gsub(/Frequency:/,\"\"); printf \" %.1f %s\", $2,$3}'", shell = True)
|
||||||
|
LINE1 = subprocess.check_output("hostname -I | awk '{printf \"IP: %s\", $1}'", shell = True )
|
||||||
|
LINE2 = subprocess.check_output("df -h /mnt/usb | awk '$NF==\"/mnt/usb\"{printf \"Disk:%s/%s %s\", $3,$2,$5}'", shell = True )
|
||||||
|
LINE3 = ssid + freq
|
||||||
|
LINE4 = subprocess.check_output("cat /sys/class/thermal/thermal_zone0/temp | awk '{printf \"Temp:%.1fC\", $1/1000}'", shell = True )
|
||||||
|
draw.rectangle((0,61,84,63), outline=255, fill=1)
|
||||||
|
draw.rectangle((85,61,127,63), outline=255, fill=0)
|
||||||
|
else:
|
||||||
|
LINE1 = subprocess.check_output("top -bn1 | awk 'NR==3{printf \"CPU:%.1f%% idle\", $8}'", shell = True )
|
||||||
|
LINE2 = subprocess.check_output("free -mh | awk 'NR==2{printf \"Mem:%s/%s %.1f%%\", $3,$2,$3*100/$2 }'", shell = True )
|
||||||
|
LINE3 = " in Kbps out Kbps"
|
||||||
|
LINE4 = subprocess.check_output("ifstat -bT 0.1 1 | awk 'NR==3{printf \"%9.2f %9.2f\",$3,$4}'", shell = True)
|
||||||
|
draw.rectangle((0,61,42,63), outline=255, fill=0)
|
||||||
|
draw.rectangle((43,61,127,63), outline=255, fill=1)
|
||||||
|
elif channel == BTN3_PIN:
|
||||||
|
y2 = y1*vert
|
||||||
|
LINE1 = "| Shutdown..."
|
||||||
|
LINE2 = "| Refresh"
|
||||||
|
LINE3 = "| Cancel"
|
||||||
|
|
||||||
|
if vert == 1:
|
||||||
|
if horz == 1:
|
||||||
|
LINE1 = "> Shutdown"
|
||||||
|
else:
|
||||||
|
LINE1 = "> Reboot"
|
||||||
|
elif vert == 2:
|
||||||
|
LINE2 = "> Refresh"
|
||||||
|
else:
|
||||||
|
LINE3 = "> Cancel"
|
||||||
|
|
||||||
|
if vert == 1:
|
||||||
|
if horz == 1:
|
||||||
|
draw.polygon([(x4,y2+6),(x5,y2-1),(x5,y2+4),(x6,y2+4),(x6,y2+8),(x5,y2+8),(x5,y2+13)], outline=255, fill=0)
|
||||||
|
draw.polygon([(x1,y2+6),(x2,y2-1),(x2,y2+4),(x3,y2+4),(x3,y2+8),(x2,y2+8),(x2,y2+13)], outline=255, fill=1)
|
||||||
|
else:
|
||||||
|
draw.polygon([(x1,y2+6),(x2,y2-1),(x2,y2+4),(x3,y2+4),(x3,y2+8),(x2,y2+8),(x2,y2+13)], outline=255, fill=0)
|
||||||
|
draw.polygon([(x4,y2+6),(x5,y2-1),(x5,y2+4),(x6,y2+4),(x6,y2+8),(x5,y2+8),(x5,y2+13)], outline=255, fill=1)
|
||||||
|
else:
|
||||||
|
draw.polygon([(x1,y2+6),(x2,y2-1),(x2,y2+4),(x3,y2+4),(x3,y2+8),(x2,y2+8),(x2,y2+13)], outline=255, fill=1)
|
||||||
|
|
||||||
|
elif channel == BTN2_PIN:
|
||||||
|
if apIndx < 0: #select ssid mode
|
||||||
|
y2 = y1*vert
|
||||||
|
if (idxWin >= 0) and (idxWin < idxLen):
|
||||||
|
LINE1 = aplist[idxWin]
|
||||||
|
if (idxWin + 1 < idxLen):
|
||||||
|
LINE2 = aplist[idxWin + 1]
|
||||||
|
if (idxWin + 2 < idxLen):
|
||||||
|
LINE3 = aplist[idxWin + 2]
|
||||||
|
if (idxWin + 3 < idxLen):
|
||||||
|
LINE4 = aplist[idxWin + 3]
|
||||||
|
|
||||||
|
draw.polygon([(x1,y2+6),(x2,y2-1),(x2,y2+4),(x3,y2+4),(x3,y2+8),(x2,y2+8),(x2,y2+13)], outline=255, fill=1)
|
||||||
|
draw.rectangle((125,12,127,60), outline=255, fill=0)
|
||||||
|
|
||||||
|
thumb_s = 48.0 / idxLen #Step
|
||||||
|
thumb_h = thumb_s * 4 #Because the screen can display 4 rows at a time
|
||||||
|
thumb_0 = idxWin * thumb_s + 12
|
||||||
|
thumb_1 = thumb_0 + thumb_h
|
||||||
|
if thumb_1 > 60:
|
||||||
|
thumb_1 = 60
|
||||||
|
draw.rectangle((125, thumb_0, 127, thumb_1), outline=255, fill=1)
|
||||||
|
else: #input mode
|
||||||
|
if horz >= pwdLen:
|
||||||
|
pwdLst.append(choices[chaSel][vert])
|
||||||
|
pwdLen = len(pwdLst)
|
||||||
|
|
||||||
|
cursorx = 6 * horz
|
||||||
|
cursory = y1 * 2
|
||||||
|
draw.text((122, y1) , choices[0][vert], font=font, fill=255)
|
||||||
|
draw.text((122, y1*2), choices[1][vert], font=font, fill=255)
|
||||||
|
draw.text((122, y1*3), choices[2][vert], font=font, fill=255)
|
||||||
|
draw.rectangle((cursorx,cursory+10,cursorx+4,cursory+11), outline=255, fill=1)
|
||||||
|
|
||||||
|
LINE1 = "SSID: " + aplist[apIndx]
|
||||||
|
if pwdLen > 0:
|
||||||
|
LINE2 = ''.join(pwdLst)
|
||||||
|
|
||||||
|
elif channel == 995:
|
||||||
|
LINE2 = " Shutting down..."
|
||||||
|
elif channel == 996:
|
||||||
|
LINE2 = " Rebooting..."
|
||||||
|
elif channel == 997:
|
||||||
|
LINE2 = " Refreshing..."
|
||||||
|
elif channel == 998:
|
||||||
|
LINE1 = "Setting passphrase"
|
||||||
|
LINE2 = "of '" + aplist[apIndx] + "'"
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
draw.text((x0, y0), LINE0, font=font, fill=255)
|
||||||
|
if len(LINE1) > CHAR_WIDTH:
|
||||||
|
draw.text((x0, y1), LINE1[:CHAR_WIDTH], font=font, fill=255)
|
||||||
|
else:
|
||||||
|
draw.text((x0, y1), LINE1, font=font, fill=255)
|
||||||
|
|
||||||
|
if len(LINE2) > CHAR_WIDTH:
|
||||||
|
draw.text((x0, y1*2), LINE2[:CHAR_WIDTH], font=font, fill=255)
|
||||||
|
else:
|
||||||
|
draw.text((x0, y1*2), LINE2, font=font, fill=255)
|
||||||
|
|
||||||
|
if len(LINE3) > CHAR_WIDTH:
|
||||||
|
draw.text((x0, y1*3), LINE3[:CHAR_WIDTH], font=font, fill=255)
|
||||||
|
else:
|
||||||
|
draw.text((x0, y1*3), LINE3, font=font, fill=255)
|
||||||
|
|
||||||
|
if len(LINE4) > CHAR_WIDTH:
|
||||||
|
draw.text((x0, y1*4), LINE4[:CHAR_WIDTH], font=font, fill=255)
|
||||||
|
else:
|
||||||
|
draw.text((x0, y1*4), LINE4, font=font, fill=255)
|
||||||
|
|
||||||
|
def main_fun(channel):
|
||||||
|
global serial
|
||||||
|
global device
|
||||||
|
global draw
|
||||||
|
global state
|
||||||
|
global start
|
||||||
|
global apIndx
|
||||||
|
if state <= 0: # Display is off
|
||||||
|
if channel > 0: # A button is pressed, turn on display
|
||||||
|
# Initialize the display...
|
||||||
|
serial = spi(device=0, port=0, bus_speed_hz = 8000000, transfer_size = 4096, gpio_DC = DC_PIN, gpio_RST = RST_PIN)
|
||||||
|
device = sh1106(serial, rotate=2) #sh1106
|
||||||
|
image = Image.new('1', (width, height))
|
||||||
|
draw = ImageDraw.Draw(image)
|
||||||
|
draw.rectangle((0,0,width,height), outline=0, fill=0)
|
||||||
|
|
||||||
|
state = channel
|
||||||
|
start = time.time()
|
||||||
|
apIndx = -1
|
||||||
|
draw_scn(channel)
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
else: # Display is on
|
||||||
|
if ((channel > 0) and (channel == state) and ((channel != BTN2_PIN) or (apIndx < 0))) or ((stamp - start) > SCREEN_SAVER): # A button is pressed or timed out, turn off display
|
||||||
|
GPIO.output(RST_PIN,GPIO.LOW)
|
||||||
|
state = 0
|
||||||
|
apIndx = -1
|
||||||
|
elif (channel > 0) and (channel != state) and ((state != BTN2_PIN) or (apIndx < 0) or (channel == 998)):
|
||||||
|
state = channel
|
||||||
|
start = time.time()
|
||||||
|
draw_scn(channel)
|
||||||
|
else: # state > 0 && channel == 0 && not-yet-timeout, refresh screen
|
||||||
|
draw_scn(state)
|
||||||
|
|
||||||
|
GPIO.add_event_detect(BTN1_PIN, GPIO.RISING, callback=click_b1, bouncetime=200)
|
||||||
|
GPIO.add_event_detect(BTN2_PIN, GPIO.RISING, callback=click_b2, bouncetime=200)
|
||||||
|
GPIO.add_event_detect(BTN3_PIN, GPIO.RISING, callback=click_b3, bouncetime=200)
|
||||||
|
GPIO.add_event_detect(JS_L_PIN, GPIO.RISING, callback=select_h, bouncetime=200)
|
||||||
|
GPIO.add_event_detect(JS_R_PIN, GPIO.RISING, callback=select_h, bouncetime=200)
|
||||||
|
GPIO.add_event_detect(JS_U_PIN, GPIO.RISING, callback=select_v, bouncetime=200)
|
||||||
|
GPIO.add_event_detect(JS_D_PIN, GPIO.RISING, callback=select_v, bouncetime=200)
|
||||||
|
|
||||||
|
#iface = subprocess.check_output("iwgetid | awk '{print $1}'", shell = True).rstrip("\r\n")
|
||||||
|
|
||||||
|
# Main Loop
|
||||||
|
try:
|
||||||
|
main_fun(BTN1_PIN)
|
||||||
|
while True:
|
||||||
|
stamp = time.time()
|
||||||
|
main_fun(0)
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
except:
|
||||||
|
print("Stopped", sys.exc_info()[0])
|
||||||
|
raise
|
||||||
|
GPIO.cleanup()
|
||||||
Reference in New Issue
Block a user