10
10
import jukebox .publishing
11
11
import jukebox .speaking_text
12
12
from jukebox .multitimer import GenericEndlessTimerClass
13
- import socket
14
13
15
14
logger = logging .getLogger ('jb.host.lnx' )
16
15
cfg = jukebox .cfghandler .get_handler ('jukebox' )
17
16
# Get the main Thread Publisher
18
17
publisher = jukebox .publishing .get_publisher ()
19
18
20
- # This is a slightly dirty way of checking if we are on an RPi
21
- # JukeBox installs the dependency RPI which has no meaning on other machines
22
- # If it does not exist all is clear
23
- # It could still be installed, which results in a RuntimeError when loaded on a PC
24
- try :
25
- import RPi .GPIO as gpio # noqa: F401
26
-
27
- IS_RPI = True
28
- except ModuleNotFoundError :
29
- IS_RPI = False
30
- except RuntimeError as e :
31
- logger .info (f"You don't seem to be on a PI, because loading 'RPi.GPIO' failed: { e .__class__ .__name__ } : { e } " )
32
- IS_RPI = False
33
-
34
19
# In debug mode, shutdown and reboot command are not actually executed
35
20
IS_DEBUG = False
36
21
try :
@@ -302,73 +287,60 @@ def start_autohotspot():
302
287
return 'not-installed'
303
288
304
289
305
- @plugin .initialize
306
- def initialize ():
307
- wlan_power = cfg .setndefault ('host' , 'wlan_power' , 'disable_power_down' , value = True )
308
- card = cfg .setndefault ('host' , 'wlan_power' , 'card' , value = 'wlan0' )
309
- if wlan_power :
310
- wlan_disable_power_down (card )
290
+ # ---------------------------------------------------------------------------
291
+ # RPi-only stuff
292
+ # ---------------------------------------------------------------------------
293
+ THROTTLE_CODES = {
294
+ 0x1 : "under-voltage detected" ,
295
+ 0x2 : "ARM frequency capped" ,
296
+ 0x4 : "currently throttled" ,
297
+ 0x8 : "soft temperature limit active" ,
298
+ 0x10000 : "under-voltage has occurred" ,
299
+ 0x20000 : "ARM frequency capped has occurred" ,
300
+ 0x40000 : "throttling has occurred" ,
301
+ 0x80000 : "soft temperature limit has occurred"
302
+ }
311
303
312
304
313
- @plugin .finalize
314
- def finalize ():
315
- global timer_temperature
316
- enabled = cfg .setndefault ('host' , 'publish_temperature' , 'enabled' , value = True )
317
- wait_time = cfg .setndefault ('host' , 'publish_temperature' , 'timer_interval_sec' , value = 5 )
318
- timer_temperature = GenericEndlessTimerClass ('host.timer.cputemp' , wait_time , publish_cpu_temperature )
319
- timer_temperature .__doc__ = "Endless timer for publishing CPU temperature"
320
- # Note: Since timer_temperature is an instance of a class from a different module,
321
- # auto-registration would register it with that module. Manually set package to this plugin module
322
- plugin .register (timer_temperature , name = 'timer_temperature' , package = plugin .loaded_as (__name__ ))
323
- if enabled :
324
- publish_cpu_temperature ()
325
- timer_temperature .start ()
326
-
305
+ def command_exists (command ):
306
+ ret = shutil .which (command )
307
+ return ret is not None
327
308
328
- @plugin .atexit
329
- def atexit (** ignored_kwargs ):
330
- global timer_temperature
331
- timer_temperature .cancel ()
332
- return timer_temperature .timer_thread
333
309
310
+ @plugin .register
311
+ def hdmi_power_down ():
312
+ """Power down HDMI circuits to save power if no display is connected
334
313
335
- # ---------------------------------------------------------------------------
336
- # RPi-only stuff
337
- # ---------------------------------------------------------------------------
338
- if IS_RPI : # noqa: C901
339
-
340
- THROTTLE_CODES = {
341
- 0x1 : "under-voltage detected" ,
342
- 0x2 : "ARM frequency capped" ,
343
- 0x4 : "currently throttled" ,
344
- 0x8 : "soft temperature limit active" ,
345
- 0x10000 : "under-voltage has occurred" ,
346
- 0x20000 : "ARM frequency capped has occurred" ,
347
- 0x40000 : "throttling has occurred" ,
348
- 0x80000 : "soft temperature limit has occurred"
349
- }
350
-
351
- @plugin .register
352
- def hdmi_power_down ():
353
- """Power down HDMI circuits to save power if no display is connected
354
-
355
- This must be done after every reboot"""
314
+ This must be done after every reboot"""
315
+ success = False
316
+ commandname = "tvservice"
317
+ if command_exists (commandname ):
356
318
logger .info ('Power down HDMI circuits' )
357
- ret = subprocess .run (['sudo' , '/usr/bin/tvservice' , '-o' ],
358
- stdout = subprocess .PIPE , stderr = subprocess .STDOUT , check = False )
319
+ ret = subprocess .run (['sudo' , commandname , '-o' ],
320
+ stdout = subprocess .PIPE , stderr = subprocess .STDOUT , check = False )
359
321
if ret .returncode != 0 :
360
322
logger .error (f"{ ret .stdout } " )
323
+ else :
324
+ success = True
325
+ else :
326
+ logger .info ('Power down HDMI not available on this system' )
361
327
362
- def filter_throttle_codes (code ):
363
- for error , msg in THROTTLE_CODES .items ():
364
- if code & error > 0 :
365
- yield msg
328
+ return success
366
329
367
- @plugin .register
368
- def get_throttled ():
330
+
331
+ def filter_throttle_codes (code ):
332
+ for error , msg in THROTTLE_CODES .items ():
333
+ if code & error > 0 :
334
+ yield msg
335
+
336
+
337
+ @plugin .register
338
+ def get_throttled ():
339
+ commandname = "vcgencmd"
340
+ if command_exists (commandname ):
369
341
# https://www.raspberrypi.org/documentation/computers/os.html#get_throttled
370
- ret = subprocess .run (['sudo' , 'vcgencmd' , 'get_throttled' ],
371
- stdout = subprocess .PIPE , check = False )
342
+ ret = subprocess .run (['sudo' , commandname , 'get_throttled' ],
343
+ stdout = subprocess .PIPE , check = False )
372
344
if ret .returncode != 0 :
373
345
status_string = f"Error in subprocess with code: { ret .returncode } "
374
346
logger .error (status_string )
@@ -384,11 +356,44 @@ def get_throttled():
384
356
else :
385
357
# Decode the bit array after we have handled all the possible exceptions
386
358
status_string = "Warning: " + ', ' .join (filter_throttle_codes (status_code ))
359
+ else :
360
+ logger .info ('Throttled state not available on this system' )
361
+ status_string = "Not available"
362
+
363
+ return status_string
364
+
365
+
366
+ # ---------------------------------------------------------------------------
367
+ # Init
368
+ # ---------------------------------------------------------------------------
369
+ @plugin .initialize
370
+ def initialize ():
371
+ wlan_power = cfg .setndefault ('host' , 'wlan_power' , 'disable_power_down' , value = True )
372
+ card = cfg .setndefault ('host' , 'wlan_power' , 'card' , value = 'wlan0' )
373
+ if wlan_power :
374
+ wlan_disable_power_down (card )
375
+ hdmi_off = cfg .setndefault ('host' , 'rpi' , 'hdmi_power_down' , value = False )
376
+ if hdmi_off :
377
+ hdmi_power_down ()
378
+
379
+
380
+ @plugin .finalize
381
+ def finalize ():
382
+ global timer_temperature
383
+ enabled = cfg .setndefault ('host' , 'publish_temperature' , 'enabled' , value = True )
384
+ wait_time = cfg .setndefault ('host' , 'publish_temperature' , 'timer_interval_sec' , value = 5 )
385
+ timer_temperature = GenericEndlessTimerClass ('host.timer.cputemp' , wait_time , publish_cpu_temperature )
386
+ timer_temperature .__doc__ = "Endless timer for publishing CPU temperature"
387
+ # Note: Since timer_temperature is an instance of a class from a different module,
388
+ # auto-registration would register it with that module. Manually set package to this plugin module
389
+ plugin .register (timer_temperature , name = 'timer_temperature' , package = plugin .loaded_as (__name__ ))
390
+ if enabled :
391
+ publish_cpu_temperature ()
392
+ timer_temperature .start ()
387
393
388
- return status_string
389
394
390
- @plugin .initialize
391
- def rpi_initialize ( ):
392
- hdmi_off = cfg . setndefault ( 'host' , 'rpi' , 'hdmi_power_down' , value = False )
393
- if hdmi_off :
394
- hdmi_power_down ()
395
+ @plugin .atexit
396
+ def atexit ( ** ignored_kwargs ):
397
+ global timer_temperature
398
+ timer_temperature . cancel ()
399
+ return timer_temperature . timer_thread
0 commit comments