distatus / battery

cross-platform, normalized battery information library
MIT License
249 stars 36 forks source link

Gomobile #3

Closed joeblew99 closed 4 years ago

joeblew99 commented 8 years ago

I wonder how easy it is to also do this on android ios ? Would be interesting to also see the effects on the code.

KenjiTakahashi commented 8 years ago

Yes, this is something I'd like to investigate as well. The problem is... I have neither Android, nor iOS devices at hand.

I've already tried using Android emulator, but it's driver does not return a valid battery info (just static percentage capacity). Hopefully that's just emulator thing and actual devices are doing this properly.

And the Xcode's iOS simulator is not ARM, which misses part of the point. Other than that, I've no idea how to get some kind of terminal interface in it. If you (or someone else) know how to get terminal or SSH server or sth like that in iOS simulator, please let me know.

joeblew99 commented 8 years ago

I have a nexus 6 so could test it.

The other way is to use the test services that run on real hardware. They are pretty good these days and quicker to work with than your own hardware. They often have free deals for low volume.

I really like programming for gomobile and gopherjs, but right now have zerotime

dmitshur commented 8 years ago

According to that "What every Browser knows about you" demo (see http://webkay.robinlinus.com/), browsers have APIs which expose battery information. For example:

image

The API is https://developer.mozilla.org/en-US/docs/Web/API/Battery_Status_API.

@KenjiTakahashi, would you be interested in a patch that adds support for (modern) browsers?

joeblew99 commented 8 years ago

I was thinking of the same thing. It would be gopherjs code ?

On Thu, 19 May 2016, 05:18 Dmitri Shuralyov, notifications@github.com wrote:

According to that "what your browser knows about you demo" (see http://webkay.robinlinus.com/ I think), browsers have APIs which expose battery information. For example:

[image: image] https://cloud.githubusercontent.com/assets/1924134/15381580/a790fb3c-1d35-11e6-8829-78ff234d0bec.png

@KenjiTakahashi https://github.com/KenjiTakahashi, would you be interested in a patch that adds support for (modern) browsers?

— You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub https://github.com/distatus/battery/issues/3#issuecomment-220218088

dmitshur commented 8 years ago

It would be Go code targetting js architecture, but it will need to use github.com/gopherjs/gopherjs/js package to access the browser's APIs, yes.

joeblew99 commented 8 years ago

Ah I use it myself also. :)

On Thu, 19 May 2016, 19:27 Dmitri Shuralyov, notifications@github.com wrote:

It would be Go code targetting js architecture, but it will need to use github.com/gopherjs/gopherjs/js https://godoc.org/github.com/gopherjs/gopherjs/js package to access the browser's APIs, yes.

— You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub https://github.com/distatus/battery/issues/3#issuecomment-220394840

KenjiTakahashi commented 8 years ago

I have played a bit with one of the services @joeblew99 suggested. It seems that Android should be doable with slightly adjusted Linux code. It uses the same API, but an older version (it seems) and file paths are a bit different. Maybe I'll try to hack sth in over the weekend, if I'll find enough time. iOS is more tricky, I'd like to get some kind of terminal there to see what's available, but I need to upload it as a app (.ipa file) and it can only be downloaded from AppStore using... iOS device. Dang Apple. But I'll find a way :-).

@shurcooL Today I learned :-). Anyway, I've looked at that browser API and it does not seem to provide any detailed info, such as wattage, only current level and timings. It does not really go well with the structure currently returned by battery. We could provide a separate API for the "browser side", but I am not convinced this is a good idea. I'm not saying no, though, any thoughts are appreciated.

joeblew99 commented 8 years ago

I hear you about IOS.

I don't have an ios device and so only targeted android so far.

Apple are so damn restrictive.

On Sat, 21 May 2016, 00:19 Karol Woźniak, notifications@github.com wrote:

I have played a bit with one of the services @joeblew99 https://github.com/joeblew99 suggested. It seems that Android should be doable with slightly adjusted Linux code. It uses the same API, but an older version (it seems) and file paths are a bit different. Maybe I'll try to hack sth in over the weekend, if I'll find enough time. iOS is more tricky, I'd like to get some kind of terminal there to see what's available, but I need to upload it as a app (.ipa file) and it can only be downloaded from AppStore using... iOS device. Dang Apple. But I'll find a way :-).

