2024-12-07 15:22:08 +01:00
import logging
import math
2024-12-09 17:01:38 +01:00
from threading import Thread , Timer
2024-12-07 15:22:08 +01:00
import bdfparser
2024-12-09 13:25:00 +01:00
from sense_hat . sense_hat import SenseHat
from sense_hat . stick import InputEvent
2024-12-07 15:22:08 +01:00
logger = logging . getLogger ( __name__ )
COLORS = {
2024-12-09 12:16:26 +01:00
" Bleu " : ( 0 , 0 , 255 ) ,
" Blanc " : ( 255 , 255 , 255 ) ,
" Rouge " : ( 255 , 0 , 0 ) ,
" Verte " : ( 0 , 127 , 31 ) ,
" Jaune " : ( 255 , 255 , 0 ) ,
" heat " : ( 255 , 0 , 0 ) ,
" heating " : ( 255 , 0 , 0 ) ,
" idle " : ( 127 , 0 , 255 ) ,
" off " : ( 127 , 127 , 127 ) ,
" on_setting " : ( 255 , 255 , 0 ) ,
" off_setting " : ( 255 , 255 , 255 ) ,
None : ( 0 , 0 , 0 ) ,
2024-12-07 15:22:08 +01:00
}
class Screen :
2024-12-09 12:16:26 +01:00
def __init__ ( self ) - > None :
2024-12-07 15:22:08 +01:00
self . sense = SenseHat ( )
self . _value = " "
self . _tmp = False
2024-12-09 12:16:26 +01:00
self . _tmp_value = " "
self . _mode = " "
2024-12-07 15:22:08 +01:00
self . font = bdfparser . Font ( " src/tom-thumb.bdf " )
2024-12-09 12:16:26 +01:00
self . _secondary : dict [ int , str ] = dict ( )
self . _secondary_pixels : list [ tuple [ int , int , int ] ] = [ ( 0 , 0 , 0 ) ] * 8
2024-12-07 15:22:08 +01:00
self . timer = Timer ( 0 , self . set_pixels )
2024-12-09 17:01:38 +01:00
self . auto_dim = AutoDim ( self . sense )
self . auto_dim . start ( )
2024-12-07 15:22:08 +01:00
self . _held = False
self . sense . stick . direction_middle = self . stick_click
2024-12-14 10:18:40 +01:00
self . sense . stick . direction_any = self . auto_dim . undim
2024-12-07 15:22:08 +01:00
@property
2024-12-09 12:16:26 +01:00
def value ( self ) - > None | str :
2024-12-07 15:22:08 +01:00
return self . _value
@value.setter
2024-12-09 12:16:26 +01:00
def value ( self , value : float ) - > None :
2024-12-07 15:22:08 +01:00
logger . debug ( f " Updated value: < { value } > " )
self . _value = format_value ( value )
if not self . _tmp :
self . set_pixels ( )
@property
2024-12-09 12:16:26 +01:00
def color ( self ) - > tuple [ int , int , int ] :
return COLORS . get ( self . mode , ( 0 , 0 , 0 ) )
2024-12-07 15:22:08 +01:00
@property
2024-12-09 12:16:26 +01:00
def mode ( self ) - > str :
2024-12-07 15:22:08 +01:00
return self . _mode
@mode.setter
2024-12-09 12:16:26 +01:00
def mode ( self , value : str ) - > None :
2024-12-07 15:22:08 +01:00
self . _mode = value
if not self . _tmp :
self . set_pixels ( )
@property
2024-12-09 12:16:26 +01:00
def tmp_value ( self ) - > None | str :
2024-12-07 15:22:08 +01:00
return self . _tmp_value
@tmp_value.setter
2024-12-09 12:16:26 +01:00
def tmp_value ( self , value : float ) - > None :
2024-12-07 15:22:08 +01:00
logger . debug ( f " Show value: < { value } > " )
self . timer . cancel ( )
self . _tmp_value = format_value ( value )
self . show_tmp ( )
2024-12-09 12:16:26 +01:00
def show_tmp ( self ) - > None :
2024-12-07 15:22:08 +01:00
self . _tmp = True
self . set_pixels (
self . tmp_value ,
color = COLORS . get ( " off_setting " if self . mode == " off " else " on_setting " ) ,
)
self . timer = Timer ( 3 , self . set_pixels )
self . timer . start ( )
2024-12-09 12:16:26 +01:00
def set_pixels (
self ,
value : str | None = None ,
color : tuple [ int , int , int ] | None = None ,
bg_color : tuple [ int , int , int ] = ( 0 , 0 , 0 ) ,
) - > None :
2024-12-07 15:22:08 +01:00
if value is None :
value = self . value
self . _tmp = False
if color is None :
color = self . color
if value :
2024-12-09 13:25:00 +01:00
pixels = [ color if x else bg_color for x in self . data_from_value ( value ) ]
2024-12-07 15:22:08 +01:00
else :
2024-12-09 12:16:26 +01:00
pixels = 48 * [ ( 0 , 0 , 0 ) ]
2024-12-07 15:22:08 +01:00
pixels + = self . secondary_pixels
self . sense . set_pixels ( pixels )
@property
2024-12-09 12:16:26 +01:00
def secondary ( self ) - > dict [ int , str ] :
2024-12-07 15:22:08 +01:00
return self . _secondary
@secondary.setter
2024-12-09 12:16:26 +01:00
def secondary ( self , value : dict [ int , str ] ) - > None :
2024-12-07 15:22:08 +01:00
self . _secondary = value
for idx in range ( 2 ) :
self . _secondary_pixels [ 4 * idx : 4 * ( idx + 1 ) ] = [
2024-12-09 12:16:26 +01:00
COLORS . get ( value . get ( idx , None ) , ( 0 , 0 , 0 ) )
2024-12-07 15:22:08 +01:00
] * 4
if not self . _tmp :
self . set_pixels ( )
2024-12-08 10:46:43 +01:00
@property
2024-12-09 12:16:26 +01:00
def secondary_pixels ( self ) - > list [ tuple [ int , int , int ] ] :
2024-12-08 10:46:43 +01:00
return self . _secondary_pixels
2024-12-09 12:16:26 +01:00
def stick_click ( self , event : InputEvent ) - > None :
2024-12-07 15:22:08 +01:00
match ( event . action , self . _held ) :
case ( " held " , False ) :
self . _held = True
case ( " released " , True ) :
self . _held = False
case ( " released " , False ) :
self . show_tmp ( )
2024-12-09 13:25:00 +01:00
case _ :
pass
def data_from_value ( self , value : str ) - > list [ int ] :
return self . font . draw ( value , mode = 0 ) . crop ( 8 , 7 ) . todata ( 3 )
2024-12-07 15:22:08 +01:00
2024-12-09 17:01:38 +01:00
class AutoDim ( Thread ) :
def __init__ ( self , sense : SenseHat ) :
super ( ) . __init__ ( )
self . daemon = True
self . sense = sense
self . dim = False
self . switching = False
self . sense . gamma_reset ( )
def run ( self ) - > None :
while True :
self . auto_dim ( )
def auto_dim ( self ) - > None :
accel_z = self . sense . get_accelerometer_raw ( ) [ " z " ]
2024-12-14 10:18:40 +01:00
if not self . switching and accel_z < 0.2 :
2024-12-09 17:01:38 +01:00
self . switching = True
self . dim = not self . dim
2024-12-14 10:18:40 +01:00
elif self . switching and accel_z > 0.9 :
2024-12-09 17:01:38 +01:00
self . switching = False
@property
def dim ( self ) - > bool :
return self . _dim
@dim.setter
def dim ( self , value : bool ) - > None :
if value :
self . sense . gamma = [ 0 ] * 32
else :
self . sense . gamma_reset ( )
self . _dim = value
2024-12-14 10:18:40 +01:00
def undim ( self ) - > None :
self . dim = False
2024-12-09 17:01:38 +01:00
2024-12-09 12:16:26 +01:00
def format_value ( value : float ) - > str :
2024-12-07 15:22:08 +01:00
v = math . trunc ( value )
d = " . " if ( value - v ) > = 0.5 else " "
return f " { v } { d } "