Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upower module #82

Closed
p00f opened this issue Mar 17, 2023 · 10 comments · Fixed by #83
Closed

upower module #82

p00f opened this issue Mar 17, 2023 · 10 comments · Fixed by #83
Labels
enhancement New feature or request
Milestone

Comments

@p00f
Copy link
Contributor

p00f commented Mar 17, 2023

upower: https://upower.freedesktop.org/

can be used to listen to device events like charger connected/battery level changed instead of polling.
I want to implement this feature and am planning to use the upower-dbus crate

@p00f p00f added the enhancement New feature or request label Mar 17, 2023
@JakeStanger
Copy link
Owner

That'd be fantastic, a battery module is something I've been meaning to add to the backlog for some time. Go for it!

@p00f
Copy link
Contributor Author

p00f commented Mar 17, 2023

Thanks, this is what I have now: https://paste.sr.ht/~p00f/7061bf6067959b1c9b61f405665c9f377baed807

When I connect/disconnect the charger, the properties get printed on the terminal

{"BatteryLevel": OwnedValue(U32(1)), "HasHistory": OwnedValue(Bool(false)), "UpdateTime": OwnedValue(U64(1679089599)), "Capacity": OwnedValue(F64(0.0)), "Voltage": OwnedValue(F64(0.0)), "ChargeCycles": OwnedValue(I32(0)), "IconName": OwnedValue(Str(Str(Owned("battery-full-charging-symbolic")))), "Type": OwnedValue(U32(2)), "Serial": OwnedValue(Str(Str(Owned("")))), "PowerSupply": OwnedValue(Bool(true)), "EnergyEmpty": OwnedValue(F64(0.0)), "Energy": OwnedValue(F64(31.83)), "Model": OwnedValue(Str(Str(Owned("")))), "TimeToEmpty": OwnedValue(I64(0)), "HasStatistics": OwnedValue(Bool(false)), "Luminosity": OwnedValue(F64(0.0)), "WarningLevel": OwnedValue(U32(1)), "Percentage": OwnedValue(F64(78.0)), "TimeToFull": OwnedValue(I64(0)), "EnergyFull": OwnedValue(F64(40.46)), "IsRechargeable": OwnedValue(Bool(false)), "Online": OwnedValue(Bool(false)), "Technology": OwnedValue(U32(0)), "Vendor": OwnedValue(Str(Str(Owned("")))), "Temperature": OwnedValue(F64(0.0)), "EnergyFullDesign": OwnedValue(F64(0.0)), "IsPresent": OwnedValue(Bool(true)), "NativePath": OwnedValue(Str(Str(Owned("")))), "State": OwnedValue(U32(5)), "EnergyRate": OwnedValue(F64(0.0))}

This is a HashMap which has properties of the battery like percentage, time to full/empty, whether it is charging, etc

I'm having trouble implementing into_widget, can you help me here?

@p00f
Copy link
Contributor Author

p00f commented Mar 17, 2023

What are the associated types SendMessage and ReceiveMessage in the Module trait? I believe SendMessage is what the controller sends to the bar to draw? And then into_widget draws from the message whenever there is a message? Is that correct?

@JakeStanger
Copy link
Owner

JakeStanger commented Mar 17, 2023

So the separation of controller/widget is really there for organisation, rather than functionality (at the moment at least anyway). With the current implementation, you could actually technically get away with doing all the rendering in the controller, or all the logic in into_widget.

SendMessage is pretty much what you described. The idea is the controller sends data to the widget/popup, and this is the type used to denote that. into_widget isn't called every time you send a message, instead you need to use context.widget_rx and attach a callback to that. You can then do the necessary UI updates when you receive an update.

ReceiveMessage is used to send events from the UI back to the controller, for example when a button is clicked. The controller can listen to its rx to receive these and fire off any necessary logic (ie send command to client, run script...)

I'd recommend having a look at the clock module implementation as the simplest example. Although from your current implementation, it looks like you're pretty much there :)

@p00f
Copy link
Contributor Author

p00f commented Mar 17, 2023

Should the initial setup in spawn_controller be blocking or nonblocking (lines 36-44)?

I tried making everything nonblocking:
https://paste.sr.ht/~p00f/b6d7aa744218ae9466a5f96a2d89213db0c76a5c

but it crashed:
https://paste.sr.ht/~p00f/d373ae7c7fdaad64fdf1919534e05a80b009b7ca

@JakeStanger
Copy link
Owner

JakeStanger commented Mar 17, 2023

Non-blocking/async is preferable, as the controller runs on the main GTK thread, so will otherwise block the UI for all bars/widgets.

The channels will error if you try to send but there is no open receiver. If you stick:

context.widget_rx.attach(None, |_| Continue(true));

inside into_widget, it should resolve that error (I think). And then you can obvs add your logic inside the callback.

@p00f
Copy link
Contributor Author

p00f commented Mar 17, 2023

Nice, thanks

@JakeStanger JakeStanger linked a pull request Apr 22, 2023 that will close this issue
@JakeStanger JakeStanger added this to the 0.12.0 milestone Apr 22, 2023
@yavko
Copy link
Contributor

yavko commented May 1, 2023

I can't use the module and the docs don't appear on the wiki, I don't know why, and I'm on latest commit.
image

@JakeStanger
Copy link
Owner

I forgot to add the sidebar link on the wiki, that's there now. There's only two reasons I can see that it wouldn't show up there for you:

a) You're not actually on the latest commit
b) The feature flag is not enabled (it is by default, but I also forgot to stick this in the docs)

@yavko
Copy link
Contributor

yavko commented May 1, 2023

b) The feature flag is not enabled (it is by default, but I also forgot to stick this in the docs)

Wait, yeah that would be why...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants