Skip to content

Instantly share code, notes, and snippets.

@apla
Last active June 15, 2019 23:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apla/c3f2cb9d30bbfedd2ce5d9e7ce24942e to your computer and use it in GitHub Desktop.
Save apla/c3f2cb9d30bbfedd2ce5d9e7ce24942e to your computer and use it in GitHub Desktop.
OrangePI protobor display monitor code
#!/bin/bash
cmd=$1
pin=$2
mode=$3
value=$3
pin_num=
function check_pin_format {
local pin=$1
# SUNXI https://github.com/torvalds/linux/blob/master/drivers/pinctrl/sunxi/pinctrl-sunxi.h#L19
# RASPBERRY https://github.com/torvalds/linux/blob/master/drivers/pinctrl/bcm/pinctrl-bcm2835.c (pin 0 - 53)
if ! [[ "$pin" =~ ^P[ABCDEFGHILMN][0-9]+$ ]] ; then
# get_pin_num $pin
# echo $pin_num
# else
echo "Pin should be P<bank><number>, like PA07"
exit
fi
}
function get_pin_num {
local pin_string=$1
check_pin_format $pin_string
bank_name=${pin_string:1:1}
bank_pin=${pin_string:2:2}
bank_offset=$(($(printf %x "'$bank_name") - 41))
pin_num=$(( $bank_offset * 32 + $bank_pin ))
}
case "$cmd" in
mode)
get_pin_num $pin
# export pin
echo "$pin_num" > /sys/class/gpio/export
# Sets pin 18 as an output
echo $mode > /sys/class/gpio/gpio$pin_num/direction
;;
read)
get_pin_num $pin
# Reading pin
cat /sys/class/gpio/gpio$pin_num/value
;;
write)
get_pin_num $pin
# Writing pin
echo "$value" > /sys/class/gpio/gpio$pin_num/value
;;
export)
get_pin_num $pin
echo "$pin_num" > /sys/class/gpio/export
;;
status)
get_pin_num $pin
cat /sys/class/gpio/gpio$pin_num/direction | xargs echo "Direction"
;;
unexport)
stop
;;
condrestart)
if test "x`pidof anacron`" != x; then
stop
start
fi
;;
*)
echo $"Usage: $0 {start|stop|restart|condrestart|status}"
exit 1
esac
# simulate some functions from gpio utility
# https://projects.drogon.net/raspberry-pi/wiringpi/the-gpio-utility/
# but without this nonsense http://wiringpi.com/pins/ https://projects.drogon.net/wiringpi-pin-numbering/
#!/usr/bin/env python
# vim: set fileencoding=utf-8
import os
import sys
from os.path import getmtime
WATCHED_FILES = [__file__]
WATCHED_FILES_MTIMES = [(f, getmtime(f)) for f in WATCHED_FILES]
from ina219 import INA219
from ina219 import DeviceRangeError
SHUNT_OHMS = 0.02
MAX_EXPECTED_AMPS = 8
import os
import sys
import time
from datetime import datetime
from luma.core.render import canvas
from PIL import ImageFont
import psutil
from luma.core.interface.serial import i2c, spi
from luma.core.render import canvas
from luma.oled.device import ssd1306, ssd1325, ssd1331, sh1106
regulatorSysPath = "/sys/class/regulator/regulator.4/"
file = open(regulatorSysPath + "min_microvolts", "r")
cpuMinVoltage = float(file.read()) / 1000000.0
file.close()
file = open(regulatorSysPath + "max_microvolts", "r")
cpuMaxVoltage = float(file.read()) / 1000000.0
file.close()
# rev.1 users set port=0
# substitute spi(device=0, port=0) below if using that interface
# serial = i2c(port=1, address=0x3C)
serial = i2c(port=0, address=0x3C)
# substitute ssd1331(...) or sh1106(...) below if using that device
device = sh1106(serial)
def read():
ina = INA219(SHUNT_OHMS, MAX_EXPECTED_AMPS, busnum=0)
ina.configure(ina.RANGE_16V, ina.GAIN_2_80MV)
print("Bus Voltage: %.3f V" % ina.voltage())
try:
print("Bus Current: %.3f mA" % ina.current())
print("Power: %.3f mW" % ina.power())
print("Shunt voltage: %.3f mV" % ina.shunt_voltage())
except DeviceRangeError as e:
print("Current overflow")
def readVA():
#return "TODO"
ina = INA219(SHUNT_OHMS, MAX_EXPECTED_AMPS, busnum=0)
ina.configure(ina.RANGE_16V, ina.GAIN_4_160MV)
return "%.3fV %.3fmA" % (ina.voltage(), ina.current());
try:
print("Bus Current: %.3f mA" % ina.current())
print("Power: %.3f mW" % ina.power())
print("Shunt voltage: %.3f mV" % ina.shunt_voltage())
except DeviceRangeError as e:
print("Current overflow")
def network(iface):
#stat = psutil.net_io_counters(pernic=True)[iface]
snics = psutil.net_if_addrs()[iface]
for snic in snics:
if snic.family == 2:
return "%s" % snic.address
def bytes2human(n):
"""
>>> bytes2human(10000)
'9K'
>>> bytes2human(100001221)
'95M'
"""
symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
prefix = {}
for i, s in enumerate(symbols):
prefix[s] = 1 << (i + 1) * 10
for s in reversed(symbols):
if n >= prefix[s]:
value = int(float(n) / prefix[s])
return '%s%s' % (value, s)
return "%sB" % n
def cpu_usage():
# load average, uptime
uptime = datetime.now() - datetime.fromtimestamp(psutil.boot_time())
av1, av2, av3 = os.getloadavg()
return "Ld:%.1f %.1f %.1f Up: %s" \
% (av1, av2, av3, str(uptime).split('.')[0])
def mem_usage():
usage = psutil.virtual_memory()
return "Mem: %s %.0f%%" \
% (bytes2human(usage.used), 100 - usage.percent)
def sys_usage():
cpu_percent = psutil.cpu_percent()
mem = psutil.virtual_memory()
return "%.0f%% RAM %.0f%%" \
% (cpu_percent, mem.percent)
def ram_percent():
mem = psutil.virtual_memory()
return mem.percent
def cpu_percent():
cpu_percent = psutil.cpu_percent()
return "%.0f%%" % (cpu_percent)
def hwmon():
hwmon = psutil.sensors_temperatures()
try:
hwmon_cpu_key = (hwmon.viewkeys() & {'iio_hwmon', 'cpu-thermal', 'cpu_thermal', 'gpu-thermal'}).pop() # hugging python
except (KeyError):
print hwmon.viewkeys()
hwmon_temp = hwmon[hwmon_cpu_key][0].current
return u"%.1f\N{DEGREE SIGN}C" % (hwmon_temp)
def cpu_voltage():
file = open(regulatorSysPath + "microvolts", "r")
strVolts = file.read()
file.close()
volts = float(strVolts) / 1000000.0
return volts
def disk_usage(dir):
usage = psutil.disk_usage(dir)
return "SD %s %.0f%%" \
% (bytes2human(usage.used), usage.percent)
def draw_cpu(draw, hot, x, y):
if hot:
draw.rectangle((x + 4, y + 4, x + 8, y + 8), fill="white")
max_lines = 5
for i in range(0, max_lines):
draw.line((0, 2 + i*2, 2, 2 + i*2), fill="white")
draw.line((2 + i*2, 0, 2 + i*2, 2), fill="white")
draw.line((max_lines * 2, 2 + i*2, max_lines * 2 + 2, 2 + i*2), fill="white")
draw.line((2 + i*2, max_lines * 2, 2 + i*2, max_lines * 2 + 2), fill="white")
def draw_ram(draw, percent, x, y):
max_lines = 3
mem9 = percent / 11.0
for i in range(0, max_lines):
for j in range(0, max_lines):
block9 = (i * max_lines + j + 1)
outline = "white" if mem9 > block9 + 1 or mem9 - (block9 - 1) > block9 - mem9 else "black"
draw.rectangle((x + 1 + i * 4, y + 1 + j * 4, x + 3 + i * 4, y + 3 + j * 4), fill="white", outline=outline)
def draw_wifi(draw, x, y):
draw.rectangle((x + 5, y + 10, x + 7, y + 10), fill="white")
draw.line((x + 6, y + 10, x + 6, y + 9), fill="white")
draw.line((x + 3, y + 8, x + 5, y + 6), fill="white")
draw.line((x + 5, y + 6, x + 7, y + 6), fill="white")
draw.line((x + 7, y + 6, x + 9, y + 8), fill="white")
draw.line((x + 1, y + 6, x + 4, y + 3), fill="white")
draw.line((x + 4, y + 3, x + 8, y + 3), fill="white")
draw.line((x + 8, y + 3, x + 11, y + 6), fill="white")
def draw_usb_logo(draw, x, y):
draw.rectangle((x + 5, y + 10, x + 7, y + 9), fill="white")
draw.rectangle((x + 5, y + 1, x + 7, y + 2), fill="white")
draw.line((x + 6, y + 2, x + 6, y + 9), fill="white")
draw.line((x + 6, y + 8, x + 2, y + 4), fill="white")
draw.line((x + 2, y + 4, x + 2, y + 2), fill="white")
draw.line((x + 6, y + 7, x + 10, y + 3), fill="white")
draw.line((x + 10, y + 3, x + 10, y + 1), fill="white")
def draw_usb(draw, active, x, y):
connFill = "white" if active else "black"
connHole = "black" if active else "white"
sizeAdj = 0 if active else 1
draw.rectangle((x + 1, y + 2, x + 11, y + 10), outline="white", fill=connFill)
draw.rectangle((x + 3 + sizeAdj, y + 4 + sizeAdj, x + 5, y + 6), fill=connHole)
draw.rectangle((x + 7, y + 4 + sizeAdj, x + 9 - sizeAdj, y + 6), fill=connHole)
draw.line((x + 0, y + 10, x + 12, y + 10), fill="white")
def draw_secure(draw, active, x, y):
connFill = "white" if active else "black"
connHole = "black" if active else "white"
sizeAdj = 0 if active else 1
draw.rectangle((x + 1, y + 2, x + 11, y + 10), outline="white", fill=connFill)
draw.rectangle((x + 3 + sizeAdj, y + 4 + sizeAdj, x + 5, y + 6), fill=connHole)
draw.rectangle((x + 7, y + 4 + sizeAdj, x + 9 - sizeAdj, y + 6), fill=connHole)
draw.line((x + 0, y + 10, x + 12, y + 10), fill="white")
def stats(device):
# use custom font
#font_path = os.path.abspath(os.path.join(os.path.dirname(__file__),'fonts', 'C&C Red Alert [INET].ttf'))
font_path = os.path.abspath(os.path.join(os.path.dirname(__file__), 'droid-mono.ttf'))
font12 = ImageFont.truetype(font_path, 12)
font6 = ImageFont.truetype(font_path, 6)
with canvas(device) as draw:
#draw.text((0, 0), cpu_usage(), font=font2, fill="white")
if device.height >= 32:
# draw.text((0, 14), mem_usage(), font=font2, fill="white")
hot = True if cpu_voltage() == cpuMaxVoltage else False
draw_cpu(draw, hot, 0, 0)
draw.text((14, 0), cpu_percent(), font=font12, fill="white")
draw_ram(draw, ram_percent(), 40, 0)
draw.text((55, 0), "%.0f%%" % (ram_percent()), font=font12, fill="white")
draw.text((85, 0), hwmon(), font=font12, fill="white")
x=1
draw_usb(draw, True, 0, 14)
draw_usb(draw, False, 14, 14)
# draw.text((0, 14), "%.1fv" % (cpu_voltage()), font=font2, fill="white")
if device.height >= 64:
x=2
#draw.text((0, 26), disk_usage('/'), font=font2, fill="white")
try:
x=3
draw.text((0, 26), readVA(), font=font12, fill="white")
x=4
draw_wifi(draw, 0, 38)
draw.text((14, 38), network('wlx8c882b0000fa'), font=font12, fill="white")
except KeyError:
# no wifi enabled/available
pass
def main():
while True:
#read()
stats(device)
time.sleep(1)
# Check whether a watched file has changed.
# for f, mtime in WATCHED_FILES_MTIMES:
# if getmtime(f) != mtime:
# One of the files has changed, so restart the script.
# When running the script via `./daemon.py` (e.g. Linux/Mac OS), use
# os.execv(__file__, sys.argv)
# When running the script via `python daemon.py` (e.g. Windows), use
# os.execv(sys.executable, ['python'] + sys.argv)
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment