Skip to content

Commit

Permalink
Hibernate and Linux Power fixes (#110)
Browse files Browse the repository at this point in the history
  • Loading branch information
infeeeee authored May 18, 2024
1 parent ba2aa9f commit 2f5d1cc
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 25 deletions.
5 changes: 3 additions & 2 deletions IoTuring/Configurator/Configuration.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

from IoTuring.ClassManager.consts import KEY_ENTITY, KEY_WAREHOUSE, KEY_SETTINGS
from IoTuring.Exceptions.Exceptions import UnknownConfigKeyException

CONFIG_CLASS = {
KEY_ENTITY: "active_entities",
Expand Down Expand Up @@ -69,15 +70,15 @@ def GetConfigValue(self, config_key: str):
config_key (str): The key of the configuration
Raises:
ValueError: If the key is not found
UnknownConfigKeyException: If the key is not found
Returns:
The value of the key.
"""
if config_key in self.configurations:
return self.configurations[config_key]
else:
raise ValueError("Config key not set")
raise UnknownConfigKeyException(config_key)

def UpdateConfigValue(self, config_key: str, config_value: str) -> None:
"""Update the value of the configuration. Overwrites existing value
Expand Down
4 changes: 3 additions & 1 deletion IoTuring/Configurator/ConfiguratorObject.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from IoTuring.Configurator.MenuPreset import BooleanAnswers, MenuPreset
from IoTuring.Configurator.Configuration import SingleConfiguration, CONFIG_CLASS, CONFIG_KEY_TYPE
from IoTuring.Exceptions.Exceptions import UnknownConfigKeyException



class ConfiguratorObject:
Expand Down Expand Up @@ -30,7 +32,7 @@ def GetFromConfigurations(self, key):
if self.GetConfigurations().HasConfigKey(key):
return self.GetConfigurations().GetConfigValue(key)
else:
raise Exception("Can't find key " + key + " in configurations")
raise UnknownConfigKeyException(key)

def GetTrueOrFalseFromConfigurations(self, key) -> bool:
""" Get boolean value from confiugurations with key (if not present raise Exception) """
Expand Down
61 changes: 45 additions & 16 deletions IoTuring/Entity/Deployments/Power/Power.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
from IoTuring.Entity.Entity import Entity
from IoTuring.Entity.EntityData import EntityCommand
from IoTuring.Exceptions.Exceptions import UnknownConfigKeyException
from IoTuring.MyApp.SystemConsts import OperatingSystemDetection as OsD
from IoTuring.MyApp.SystemConsts import DesktopEnvironmentDetection as De
from IoTuring.Configurator.MenuPreset import MenuPreset


CONFIG_KEY_ENABLE_HIBERNATE = 'enable_hibernate'

KEY_SHUTDOWN = 'shutdown'
KEY_REBOOT = 'reboot'
KEY_SLEEP = 'sleep'
KEY_HIBERNATE = 'hibernate'

commands = {
OsD.WINDOWS: {
KEY_SHUTDOWN: 'shutdown /s /t 0',
KEY_REBOOT: 'shutdown /r',
KEY_SLEEP: 'rundll32.exe powrprof.dll,SetSuspendState 0,1,0'
KEY_SLEEP: 'rundll32.exe powrprof.dll,SetSuspendState 0,1,0',
KEY_HIBERNATE: 'rundll32.exe powrprof.dll,SetSuspendState Hibernate'

},
OsD.MACOS: {
KEY_SHUTDOWN: 'sudo shutdown -h now',
Expand All @@ -21,12 +28,19 @@
OsD.LINUX: {
KEY_SHUTDOWN: 'poweroff',
KEY_REBOOT: 'reboot',
KEY_SLEEP: 'systemctl suspend'
KEY_SLEEP: 'systemctl suspend',
KEY_HIBERNATE: 'systemctl hibernate'
}
}

linux_optional_sleep_commands = {
'X11': 'xset dpms force standby'
linux_commands = {
"gnome": {
KEY_SHUTDOWN: 'gnome-session-quit --power-off',
KEY_REBOOT: 'gnome-session-quit --reboot'
},
"X11": {
KEY_SLEEP: 'xset dpms force standby'
}
}


Expand All @@ -36,7 +50,15 @@ class Power(Entity):
def Initialize(self):
self.commands = {}

for command_key in [KEY_SHUTDOWN, KEY_REBOOT, KEY_SLEEP]:
command_keys = [KEY_SHUTDOWN, KEY_REBOOT, KEY_SLEEP]

try:
if self.GetTrueOrFalseFromConfigurations(CONFIG_KEY_ENABLE_HIBERNATE):
command_keys.append(KEY_HIBERNATE)
except UnknownConfigKeyException:
pass

for command_key in command_keys:
if command_key in commands[OsD.GetOs()]:
self.commands[command_key] = self.GetCommand(command_key)
self.RegisterEntityCommand(EntityCommand(
Expand Down Expand Up @@ -64,17 +86,14 @@ def GetCommand(self, command_key: str) -> str:

if OsD.IsLinux():

if command_key == KEY_SLEEP:
# Fallback to xset, if supported:
if not De.IsWayland():
try:
De.CheckXsetSupport()
command = linux_optional_sleep_commands['X11']
except Exception as e:
self.Log(self.LOG_DEBUG,
f'Xset not supported: {str(e)}')

else:
if De.IsXsetSupported() and command_key in linux_commands['X11']:
command = linux_commands['X11'][command_key]
elif De.GetDesktopEnvironment() in linux_commands \
and command_key in linux_commands[De.GetDesktopEnvironment()]:
command = linux_commands[De.GetDesktopEnvironment(
)][command_key]

elif not command.startswith("systemctl"):
# Try if command works without sudo, add if it's not working:
testcommand = command + " --wtmp-only"

Expand All @@ -86,6 +105,16 @@ def GetCommand(self, command_key: str) -> str:

return command

@classmethod
def ConfigurationPreset(cls) -> MenuPreset:
preset = MenuPreset()

if KEY_HIBERNATE in commands[OsD.GetOs()]:
preset.AddEntry("Enable hibernation",
CONFIG_KEY_ENABLE_HIBERNATE, default="N",
question_type="yesno")
return preset

@classmethod
def CheckSystemSupport(cls):
if OsD.GetOs() not in commands:
Expand Down
2 changes: 1 addition & 1 deletion IoTuring/Entity/Entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def GetEntitySensorByKey(self, key) -> EntitySensor:
sensor = next((s for s in self.entitySensors if s.GetKey() == key))
return sensor
except StopIteration:
raise UnknownEntityKeyException
raise UnknownEntityKeyException(key)

def GetEntityName(self) -> str:
""" Return entity name """
Expand Down
12 changes: 8 additions & 4 deletions IoTuring/Exceptions/Exceptions.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
class UnknownEntityKeyException(Exception):
def __init__(self, *args: object) -> None:
super().__init__(*args)
self.message = "This key isn't registered in any entity data"
def __init__(self, key: str) -> None:
super().__init__(f"Unknown entity key: {key}")


class UnknownConfigKeyException(Exception):
def __init__(self, key: str) -> None:
super().__init__(f"Configuration key not found: {key}")


class UserCancelledException(Exception):
Expand All @@ -13,4 +17,4 @@ def __init__(self, *args: object) -> None:
class UnknownLoglevelException(Exception):
def __init__(self, loglevel: str) -> None:
super().__init__(f"Unknown log level: {loglevel}")
self.loglevel = loglevel
self.loglevel = loglevel
10 changes: 9 additions & 1 deletion IoTuring/MyApp/SystemConsts/DesktopEnvironmentDetection.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,12 @@ def CheckXsetSupport() -> None:
elif not OsD.GetEnv('DISPLAY'):
raise Exception('No $DISPLAY environment variable!')


@staticmethod
def IsXsetSupported() -> bool:
if DesktopEnvironmentDetection.IsWayland():
return False
try:
DesktopEnvironmentDetection.CheckXsetSupport()
return True
except:
return False

0 comments on commit 2f5d1cc

Please sign in to comment.