-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathicons.py
117 lines (104 loc) · 4.12 KB
/
icons.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# Copyright (C) 2023 Salvatore Sanfilippo <[email protected]>
# All Rights Reserved
#
# This code is released under the BSD 2 clause license.
# See the LICENSE file for more information
from font4x6 import *
import time, urandom
# This class shows status icons on the display. It is called every
# time the current view is refreshed, at the end, so it should assume
# that a view was already drawn and should only operate on the pixels
# related to the icons.
class StatusIcons:
def __init__(self, display, get_batt_perc):
self.display = display
self.xres = 128
self.yres = 64
self.get_batt_perc = get_batt_perc # Method to get battery percentage
self.last_batt_perc = 0
self.show = {}
self.show['ack'] = False # Show ACK received icon if !False
self.show['relay'] = False # Show packet relayed icon !False
self.icons_ttl = 5 # Turn icons off after N seconds
# Set to True / False to show/hide ACK icon.
def set_ack_visibility(self,new):
self.show['ack'] = time.time() if new else False
# Set to True / False to show/hide relay icon.
def set_relay_visibility(self,new):
self.show['relay'] = time.time() if new else False
# Display the battery icon, that is built on the
# following model. There are a total of 10 pixels to
# fill, so each horizontal pixel is 10% of battery.
#..............
#.##########...
#.#xxxxxxxxx##.
#.#xxxxxxxxxx#.
#.#xxxxxxxxx##.
#.##########...
#..............
def draw_battery(self):
self.last_batt_perc = self.get_batt_perc()
px = self.xres-14+self.xoff
py = 0+self.yoff
self.display.fill_rect(0+px,0+py,14,7,0)
self.display.fill_rect(1+px,1+py,12,5,1)
self.display.pixel(11+px,1+py,0)
self.display.pixel(12+px,1+py,0)
self.display.pixel(11+px,5+py,0)
self.display.pixel(12+px,5+py,0)
self.display.pixel(11+px,3+py,0)
self.display.fill_rect(2+px,2+py,9,3,0)
full_pixel = round(self.last_batt_perc/10)
self.display.fill_rect(2+px,2+py,full_pixel,3,1)
def draw_ack_icon(self):
px = self.xres-8+self.xoff
py = 10+self.yoff
self.display.fill_rect(px,py,8,9,1)
self.display.text("A",px,py+1,0)
def draw_relay_icon(self):
px = self.xres-8+self.xoff
py = 22+self.yoff
self.display.fill_rect(px,py,8,9,1)
self.display.text("R",px,py+1,0)
# Return the minimum refresh time of the status icons
# in seconds, depending on what is enabled right now:
def min_refresh_time(self):
# If at least a status icon is enabled right now, better
# to refresh the display every second.
for icon in self.show:
if self.show[icon]: return 1
# If it's just the battery, it is unlikely that it
# changes much before one minute.
return 60
# Update the screen content. If 'random_offset' is True, we are in
# screensaver mode and the icons should be displayed at random locations.
def refresh(self,random_offset=False):
if not self.display: return
if random_offset:
self.xoff = urandom.randint(-(self.xres-10),0)
self.yoff = urandom.randint(0,self.yres-20)
else:
self.xoff = 0
self.yoff = 0
self.draw_battery()
# Turn off icons that timed out.
for icon in self.show:
if self.show[icon]:
age = time.time() - self.show[icon]
if age > self.icons_ttl: self.show[icon] = False
if self.show['ack']: self.draw_ack_icon()
if self.show['relay']: self.draw_relay_icon()
self.display.show()
# Test code
if __name__ == "__main__":
import ssd1306, time
from machine import Pin, SoftI2C
def get_batt_perc_test():
return 100
i2c = SoftI2C(sda=Pin(21),scl=Pin(22))
display = ssd1306.SSD1306_I2C(128, 64, i2c)
display.poweron()
icons = StatusIcons(display,get_batt_perc=get_batt_perc_test)
icons.set_ack_visibility(True)
icons.set_relay_visibility(True)
icons.refresh()