Hi! I'm making a list of software configuration/hacks to save power on the Odroid Go Super (possibly works on Odroid Go Advance too). If anyone has anything to add, please do so!~
Confirmed
(obvious) reduce/zero brightness of backlight. This saves a bit of power (or more, depending on your normal preferred brightness levels). Note: due to the type of screen, you will not be able to see anything at all once the backlight is off, unless you shine a super duper bright flashlight on a corner.
(not-so-obvious) disable audio (set playback path to OFF). This saves a suprisingly large amount of power. Volume is reset to max when you turn it back on (SPK, HP, SPK_HP), so be sure to save volume levels beforehand to restore!~
If anyone is using the oga_events.py hotkey daemon created by valadaa48, you can greatly reduce cpu usage of it by adding a small sleep of 0.001 to it. It reduced cpu usage from almost as high as 91 percent down to at most 28 percent since it would constantly read gamepad inputs. It doesn’t seem to impact the responsiveness of the script very much either. See the code below.
If anyone is using the oga_events.py hotkey daemon created by valadaa48, you can greatly reduce cpu usage of it by adding a small sleep of 0.001 to it. It reduced cpu usage from almost as high as 91 percent down to at most 28 percent since it would constantly read gamepad inputs. It doesn’t seem to impact the responsiveness of the script very much either. See the code below.
If anyone is using the oga_events.py hotkey daemon created by valadaa48, you can greatly reduce cpu usage of it by adding a small sleep of 0.001 to it. It reduced cpu usage from almost as high as 91 percent down to at most 28 percent since it would constantly read gamepad inputs. It doesn’t seem to impact the responsiveness of the script very much either. See the code below.
#!/usr/bin/env python3
import evdev
import asyncio
import time
from subprocess import check_output
pwrkey = evdev.InputDevice("/dev/input/event0")
odroidgo2_joypad = evdev.InputDevice("/dev/input/event2")
sound = evdev.InputDevice("/dev/input/event2")
brightness_path = "/sys/devices/platform/backlight/backlight/backlight/brightness"
max_brightness = int(open("/sys/devices/platform/backlight/backlight/backlight/max_brightness", "r").read())
class Power:
pwr = 116
class Joypad:
l1 = 310
r1 = 311
up = 544
down = 545
left = 546
right = 547
f1 = 704
f2 = 705
f3 = 709
def runcmd(cmd, *args, **kw):
print(f">>> {cmd}")
check_output(cmd, *args, **kw)
def brightness(direction):
with open(brightness_path, "r+") as f:
cur = int(f.read())
adj = max(1, int(cur * 0.13))
cur = max(0, min(cur + adj * direction, max_brightness))
f.seek(0, 0)
f.write(f"{cur}")
async def handle_event(device):
async for event in device.async_read_loop():
if device.name == "rk8xx_pwrkey":
keys = odroidgo2_joypad.active_keys()
if event.value == 1 and event.code == Power.pwr: # pwr
if Joypad.f3 in keys:
runcmd("/bin/systemctl poweroff || true", shell=True)
else:
runcmd("/bin/systemctl suspend || true", shell=True)
elif device.name == "GO-Advance Gamepad" or device.name == "GO-Super Gamepad":
keys = odroidgo2_joypad.active_keys()
#print(keys)
if event.value == 1 and Joypad.f3 in keys:
if event.code == Joypad.left:
runcmd("/usr/bin/amixer -q sset Playback 1%-", shell=True)
elif event.code == Joypad.right:
runcmd("/usr/bin/amixer -q sset Playback 1%+", shell=True)
elif event.code == Joypad.up:
brightness(1)
elif event.code == Joypad.down:
brightness(-1)
elif event.code == Joypad.l1:
runcmd("/usr/local/bin/perfnorm", shell=True)
elif event.code == Joypad.r1:
runcmd("/usr/local/bin/perfmax", shell=True)
time.sleep(0.001)
def run():
asyncio.ensure_future(handle_event(pwrkey))
asyncio.ensure_future(handle_event(odroidgo2_joypad))
asyncio.ensure_future(handle_event(sound))
loop = asyncio.get_event_loop()
loop.run_forever()
if __name__ == "__main__": # admire
run()
This code would run much better if it was written in C, as synchronous reads, which are easiest to do on event devices are perfect for this usecase
Ha, I wrote oga_events really quickly to get something going. I didn't think it would end up in so many spots, at least the name didn't get mangled =)
I think I will actually open source ogage as there's little sense in keeping it private, clones be damned!
It's written in rust and uses epoll. I don't know rust very well but in principle it's pretty low-pro and is prob how I would have implemented it in C. It uses ~0% cpu and I think like 2-4MB of mem.
If anyone is using the oga_events.py hotkey daemon created by valadaa48, you can greatly reduce cpu usage of it by adding a small sleep of 0.001 to it. It reduced cpu usage from almost as high as 91 percent down to at most 28 percent since it would constantly read gamepad inputs. It doesn’t seem to impact the responsiveness of the script very much either. See the code below.
#!/usr/bin/env python3
import evdev
import asyncio
import time
from subprocess import check_output
pwrkey = evdev.InputDevice("/dev/input/event0")
odroidgo2_joypad = evdev.InputDevice("/dev/input/event2")
sound = evdev.InputDevice("/dev/input/event2")
brightness_path = "/sys/devices/platform/backlight/backlight/backlight/brightness"
max_brightness = int(open("/sys/devices/platform/backlight/backlight/backlight/max_brightness", "r").read())
class Power:
pwr = 116
class Joypad:
l1 = 310
r1 = 311
up = 544
down = 545
left = 546
right = 547
f1 = 704
f2 = 705
f3 = 709
def runcmd(cmd, *args, **kw):
print(f">>> {cmd}")
check_output(cmd, *args, **kw)
def brightness(direction):
with open(brightness_path, "r+") as f:
cur = int(f.read())
adj = max(1, int(cur * 0.13))
cur = max(0, min(cur + adj * direction, max_brightness))
f.seek(0, 0)
f.write(f"{cur}")
async def handle_event(device):
async for event in device.async_read_loop():
if device.name == "rk8xx_pwrkey":
keys = odroidgo2_joypad.active_keys()
if event.value == 1 and event.code == Power.pwr: # pwr
if Joypad.f3 in keys:
runcmd("/bin/systemctl poweroff || true", shell=True)
else:
runcmd("/bin/systemctl suspend || true", shell=True)
elif device.name == "GO-Advance Gamepad" or device.name == "GO-Super Gamepad":
keys = odroidgo2_joypad.active_keys()
#print(keys)
if event.value == 1 and Joypad.f3 in keys:
if event.code == Joypad.left:
runcmd("/usr/bin/amixer -q sset Playback 1%-", shell=True)
elif event.code == Joypad.right:
runcmd("/usr/bin/amixer -q sset Playback 1%+", shell=True)
elif event.code == Joypad.up:
brightness(1)
elif event.code == Joypad.down:
brightness(-1)
elif event.code == Joypad.l1:
runcmd("/usr/local/bin/perfnorm", shell=True)
elif event.code == Joypad.r1:
runcmd("/usr/local/bin/perfmax", shell=True)
time.sleep(0.001)
def run():
asyncio.ensure_future(handle_event(pwrkey))
asyncio.ensure_future(handle_event(odroidgo2_joypad))
asyncio.ensure_future(handle_event(sound))
loop = asyncio.get_event_loop()
loop.run_forever()
if __name__ == "__main__": # admire
run()
This code would run much better if it was written in C, as synchronous reads, which are easiest to do on event devices are perfect for this usecase
Ha, I wrote oga_events really quickly to get something going. I didn't think it would end up in so many spots, at least the name didn't get mangled =)
I think I will actually open source ogage as there's little sense in keeping it private, clones be damned!
It's written in rust and uses epoll. I don't know rust very well but in principle it's pretty low-pro and is prob how I would have implemented it in C. It uses ~0% cpu and I think like 2-4MB of mem.
Thanks alot Val. Took me a little research to understand rust. You’re using a command named light in this program to control brightness but it doesn’t seem to exist in Ubuntu. Is it a program you create or a program that exist in Void?
A jack of all trades is a master of none, but oftentimes better than a master of one
If anyone is using the oga_events.py hotkey daemon created by valadaa48, you can greatly reduce cpu usage of it by adding a small sleep of 0.001 to it. It reduced cpu usage from almost as high as 91 percent down to at most 28 percent since it would constantly read gamepad inputs. It doesn’t seem to impact the responsiveness of the script very much either. See the code below.
#!/usr/bin/env python3
import evdev
import asyncio
import time
from subprocess import check_output
pwrkey = evdev.InputDevice("/dev/input/event0")
odroidgo2_joypad = evdev.InputDevice("/dev/input/event2")
sound = evdev.InputDevice("/dev/input/event2")
brightness_path = "/sys/devices/platform/backlight/backlight/backlight/brightness"
max_brightness = int(open("/sys/devices/platform/backlight/backlight/backlight/max_brightness", "r").read())
class Power:
pwr = 116
class Joypad:
l1 = 310
r1 = 311
up = 544
down = 545
left = 546
right = 547
f1 = 704
f2 = 705
f3 = 709
def runcmd(cmd, *args, **kw):
print(f">>> {cmd}")
check_output(cmd, *args, **kw)
def brightness(direction):
with open(brightness_path, "r+") as f:
cur = int(f.read())
adj = max(1, int(cur * 0.13))
cur = max(0, min(cur + adj * direction, max_brightness))
f.seek(0, 0)
f.write(f"{cur}")
async def handle_event(device):
async for event in device.async_read_loop():
if device.name == "rk8xx_pwrkey":
keys = odroidgo2_joypad.active_keys()
if event.value == 1 and event.code == Power.pwr: # pwr
if Joypad.f3 in keys:
runcmd("/bin/systemctl poweroff || true", shell=True)
else:
runcmd("/bin/systemctl suspend || true", shell=True)
elif device.name == "GO-Advance Gamepad" or device.name == "GO-Super Gamepad":
keys = odroidgo2_joypad.active_keys()
#print(keys)
if event.value == 1 and Joypad.f3 in keys:
if event.code == Joypad.left:
runcmd("/usr/bin/amixer -q sset Playback 1%-", shell=True)
elif event.code == Joypad.right:
runcmd("/usr/bin/amixer -q sset Playback 1%+", shell=True)
elif event.code == Joypad.up:
brightness(1)
elif event.code == Joypad.down:
brightness(-1)
elif event.code == Joypad.l1:
runcmd("/usr/local/bin/perfnorm", shell=True)
elif event.code == Joypad.r1:
runcmd("/usr/local/bin/perfmax", shell=True)
time.sleep(0.001)
def run():
asyncio.ensure_future(handle_event(pwrkey))
asyncio.ensure_future(handle_event(odroidgo2_joypad))
asyncio.ensure_future(handle_event(sound))
loop = asyncio.get_event_loop()
loop.run_forever()
if __name__ == "__main__": # admire
run()
This code would run much better if it was written in C, as synchronous reads, which are easiest to do on event devices are perfect for this usecase
Ha, I wrote oga_events really quickly to get something going. I didn't think it would end up in so many spots, at least the name didn't get mangled =)
I think I will actually open source ogage as there's little sense in keeping it private, clones be damned!
It's written in rust and uses epoll. I don't know rust very well but in principle it's pretty low-pro and is prob how I would have implemented it in C. It uses ~0% cpu and I think like 2-4MB of mem.
Thanks alot Val. Took me a little research to understand rust. You’re using a command named light in this program to control brightness but it doesn’t seem to exist in Ubuntu. Is it a program you create or a program that exist in Void?
I think light is a great app for controlling brightness and I use it on all of my systems including desktop and laptop. If you have trouble getting it compiled/added to Ubuntu you can always replace the commands with something else or even just read/write to the respective sys files.
These users thanked the author valadaa48 for the post:
Ha, I wrote oga_events really quickly to get something going. I didn't think it would end up in so many spots, at least the name didn't get mangled =)
I think I will actually open source ogage as there's little sense in keeping it private, clones be damned!
It's written in rust and uses epoll. I don't know rust very well but in principle it's pretty low-pro and is prob how I would have implemented it in C. It uses ~0% cpu and I think like 2-4MB of mem.
Give me a bit to clean it up and I'll post it.
EDIT: here you go https://github.com/valadaa48/ogage good luck and don't make fun of my rust code please
I wrote a quick and dirty program to convert from gamepad events to keyboard and mouse.
It uses almost no resources and is missing analog input support but it kinda works https://github.com/Maccraft123/joy2key/ ... /joy2key.c
The best thing is that I use sway to handle hotkeys xDD
If anyone is using the oga_events.py hotkey daemon created by valadaa48, you can greatly reduce cpu usage of it by adding a small sleep of 0.001 to it. It reduced cpu usage from almost as high as 91 percent down to at most 28 percent since it would constantly read gamepad inputs. It doesn’t seem to impact the responsiveness of the script very much either. See the code below.
#!/usr/bin/env python3
import evdev
import asyncio
import time
from subprocess import check_output
pwrkey = evdev.InputDevice("/dev/input/event0")
odroidgo2_joypad = evdev.InputDevice("/dev/input/event2")
sound = evdev.InputDevice("/dev/input/event2")
brightness_path = "/sys/devices/platform/backlight/backlight/backlight/brightness"
max_brightness = int(open("/sys/devices/platform/backlight/backlight/backlight/max_brightness", "r").read())
class Power:
pwr = 116
class Joypad:
l1 = 310
r1 = 311
up = 544
down = 545
left = 546
right = 547
f1 = 704
f2 = 705
f3 = 709
def runcmd(cmd, *args, **kw):
print(f">>> {cmd}")
check_output(cmd, *args, **kw)
def brightness(direction):
with open(brightness_path, "r+") as f:
cur = int(f.read())
adj = max(1, int(cur * 0.13))
cur = max(0, min(cur + adj * direction, max_brightness))
f.seek(0, 0)
f.write(f"{cur}")
async def handle_event(device):
async for event in device.async_read_loop():
if device.name == "rk8xx_pwrkey":
keys = odroidgo2_joypad.active_keys()
if event.value == 1 and event.code == Power.pwr: # pwr
if Joypad.f3 in keys:
runcmd("/bin/systemctl poweroff || true", shell=True)
else:
runcmd("/bin/systemctl suspend || true", shell=True)
elif device.name == "GO-Advance Gamepad" or device.name == "GO-Super Gamepad":
keys = odroidgo2_joypad.active_keys()
#print(keys)
if event.value == 1 and Joypad.f3 in keys:
if event.code == Joypad.left:
runcmd("/usr/bin/amixer -q sset Playback 1%-", shell=True)
elif event.code == Joypad.right:
runcmd("/usr/bin/amixer -q sset Playback 1%+", shell=True)
elif event.code == Joypad.up:
brightness(1)
elif event.code == Joypad.down:
brightness(-1)
elif event.code == Joypad.l1:
runcmd("/usr/local/bin/perfnorm", shell=True)
elif event.code == Joypad.r1:
runcmd("/usr/local/bin/perfmax", shell=True)
time.sleep(0.001)
def run():
asyncio.ensure_future(handle_event(pwrkey))
asyncio.ensure_future(handle_event(odroidgo2_joypad))
asyncio.ensure_future(handle_event(sound))
loop = asyncio.get_event_loop()
loop.run_forever()
if __name__ == "__main__": # admire
run()
This code would run much better if it was written in C, as synchronous reads, which are easiest to do on event devices are perfect for this usecase
Ha, I wrote oga_events really quickly to get something going. I didn't think it would end up in so many spots, at least the name didn't get mangled =)
I think I will actually open source ogage as there's little sense in keeping it private, clones be damned!
It's written in rust and uses epoll. I don't know rust very well but in principle it's pretty low-pro and is prob how I would have implemented it in C. It uses ~0% cpu and I think like 2-4MB of mem.
Thanks alot Val. Took me a little research to understand rust. You’re using a command named light in this program to control brightness but it doesn’t seem to exist in Ubuntu. Is it a program you create or a program that exist in Void?
I think light is a great app for controlling brightness and I use it on all of my systems including desktop and laptop. If you have trouble getting it compiled/added to Ubuntu you can always replace the commands with something else or even just read/write to the respective sys files.
So for Ubuntu, I ended up finding a similar app named brightnessctl that functions similarly. It works well with slight modification for ogage. Thanks again for open sourcing that. It's extremely light on resources and the learning curve for rust isn't too bad.