@shurcooL https://github.com/shurcooL Today I learned :-). Anyway, I've looked at that browser API and it does not seem to provide any detailed info, such as wattage, only current level and timings. It does not really go well with the structure currently returned by battery. We could provide a separate API for the "browser side", but I am not convinced this is a good idea. I'm not saying no, though, any thoughts are appreciated.

— You are receiving this because you were mentioned.

Reply to this email directly or view it on GitHub https://github.com/distatus/battery/issues/3#issuecomment-220732007

dmitshur commented 8 years ago

@shurcooL Today I learned :-). Anyway, I've looked at that browser API and it does not seem to provide any detailed info, such as wattage, only current level and timings. It does not really go well with the structure currently returned by battery. We could provide a separate API for the "browser side", but I am not convinced this is a good idea. I'm not saying no, though, any thoughts are appreciated.

You currently support quite a number of diverse systems:

It seems that this library attempts to generalize the information in a uniformly accessible format. I think it's very likely that sooner or later you'll run into a situation where at least one of the supported platforms cannot provide certain information about batteries (that most other platforms do support and you might want to expose).

I think it's a good idea to plan for that and come up with a way to expose partial information. I agree that providing a separate API for a specific platform is a bad idea. Instead, I'd rather see some ability to express that information X is unavailable (but Y and Z are available).

I still think it's helpful for battery to provide support for an additional platform, even if's only able to populate a subset of fields of Battery struct. It's also possible future additions/changes to that API would allow the implementation to fill in more of the fields.

I admit the main reason I'm offering to make a PR to add (modern) browser support is because I think it's cool, that way battery can support 7 platforms, and it's neat that browsers can support this, even if partially. I don't have a concrete use case for this information in mind at this time, but I've mentally bookmarked this library for whenever I need/want to access battery information in any of my Go code.

joeblew99 commented 8 years ago

I agree. Don't throw the baby out with the bath water as they say. The middle ground is good enough, and that's the best that's possible.

Personally I am excited by the idea that this library represents - Convergence and harmonisation to achieve commonalities across platforms.

I am building a platform that uses both gopherjs and gomobile at work. The long term payoffs are big in terms of development. Some examples are:

Data storage. Boltdb for all systems, with leveldb / indexdb for web. They are both kV stores that just need a harmonisation layer.

Notifications. Mobile OS, web, desktop.

Anyway you get the point. I guess I just wanted to say what I think here

On Sat, 21 May 2016, 06:20 Dmitri Shuralyov, notifications@github.com wrote:

@shurcooL https://github.com/shurcooL Today I learned :-). Anyway, I've looked at that browser API and it does not seem to provide any detailed info, such as wattage, only current level and timings. It does not really go well with the structure currently returned by battery. We could provide a separate API for the "browser side", but I am not convinced this is a good idea. I'm not saying no, though, any thoughts are appreciated.

You currently support quite a number of diverse systems:

  • Linux 2.6.39+
  • OS X 10.10+
  • Windows XP+
  • FreeBSD
  • DragonFlyBSD
  • NetBSD

It seems that this library attempts to generalize the information in a uniformly accessible format. I think it's very likely that sooner or later you'll run into a situation where at least one of the supported platforms cannot provide certain information about batteries (that most other platforms do support and you might want to expose).

I think it's a good idea to plan for that and come up with a way to expose partial information. I agree that providing a separate API for a specific platform is a bad idea. Instead, I'd rather see some ability to express that information X is unavailable (but Y and Z are available).

I still think it's helpful for battery to provide support for an additional platform, even if's only able to populate a subset of fields of Battery. It's also possible future additions/changes to that API would allow the implementation to fill in more of the fields.

I admit the main reason I'm offering to make a PR to add (modern) browser support is because I think it's cool, that way battery can support 7 platforms, and it's neat that browsers can support this, even if partially. I don't have a concrete use case for this information in mind at this time, but I've mentally bookmarked this library for whenever I need/want to access battery information in any of my Go code.

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/distatus/battery/issues/3#issuecomment-220757627

KenjiTakahashi commented 8 years ago

There already is a way to provide partial information, along with "partial errors". It's in the docs :-).

I understand the urge to support as much platforms as possible. That's why I already have OpenBSD, Solaris and Plan 9 VMs spun up to try bringing them in too.

The problem with the browser is that it's a layer (many layers, really) above the low-level OS APIs. It exposes state, percentage and (dis)charging time(s), most probably calculated from the lower level data. Of all this info, only "state" is currently reported by battery. I've made it this way, because all other values can be derived from the ones currently returned (e.g. charging time would be (Full - Current) / ChargeRate). We could expose such derived info as well. But then what about systems that expose both (it happens)? Should we go the "just return system info" route? Or the "be consistent" route, and calculate it the way shown above, while ignoring what the system tells us? With the latter, we now sometimes return, say percentage, as the system tells us and sometimes not really. Theoretically, it all should not matter, because the results would be the same. But such theory often does not go into practice all too well. Also, regardless of this, users now end up with two ways of obtaining the same end result.

dmitshur commented 8 years ago

[the browser] exposes state, percentage and (dis)charging time(s), most probably calculated from the lower level data. Of all this info, only "state" is currently reported by battery.

I see. I didn't realize only 1 field was a direct match. I thought it was more than that, as in you also exposed the percentage and (dis)charge time, but I see now those are meant to be calculated indirectly from the capacities and (dis)charge rates.

In that case, I'm okay to punt on adding browser support. I primarily wanted to do it because I thought it was a very close fit, but it's not. Thanks for considering it. :)

KenjiTakahashi commented 8 years ago

OK, I say lets wait and see. I will be implementing more systems, maybe there will be more occurrences of APIs that expose only higher level info. Then we can think how to solve this, having bigger picture. Maybe browser API will be extended at some point, too.

joeblew99 commented 8 years ago

Cool. :)

On Mon, 23 May 2016, 00:53 Karol Woźniak, notifications@github.com wrote:

OK, I say lets wait and see. I will be implementing more systems, maybe there will be more occurrences of APIs that expose only higher level info. Then we can think how to solve this, having bigger picture. Maybe browser API will be extended at some point, too.

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/distatus/battery/issues/3#issuecomment-220861633

LEI commented 7 years ago

I just stumbled on this issue; I am considering writing a wrapper around this library with colored output and formatting, plus support for Termux, which is a terminal emulator for Android (no root):

Could not retrieve battery info: `open /sys/class/power_supply: permission denied`

FYI, I will try to use the API add-on which provides the command termux-battery-status displaying basic battery information, probably thanks to the app permissions.

Here is the output:

{
    "health": "GOOD",
    "percentage": 100,
    "plugged": "UNPLUGGED",
    "status": "DISCHARGING",
    "temperature": 13.37
}
KenjiTakahashi commented 7 years ago

Hey @LEI, sorry for such a delay. Yeah, on Android, the actual files are stored somewhere else (don't remember anymore), if at all. I've investigated it earlier and it turns out that Google does not enforce implementing Linux's battery interface in any way. Therefore many HW manufacturers don't implement it or implement only a subset they want. There is a separate Java API provided by Google that's supposed to have reliable info from elsewhere. I planned to dig it to find where the elsewhere is. There were many things happening, so it got delayed more than I wanted, but hopefully I'll have some time for it soon.

Thanks for pointing me at the termux-api thing. I've looked in the code and it seems to be using aforementioned API. I hope that there's something below it that we could use, without calling a Java app.

KenjiTakahashi commented 7 years ago

Alright, I've looked a little bit more into this (and into Android sources). The Java API is reading info from the healthd daemon. The daemon in turn, reads most of the data from... /sys/class. So it is there, in the end. But not the whole Linux API is supported. For example, there's no energy_now, nor charge_now. Instead there's some dubious level value, which I don't yet know where it comes from.

As for the permission denied, @LEI, I think you're hitting this: https://code.google.com/p/android/issues/detail?id=208085

I've tested on Moto E 2nd (6.0) and Nexus 5X (7.1). On the former, I can read the data just fine, on the latter it crashes with the above error.

LEI commented 7 years ago

Hello @KenjiTakahashi, thank you for your investment in this nice library 👍 You can find my first attempt of wrapper here.

I am testing on OnePlus 3 (7.0), let me know if I can help.

KenjiTakahashi commented 4 years ago

I think it's time to put closure to this one. I've been investigating it on and off for a while. Conclusions are that: