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

Virtual ambiance light indicator device #6

Closed
nick87720z opened this issue Jul 11, 2018 · 31 comments
Closed

Virtual ambiance light indicator device #6

nick87720z opened this issue Jul 11, 2018 · 31 comments

Comments

@nick87720z
Copy link

While there are already existing tools to control backlight (usually in DE settings), color temperature (redshift, f.lux), dpms and dimming (also both DE settings, more likely in power-man part), and even some integration with ambiant light sensors (i found mention, that gnome automatically uses it to adjust brightness, if such sensor found), there are only lack of something to use webcam as light sensor.

Having some virtual device, which actually gets brightness from software, instead of hardware, would allow to things to work in more standard way. Virtual device may have input, either for video buffer (so, module itself does all calculation for final brightness value) or light level itself (i.e., userspace daemon calculates value by own, and uses virtual device only to submit results).

Probably, second variant looks more desirable, as daemon would be needed anyway, to do input.

@nick87720z nick87720z changed the title Virtual ambiance light indicator Virtual ambiance light indicator device Jul 11, 2018
@FedeDP
Copy link
Owner

FedeDP commented Jul 11, 2018

I don't understand your request...clightd already has a dbus API to set monitor backlight.
It also offers a way to get ambient brightness from webcam, obviously.
Even if clightd has been developed as a backend for clight, it offers a nice API that everyone is free to use (without clight obviously). In fact, clightd README offers a simple example of a stupid (and stupidly simple) clight implementation in bash-like pseudocode:

$ ambient_br = busctl call org.clightd.backlight /org/clightd/backlight org.clightd.backlight captureframes "si" "" 5
$ avg_br_percent = compute_avg(ambient_br, 5)
$ busctl call org.clightd.backlight /org/clightd/backlight org.clightd.backlight setallbrightness "d(bdu)s" $(avg_br_percent) 1 0.05 80 ""

@FedeDP
Copy link
Owner

FedeDP commented Aug 25, 2018

Closing as reporter did not answer back. Feel free to reopen the issue.

@FedeDP FedeDP closed this as completed Aug 25, 2018
@nick87720z
Copy link
Author

Sorry for slow reply, i just was in trouble with finding answer.
I currently can't test clight, as ubuntu laptop, i did configurations on, is unreachable - i had it for some time to setup&configure, while my system uses openrc.

Though writing dedicated guis for clight is possible (and even wanted by those, who know clight), meanwhile brightness controll and virtual light sensor could be separate as well. For now DE's own brightness control has to be disabled in order to let clight brightness module run (it is probably not good idea to let different powermanagers interfere).
Btw - it seems, there is no need to make separate daemon for camera light sensor itself. It may be just another clightd module - e.g. "lightsensor". When both brightness and lightsensor are loaded, they are interacting as now (or as other modules do, if they do it).

At the same time lightsensor module may send lightness values as input for virtual device module... i'm only unsure, is there some dummy/testing driver for that (i only know, there are testing drivers for various device types).

@FedeDP
Copy link
Owner

FedeDP commented Aug 26, 2018

I'm not sure i understood it :) I'll try to answer!

Btw - it seems, there is no need to make separate daemon for camera light sensor itself. It may be just another clightd module - e.g. "lightsensor". When both brightness and lightsensor are loaded, they are interacting as now (or as other modules do, if they do it).

Separate daemons are needed as:

  1. Clightd only must be run by root
  2. Clightd is a Bus Interface that can be used from every program, it is not clight-only
  3. Clight must be run by each user (if you have a multi-user setup, may be some user wants clight and some other does not)

For now DE's own brightness control has to be disabled in order to let clight brightness module run (it is probably not good idea to let different powermanagers interfere).

My long-term idea/hope is to convert these DEs features to directly use clightd. I know it seems impossible right now though.

Though writing dedicated guis for clight is possible (and even wanted by those, who know clight)

Hopefully, as soon as i find time, a dbus API to query clight status and enable/disable modules is in clight todo. This way, creating a GUI should be quite simple.

@FedeDP FedeDP reopened this Aug 26, 2018
@nick87720z
Copy link
Author

Ah, now i understood goals.

My long-term idea/hope is to convert these DEs features to directly use clightd. I know it seems impossible right now though.

Then it would need support for all kinds of hardware sensors.

Btw - it seems, there is no need to make separate daemon for camera light sensor itself. It may be just another clightd module - e.g. "lightsensor". When both brightness and lightsensor are loaded, they are interacting as now (or as other modules do, if they do it).

I did not mean separation between root/user parts. I meaned rather further separation of brightness module, moving camera2lightness calc module to separate module...
...But of course, it would make sence only when there is driver for loopback light sensor device, which e.g. takes value as input (special testing interface) and provides it as current lightness. May be it is testing driver... anyway, it needs to be found yet.

@FedeDP
Copy link
Owner

FedeDP commented Aug 26, 2018

Ok i now understand.

I meaned rather further separation of brightness module, moving camera2lightness calc module to separate module...

Yes, this may be correct (and a nice extension of clight features): clight will then have a "webcam driver" and may be any other "X source driver", where "X source" can be any other hardware, like an ambient sensor.
Then, brightness module (probably better called "backlight" module) will only receive an input value without knowing where it comes from (ie: from which hardware device), and set accordingly screen brightness.

I see a couple of issues, though:

  1. ambient light sensors shipped with laptops probably already do everything (backlight changing too) in their driver
  2. i don't own any external ambient light sensor (do they even exist?) and i fear their kernel-support is not very good. Moreover i don't even know if there is an unified interface (eg: udev) to check their output.
  3. Another sensor could be a connected smartphone. But again, i don't know if and how we can access camera (or phone ambient light sensor) from a pc application.

It would be great though, but it is probably a huge amount of work that i'm not willing to do right now.

@nick87720z
Copy link
Author

nick87720z commented Aug 26, 2018

i don't own any external ambient light sensor (do they even exist?)

Today i discovered about ColorHug ALS, which is usb dongle light sensor.
https://blogs.gnome.org/hughsie/2015/03/17/introducing-colorhug-als/
My wish as well :)

@FedeDP
Copy link
Owner

FedeDP commented Aug 26, 2018

Very cool thanks for the info!

@FedeDP
Copy link
Owner

FedeDP commented Aug 27, 2018

@nick87720z By the way, as it seems you are really interested in clight/clightd (at least i hope!); are you by chance a developer?
Once proper clight bus interface is ready (i am currently working on it) are you willing to write a plasma5 applet for it (or a gnome extension, i don't know what DE you are using :D )?
I think it won't be a huge work, but i won't probably do that as i already fail to keep up with my own projects sadly...
It would be a great help for me and the project :)

@nick87720z
Copy link
Author

It is rather hobby now. I don't feel self very performant for now :)
Yep, i could eventually try applets for several gtk-based panels i have installed (made some short contrib to vala-panel-appmenu).

Btw, for example about root part: I looked to xfce4-power-manager files layout, there are only two helpers /usr/sbin/xfce4-pm-helper and /usr/sbin/xfpm-power-backlight-helper, but they are not runing at least some time.

@FedeDP
Copy link
Owner

FedeDP commented Sep 1, 2018

It is rather hobby now. I don't feel self very performant for now :)
Yep, i could eventually try applets for several gtk-based panels i have installed (made some short contrib to vala-panel-appmenu).

It would be great if you feel :)
Btw you can follow my bus interface work on clight bus_interface branch.
Note that next clight release will already ship bus interface!

@beret
Copy link

beret commented Sep 15, 2018

Edit: If I should just split this into a different issue just let me know!

I'm really interested in generic light sensing sources for Clight/Clightd, since my device has a simple accessible ambient light sensor, and a pain of a camera. None of this answers the question about external ambient light sensors, but there is a unified api for ACPI ones at least, and I would love to be able to use that with Clight.

It appears there is a standard kernel sysfs ACPI 0008 device for getting ambient illuminance: https://cateee.net/lkddb/web-lkddb/ACPI_ALS.html
Some of the original patches and kernel mailing list messages are here:
https://github.com/seidler2547/linux-acpi-als
https://lwn.net/Articles/345647/

It shows up on my MacBookAir 6,2 as

/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0c/ACPI0008:00/iio:device0/in_illuminance_input
/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0c/ACPI0008:00/iio:device0/in_illuminance_raw

Both return the same values for me, but input can be subject to some correction and normalization supposedly? (See below IIO docs.) _raw is supposedly raw, but still converted into Lux/SI. This may just be duplicate data because the original patch appears to have been converted to the IIO ABI later on. I get a range from 0 to 4095 on my hardware, with aliasing/stepping for the intermediate values due to the underlying sensor having less detail.

There are also vendor specific paths which return the sensor data as reported, one on my device is: /sys/devices/platform/applesmc.768/light with a max reading of (255,0) and a minimum reading of (0,0)

These docs are general about the iio (Industrial I/O) ABI, rather than the specific ACPI device output. They do includes some of the in_illumninance_[raw,input] paths, so mildly helpful about interactions?
https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-bus-iio
https://www.kernel.org/doc/html/v4.15/driver-api/iio/core.html

@FedeDP
Copy link
Owner

FedeDP commented Sep 15, 2018

I think the proper way to achieve this is to add a new "capture_light" method to clightd API, and then let clight use proper method (capture_frames or capture_light) based upon device specified in its config file.
Or something like that.

I'll obviously need your help though as i cannot test anything :)

Can you share me your: $ udevadm info /sys/class/als/als0008 -a --root? If "0008" does not exist, check your als number!

@FedeDP FedeDP self-assigned this Sep 15, 2018
@beret
Copy link

beret commented Sep 15, 2018

i had to change the path since /sys/class/als doesn't exist any more. It looks like it's just an ACPI part.

For the uvevadm output I went another layer deeper to the iio device0 folder that has the sensor files (in_illuminance_input, etc)

Paths: /sys/bus/acpi/devices/ACPI0008\:00
/sys/bus/acpi/drivers/acpi_als/ACPI0008\:00

# udevadm info /sys/bus/acpi/drivers/acpi_als/ACPI0008\:00/iio\:device0/ -a --root

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0c/ACPI0008:00/iio:device0':
    KERNEL=="iio:device0"
    SUBSYSTEM=="iio"
    DRIVER==""
    ATTR{in_illuminance_input}=="0"
    ATTR{in_illuminance_raw}=="0"
    ATTR{name}=="acpi-als"

  looking at parent device '/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0c/ACPI0008:00':
    KERNELS=="ACPI0008:00"
    SUBSYSTEMS=="acpi"
    DRIVERS=="acpi_als"
    ATTRS{hid}=="ACPI0008"
    ATTRS{path}=="\_SB_.PCI0.LPCB.ALS0"
    ATTRS{status}=="15"

  looking at parent device '/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0c':
    KERNELS=="device:0c"
    SUBSYSTEMS=="acpi"
    DRIVERS==""
    ATTRS{adr}=="0x001f0000"
    ATTRS{path}=="\_SB_.PCI0.LPCB"

  looking at parent device '/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00':
    KERNELS=="PNP0A08:00"
    SUBSYSTEMS=="acpi"
    DRIVERS==""
    ATTRS{adr}=="0x00000000"
    ATTRS{hid}=="PNP0A08"
    ATTRS{path}=="\_SB_.PCI0"
    ATTRS{uid}=="0"

  looking at parent device '/devices/LNXSYSTM:00/LNXSYBUS:00':
    KERNELS=="LNXSYBUS:00"
    SUBSYSTEMS=="acpi"
    DRIVERS==""
    ATTRS{hid}=="LNXSYBUS"
    ATTRS{path}=="\_SB_"

  looking at parent device '/devices/LNXSYSTM:00':
    KERNELS=="LNXSYSTM:00"
    SUBSYSTEMS=="acpi"
    DRIVERS==""
    ATTRS{hid}=="LNXSYSTM"
    ATTRS{path}=="\"

For reference:
Arch: Linux hostname 4.14.69-1-lts #1 SMP Mon Sep 10 16:59:09 CEST 2018 x86_64 GNU/Linux

@FedeDP
Copy link
Owner

FedeDP commented Sep 15, 2018

Very nice, thanks!

i had to change the path since /sys/class/als doesn't exist any more.

Very unfortunate :(

Most important things i note in your output:

ATTR{in_illuminance_input}=="0"
ATTR{in_illuminance_raw}=="0"

Is this ok? I mean they are both 0...
Can you test with this small sample: http://codepad.org/Eim0iwBe .
Compile with gcc sample.c -o sample -ludev.
Thanks!

@beret
Copy link

beret commented Sep 15, 2018

No worries, that's correct and reflects the reading of my sensor. I was in a dark room and I have a sticker that covers the camera/ALS. It is responsive when I add light.

It also looks like the ACPI readings are not a direct conversion of the applesmc.768 readings.
The ACPI readings are better and more precise. (I can see 18 lux with camera covered in indoor daylight, and 0 with my finger fully covering the sensor. Both of those are just (0,0) when reading applesmc)

Readings appear to be accurate enough (compared with Wikipedia Lux chart)
First reading is uncovered camera facing a window with morning light, then with the sticker covering the camera, then fully blocked.

$ ./sample 
Name: acpi-als
Illuminance raw: 262
Illuminance input: 262
$ ./sample 
Name: acpi-als
Illuminance raw: 18
Illuminance input: 18
$ ./sample 
Name: acpi-als
Illuminance raw: 0
Illuminance input: 0

@FedeDP
Copy link
Owner

FedeDP commented Sep 15, 2018

That's great! Shouldn't max value be 255 though?
As clightd returns percentage of current luminance/max luminance, I must be sure that max luminance level(I am assuming 255 is the correct maximum and that 262 is a small "bug") is the same across different hardwares.

@beret
Copy link

beret commented Sep 15, 2018

The vendor specific applesmc.768 only returns 256 discrete values covering the sensor range. (0-255.) I was only using that for validation though.

The ACPI interface returns Lux (estimated) and I was able to get it to go up to 4095. So I think it covers 4096 values (12bit precision) at least on my hardware. For screens today, at 4095 lux the user probably would have their screen at full brightness.

At full saturation (flashlight on top of ALS/camera):

$ ./sample 
Name: acpi-als
Illuminance raw: 4095
Illuminance input: 4095

Lux is absolute, so 0 should always be 0 across sensors, and 4096 Lux is already quite bright, so we could use that as the max brightness threshold for Clight's use. But the lux variable should probably be handled as a 32bit signed int, since that's how the driver uses it.

Also, I get this info from cat /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0c/ACPI0008:00/iio:device0/scan_elements/in_illuminance_type
le:s32/32>>0

So it looks like the driver uses it as a 32bit signed number, in LE with 0 right shifts.

Per the data here: https://github.com/01org/iio_testing_framework/blob/master/iio_sample_format.c#L45
http://www.at91.com/linux4sam/bin/view/Linux4SAM/IioAdcDriver#Understanding_the_in_voltageX_ty

@FedeDP
Copy link
Owner

FedeDP commented Sep 16, 2018

Thank you very much, your info were really helpful!
I'm just curious about

ATTR{name}=="acpi-als"

will it be the same for every als device? (i guess yes, it will).
This is the last info i need to actually understand that an "iio" subsystem device is an als :)
Btw you can check clightd-side work in progress in als_support branch.
It will take some time because i mostly work on it during the weekends; i'd say a couple of weeks for clightd, and one more week for clight support.

@FedeDP
Copy link
Owner

FedeDP commented Sep 30, 2018

@beret Can you test once more with this code:
udev_als.txt

and paste here the output?
More specifically, i'm trying to understand what does "udev_device_get_devtype" return.

@FedeDP
Copy link
Owner

FedeDP commented Oct 2, 2018

Referring to this, DEVTYPE should be "iio_device", that obviously does not give us any information whether this device is an ALS device. We should alawys check for ATTR{name}=="acpi-als".

@beret
Copy link

beret commented Oct 3, 2018

With the new test code, in a dark room:

Name: acpi-als
Illuminance raw: 0
Illuminance input: 0
Devtype: iio_device

I haven't tested on other devices, but it makes sense that all sensors using the kernel ACPI-ALS driver would report that type.

If you need to, the udev parent's ATTRS{hid}=="ACPI0008" should be a good way to be sure it is an ambient light sensor. (Since ACPI0008 is the Plug and Play ID for ambient light sensors - page 567.) Then we would look for the Illuminance property only, since support for other properties (color temperature, etc.) may be exposed by the kernel later.

Sorry I wasn't able to test sooner!

@FedeDP
Copy link
Owner

FedeDP commented Oct 3, 2018

If you need to, the parent's ATTRS{hid}=="ACPI0008" should be a good way to be sure it is an ambient light sensor. (Since ACPI0008 is the Plug and Play ID for ambient light sensors.) Then we would look for the Illuminance property only, since support for other properties (color temperature, etc.) may be exposed by the kernel later.

Great! I think ATTRS{name}=="ACPI-ALS" is already a good way to filter als devices.
The work (clightd's side) is quite done, i still need a couple of small things.

Then I need to port Clight to new Clightd interface :)

Sorry I wasn't able to test sooner!

No problem at all! Thank you!

@FedeDP
Copy link
Owner

FedeDP commented Oct 6, 2018

@beret For me als support in Clightd is completed; I still need to add support for new interface in clight.

The work will stay in als branch until clight catch up with new clightd interface (in a devel branch).
Then, when i feel ready, i will merge both Clightd's ALS branch and Clight's Devel branch into master and prepare a new release.

It would be great if you can test clightd new interface cloning the repository and building from ALS branch.
To build, just run make and then sudo ./clightd to run.
Finally, switch terminal and issue a
busctl call org.clightd.backlight /org/clightd/backlight org.clightd.backlight IsAlsAvailable "s" ""
It should return true.
busctl call org.clightd.backlight /org/clightd/backlight org.clightd.backlight IsSensorAvailable "s" ""
Again, it should return true.
Finally:
busctl call org.clightd.backlight /org/clightd/backlight org.clightd.backlight CaptureAls "s" ""
and
busctl call org.clightd.backlight /org/clightd/backlight org.clightd.backlight CaptureSensor "s" ""

They should both return current luminance as a double.

Note that "Sensor" is just a high level interface that will use ALS or WEBCAM depending on which one is available. It checks ALS first as obviously it is the best and most accurate option.

@beret
Copy link

beret commented Oct 11, 2018

I'll test this tonight and report back!

@beret
Copy link

beret commented Oct 12, 2018

It builds fine, and strace shows it is reading the right file and getting the right values:
7270 read(9, "2485\n", 4096)
(strace-clightd-als_support.txt)

However, dbus does not output the right values, and always prints zero.

In a dark room:

$ busctl call org.clightd.backlight /org/clightd/backlight org.clightd.backlight IsAlsAvailable "s" ""
b true
$ busctl call org.clightd.backlight /org/clightd/backlight org.clightd.backlight IsSensorAvailable "s" ""
b true
$ busctl call org.clightd.backlight /org/clightd/backlight org.clightd.backlight CaptureAls "s" ""
d 0
$ busctl call org.clightd.backlight /org/clightd/backlight org.clightd.backlight CaptureSensor "s" ""
d 0

In a dim room:

$ cat /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0c/ACPI0008:00/iio:device0/in_illuminance_raw
9
$ busctl call org.clightd.backlight /org/clightd/backlight org.clightd.backlight CaptureAls "s" ""
d 0

With a flashlight pointing at the sensor:

$ cat /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0c/ACPI0008:00/iio:device0/in_illuminance_raw
2853
$ busctl call org.clightd.backlight /org/clightd/backlight org.clightd.backlight CaptureAls "s" ""
d 0

For comparison, udev_als.c reads the values correctly.

@beret Can you test once more with this code:
udev_als.txt

$ busctl call org.clightd.backlight /org/clightd/backlight org.clightd.backlight CaptureAls "s" ""; ./sample
d 0
Name: acpi-als
Illuminance raw: 2010
Illuminance input: 2010
Devtype: iio_device

@FedeDP
Copy link
Owner

FedeDP commented Oct 12, 2018

Thanks! It works then. The issue is that, quite obviously, i forgot to cast "illuminance" to double before division, here: https://github.com/FedeDP/Clightd/blob/als_support/src/sensors/als.c#L12.
I will fix it as soon as i get home :)

@FedeDP
Copy link
Owner

FedeDP commented Oct 12, 2018

The above issue is now fixed, so i expect the code to work. It is ready to be merged to master.
Can you test once more?

Clight is slowly catching up, unfortunately it is not yet ready.

@beret
Copy link

beret commented Oct 12, 2018

Yup, that was it! It now goes from 0 to full (4095.)

$ busctl call org.clightd.backlight /org/clightd/backlight org.clightd.backlight CaptureAls "s" ""
d 0
$ cat /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:0c/ACPI0008:00/iio:device0/in_illuminance_raw
4095
$ busctl call org.clightd.backlight /org/clightd/backlight org.clightd.backlight CaptureAls "s" ""
d 0.999756

@FedeDP
Copy link
Owner

FedeDP commented Oct 26, 2018

Fixed in f948833.
@beret Note that i plan to break Clightd API with some more changes before 3.0 Clight and Clightd release.
But i will work on a devel branch; master (on both projects) should remain always usable.

Note also that travis build is not broken; the script i use to build has some weird issues.

@FedeDP FedeDP closed this as completed Oct 26, 2018
@FedeDP
Copy link
Owner

FedeDP commented Oct 26, 2018

Obviously, let me know if everything works as expected :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants