Hoewel je met de knoppen op uw monitor deze naar wens kunt instellen, kan het handig zijn dit met software uit te voeren. Ddcutil is een programma om monitor instellingen aan te passen. Je kunt er de helderheid, kleur niveau's, ingangen, enz. mee regelen.
Ddcutil gebruikt DDC/CI (Display Data Channel Command Interface) om met de monitor te communiceren via I2C, een veel gebruikt systeem voor communicatie tussen hardwareonderdelen.
Ddcutil werkt niet met laptop schermen die een eigen speciaal systeem hebben en geen I2C gebruiken. Ddcutil werkt met alle grafische kaarten op voorwaarde dat je de open source stuurprogramma's gebruikt. Met AMD stuurprogramma's, moet je een speciaal geprepareerde versie van ddcutil gebruiken. Met NVidia stuurprogramma's moet je enkele extra instellingen aanpassen (zie verder).
Sommige monitors bevatten een lichtsensor waarmee de helderheid van de monitor aangepast wordt als het omgevingslicht veranderd. Zo zal bij zonlicht de monitor helderder worden en bij donker weer de helderheid van de monitor lager worden ingesteld. Toevallig heb ik op een Raspberry Pi een lichtsensor die via HTTP in het netwerk kan uitgelezen worden. Een uitdaging om al mijn schermen automatisch te dimmen naargelang het omgevingslicht.
Waarschuwing: weet wat je doet en zorg dat je steeds het systeem kunt herstellen (bijvoorbeeld via een back-up), m.a.w. als je deze tip tot een goed einde wilt brengen, heb je toch wat ervaring nodig.
Stel de monitor in zodat deze DDC/CI opdrachten kan verwerken.
Mijn computers bevatten allemaal NVidia grafische kaarten en stuurprogramma's (geen open source). Om ddcutil te kunnen gebruiken, moet je het stuurprogramma daarvan op de hoogte brengen. Dit kan door opties mee te geven met de kernel module voor de NVidia grafische kaart. Maar eerst maken we daar een back-up van (je weet maar nooit):
dany@main:~> sudo cp /etc/modprobe.d/50-nvidia-default.conf .
Er staat nu een kopie in uw Persoonlijke map.
Voeg als systeembeheerder de optie NVreg_RegistryDwords=RMUseSwI2c=0x01;RMI2cSpeed=100
aan de options regel toe.
Dit wordt dan (in mijn geval):
options nvidia NVreg_DeviceFileUID=0 NVreg_DeviceFileGID=484 NVreg_DeviceFileMode=0660 NVreg_RegistryDwords=RMUseSwI2c=0x01;RMI2cSpeed=100 install nvidia PATH=$PATH:/bin:/usr/bin; if /sbin/modprobe --ignore-install nvidia; then if /sbin/modprobe nvidia_uvm; then if [ ! -c /dev/nvidia-uvm ]; then mknod -m 660 /dev/nvidia-uvm c $(cat /proc/devices | while read major device; do if [ "$device" == "nvidia-uvm" ]; then echo $major; break; fi ; done) 0; chown :video /dev/nvidia-uvm; fi; fi; if [ ! -c /dev/nvidiactl ]; then mknod -m 660 /dev/nvidiactl c 195 255; chown :video /dev/nvidiactl; fi; devid=-1; for dev in $(ls -d /sys/bus/pci/devices/*); do vendorid=$(cat $dev/vendor); if [ "$vendorid" == "0x10de" ]; then class=$(cat $dev/class); classid=${class%%00}; if [ "$classid" == "0x0300" -o "$classid" == "0x0302" ]; then devid=$((devid+1)); if [ ! -c /dev/nvidia${devid} ]; then mknod -m 660 /dev/nvidia${devid} c 195 ${devid}; chown :video /dev/nvidia${devid}; fi; fi; fi; done; /sbin/modprobe nvidia_drm; if [ ! -c /dev/nvidia-modeset ]; then mknod -m 660 /dev/nvidia-modeset c 195 254; chown :video /dev/nvidia-modeset; fi; fi
Herstart de computer om de aanpassing te testen met:
dany@main:~> grep RegistryDwords /proc/driver/nvidia/params
RegistryDwords: "RMUseSwI2c=0x01;RMI2cSpeed=100"
RegistryDwordsPerDevice: ""
Op één computer gaf deze test foutieve parameters weer, daar werd het duidelijk in het logboek:
dany@pindabackup:~> cat /var/log/Xorg.0.log | grep RegistryDwords
[ 12.915] (**) NVIDIA(0): Option "RegistryDwords" "RMUseSwI2c=0x01; RMI2cSpeed=100"
Aangezien ddcutil werkt met I2C, moeten we ook I2C via een kernel module activeren:
dany@pindabackup:~> echo "i2c_dev" | sudo tee /etc/modules-load.d/i2c-dev.conf
i2c_dev
Herstart de computer om de I2C kernel module te laden.
Uiteindelijk kunnen we ddcutil installeren:
dany@pindabackup:~> sudo zypper install ddcutil
Gegevens van opslagruimte laden...
Lezen van geïnstalleerde pakketten...
Pakketafhankelijkheden oplossen...
Het volgende NIEUWE pakket zal worden geïnstalleerd:
ddcutil
1 nieuw te installeren pakket.
Totale downloadgrootte: 199,9 KiB. Reeds in de cache: 0 B. Na de bewerking zal aanvullend 537,3 KiB worden gebruikt.
Doorgaan? [j/n/v/...? alle opties tonen] (j):
pakket ddcutil-0.8.5-lp151.2.3.x86_64 wordt opgehaald (1/1), 199,9 KiB (537,3 KiB uitgepakt)
Ophalen: ddcutil-0.8.5-lp151.2.3.x86_64.rpm ......................................................................[gereed]
Controleren op conflicten tussen bestanden: ......................................................................[gereed]
(1/1) Installeren van: ddcutil-0.8.5-lp151.2.3.x86_64 ............................................................[gereed]
Een volledig overzicht van DDC/CI mogelijkheden van uw hardware, kan je opvragen met sudo ddcutil interrogate
.
Bijvoorbeeld om het type grafische kaart te achterhalen:
dany@pindabackup:~> sudo ddcutil interrogate | grep Device
Device class: x030000 VGA compatible controller
Device: x13c0 GM204 [GeForce GTX 980]
ModifyDeviceFiles: 1
DeviceFileUID: 0
DeviceFileGID: 484
DeviceFileMode: 432
RegistryDwordsPerDevice: ""
Device Minor: 0
Device /dev/i2c-0 is a SMBus or other ignorable device. Skipping i2cdetect.
***One Device ***
Device Node Path: /dev/i2c-1
***One Device ***
Device Node Path: /dev/i2c-2
***One Device ***
Device Node Path: /dev/i2c-3
***One Device ***
Device Node Path: /dev/i2c-4
***One Device ***
Device Node Path: /dev/i2c-5
***One Device ***
Device Node Path: /dev/i2c-6
***One Device ***
Device Node Path: /dev/i2c-7
***One Device ***
Device Node Path: /dev/i2c-0
options nvidia NVreg_DeviceFileUID=0 NVreg_DeviceFileGID=484 NVreg_DeviceFileMode=0660 NVreg_RegistryDwords=RMUseSwI2c=0x01;RMI2cSpeed=100
Device information:
Device Identifier Cross Reference Report
Of je ddcutil kunt gebruiken, kan je testen met:
dany@pindabackup:~> ddcutil environment
The following tests probe the runtime environment using multiple overlapping methods.
*** Basic System Information ***
ddcutil version: 0.8.5
/proc/version:
Linux version 4.12.14-lp151.28.40-default (geeko@buildhost) (gcc version 7.5.0 (SUSE Linux) ) #1 SMP Fri Mar 6 13:48:15 UTC 2020 (f0f1262)
Architecture: x86_64
Distributor id: sh: lsb_release: opdracht niet gevonden
Release: sh: lsb_release: opdracht niet gevonden
Found a known architecture
/proc/cmdline:
BOOT_IMAGE=/boot/vmlinuz-4.12.14-lp151.28.40-default root=UUID=3cb308c2-0508-4646-9e44-10efd013f7b2 splash=silent resume=/dev/disk/by-id/ata-OCZ-AGILITY3_OCZ-2SUN85O88IZYD6JY-part1 quiet mitigations=auto
*** Primary Check 1: Identify video card and driver ***
Obtaining card and driver information from /sys...
Primary video controller at PCI address 0000:01:00.0 (boot_vga flag is set)
Device class: x030000 VGA compatible controller
Vendor: x10de NVIDIA Corporation
Device: x13c0 GM204 [GeForce GTX 980]
Subvendor/Subdevice: 103c/2b49 Hewlett-Packard Company
Driver name: nvidia
Driver version: 390.132
I2C device: i2c-3 name: NVIDIA i2c adapter 2 at 1:00.0
I2C device: i2c-1 name: NVIDIA i2c adapter 0 at 1:00.0
I2C device: i2c-6 name: NVIDIA i2c adapter 8 at 1:00.0
I2C device: i2c-4 name: NVIDIA i2c adapter 6 at 1:00.0
I2C device: i2c-2 name: NVIDIA i2c adapter 1 at 1:00.0
I2C device: i2c-7 name: NVIDIA i2c adapter 9 at 1:00.0
I2C device: i2c-5 name: NVIDIA i2c adapter 7 at 1:00.0
*** Primary Check 2: Check that /dev/i2c-* exist and writable ***
Current user: dany (1000)
Checking /dev/i2c-* devices...
Unless the system is using the AMD proprietary driver fglrx, devices /dev/i2c-*
must exist and the logged on user must have read/write permission for those
devices (or at least those devices associated with monitors).
Typically, this access is enabled by:
- setting the group for /dev/i2c-* to i2c
- setting group RW permissions for /dev/i2c-*
- making the current user a member of group i2c
Alternatively, this can be enabled by just giving everyone RW permission
The following tests probe for these conditions.
Checking for /dev/i2c-* devices...
crw-rw---- 1 root i2c 89, 0 20 mrt 14:40 /dev/i2c-0
crw-rw---- 1 root i2c 89, 1 20 mrt 14:40 /dev/i2c-1
crw-rw---- 1 root i2c 89, 2 20 mrt 14:40 /dev/i2c-2
crw-rw---- 1 root i2c 89, 3 20 mrt 14:40 /dev/i2c-3
crw-rw---- 1 root i2c 89, 4 20 mrt 14:40 /dev/i2c-4
crw-rw---- 1 root i2c 89, 5 20 mrt 14:40 /dev/i2c-5
crw-rw---- 1 root i2c 89, 6 20 mrt 14:40 /dev/i2c-6
crw-rw---- 1 root i2c 89, 7 20 mrt 14:40 /dev/i2c-7
Current user (dany) has RW access to all /dev/i2c-* devices.
*** Primary Check 3: Check that module i2c_dev is loaded ***
Checking for module i2c_dev...
Module i2c_dev is NOT built into kernel
Using only proprietary nvidia or fglrx driver. Module i2c_dev not required.
*** Primary Check 4: Driver specific checks ***
Performing driver specific checks...
Checking for special settings for proprietary Nvidia driver
(Needed for some newer Nvidia cards).
grep: /etc/X11/xorg.conf: Bestand of map bestaat niet
/etc/X11/xorg.conf.d/90-nvidia_i2c.conf: Option "RegistryDwords" "RMUseSwI2c=0x01; RMI2cSpeed=100"
/etc/X11/xorg.conf.d/90-nvidia_i2c.conf: # solves problem of i2c errors with nvidia driver
/etc/X11/xorg.conf.d/90-nvidia_i2c.conf: # per https://devtalk.nvidia.com/default/topic/572292/-solved-does-gddccontrol-work-for-anyone-here-nvidia-i2c-monitor-display-ddc/#4309293
*** Additional probes ***
Scanning /proc/modules for driver environment...
Found other loaded module: videobuf2_vmalloc
Found other loaded module: videobuf2_memops
Found other loaded module: videobuf2_v4l2
Found other loaded module: videobuf2_core
Found other loaded module: videodev
Found other loaded module: i2c_i801
Found other loaded module: i2c_dev
Found video driver module: nvidia
Found other loaded module: drm_kms_helper
Loaded drm module depends on: nvidia_drm,drm_kms_helper,
Found other loaded module: drm_panel_orientation_quirks
Loaded video module depends on: -
Testing if modules are loaded using /sys...
Module amdgpu is NOT loaded
Module fbdev is NOT loaded
Module fglrx is NOT loaded
Module fturbo is NOT loaded
Module i915 is NOT loaded
Module mgag200 is NOT loaded
Module nvidia is loaded
Module nouveau is NOT loaded
Module radeon is NOT loaded
Module vboxvideo is NOT loaded
Module vc4 is NOT loaded
Module drm is loaded
Module i2c_algo_bit is NOT loaded
Module i2c_dev is loaded
Module i2c_piix4 is NOT loaded
Examining /sys/bus/i2c/devices...
/sys/bus/i2c/devices/i2c-3/name: NVIDIA i2c adapter 2 at 1:00.0
/sys/bus/i2c/devices/i2c-1/name: NVIDIA i2c adapter 0 at 1:00.0
/sys/bus/i2c/devices/i2c-6/name: NVIDIA i2c adapter 8 at 1:00.0
/sys/bus/i2c/devices/i2c-4/name: NVIDIA i2c adapter 6 at 1:00.0
/sys/bus/i2c/devices/i2c-2/name: NVIDIA i2c adapter 1 at 1:00.0
/sys/bus/i2c/devices/i2c-0/name: SMBus I801 adapter at f000
/sys/bus/i2c/devices/i2c-7/name: NVIDIA i2c adapter 9 at 1:00.0
/sys/bus/i2c/devices/i2c-5/name: NVIDIA i2c adapter 7 at 1:00.0
Env_Accumulator:
architecture: x86_64
distributor_id sh: lsb_release: opdracht niet gevonden
/dev/i2c device numbers: 0 1 2 3 4 5 6 7
Drivers detected: nvidia
sysfs_i2c_devices_exist: true
/sys/bus/i2c device numbers: 0 1 2 3 4 5 6 7
dev_i2c_devices_required: true
group_i2c_checked: true
group_i2c_exists: true
dev_i2c_common_group_name: i2c
cur_uname: dany
cur_uid: 1000
cur_user_in_group_i2c: true
cur_user_any_devi2c_rw: true
cur_user_all_devi2c_rw: true
module_i2c_dev_needed: false
module_i2c_dev_loaded: false
all_dev_i2c_has_group_i2c: true
any_dev_i2c_has_group_i2c: true
all_dev_i2c_is_group_rw: true
any_dev_i2c_is_group_rw: true
Configuration suggestions:
Current user has RW access to all /dev/i2c-N devices.
Skipping further group and permission checks.
Hou de geladen kernel modules in het oog. Deze opdracht toont op het einde configuratie suggesties. Bovenstaande uitvoer is van op een reeds geconfigureerd en werkend systeem. Bij jullie staan er waarschijnlijk opmerkingen over de group i2c en zijn gebruikers en apparaatrechten. De groep i2c maak je aan met:
dany@pindabackup:~> sudo groupadd --system i2c
Waarna je de gebruiker (hier dany) aan de i2c groep toevoegt:
dany@pindabackup:~> sudo usermod -G i2c -a dany
Met de volgende stap zorg je dat het I2C apparaat (toegang tot het gebruik van I2C) mogelijk wordt voor leden van de i2c groep. Dit zit in het ddcutil softwarepakket en moet je enkel kopiëren naar de juiste map om het te activeren:
dany@pindabackup:~> sudo cp /usr/share/ddcutil/data/45-ddcutil-i2c.rules /etc/udev/rules.d/
Na een herstart moet alles werken. De gebruiker moet lid zijn van de i2c groep:
dany@pindabackup:~> groups dany
dany : users i2c
En de I2C apparaten (devices) moeten toegankelijk zijn voor leden van de i2c groep:
dany@pindabackup:~> ls -l /dev/i2c-*
crw-rw---- 1 root i2c 89, 0 20 mrt 14:40 /dev/i2c-0
crw-rw---- 1 root i2c 89, 1 20 mrt 14:40 /dev/i2c-1
crw-rw---- 1 root i2c 89, 2 20 mrt 14:40 /dev/i2c-2
crw-rw---- 1 root i2c 89, 3 20 mrt 14:40 /dev/i2c-3
crw-rw---- 1 root i2c 89, 4 20 mrt 14:40 /dev/i2c-4
crw-rw---- 1 root i2c 89, 5 20 mrt 14:40 /dev/i2c-5
crw-rw---- 1 root i2c 89, 6 20 mrt 14:40 /dev/i2c-6
crw-rw---- 1 root i2c 89, 7 20 mrt 14:40 /dev/i2c-7
Om de instelmogelijkheden van uw monitor via ddcutil op te vragen, gebruik je de volgende opdracht:
dany@pindabackup:~> ddcutil getvcp known
(ddc_write_read_with_retry) Display_Handle[i2c: fh=3, busno=4], ddc_write_read() succeeded after 2 sleep and retry for DDC Null Response
VCP code 0x02 (New control value ): One or more new control values have been saved (0x02)
VCP code 0x0b (Color temperature increment ): 1000 degree(s) Kelvin
VCP code 0x0c (Color temperature request ): 3000 + 4 * (feature 0B color temp increment) degree(s) Kelvin
VCP code 0x0e (Clock ): current value = 60, max value = 120
VCP code 0x10 (Brightness ): current value = 37, max value = 100
VCP code 0x12 (Contrast ): current value = 50, max value = 100
(ddc_write_read_with_retry) Display_Handle[i2c: fh=3, busno=4], ddc_write_read() succeeded after 1 sleep and retry for DDC Null Response
VCP code 0x14 (Select color preset ): 6500 K (sl=0x05)
VCP code 0x16 (Video gain: Red ): current value = 255, max value = 255
VCP code 0x18 (Video gain: Green ): current value = 255, max value = 255
VCP code 0x1a (Video gain: Blue ): current value = 255, max value = 255
(ddc_write_read_with_retry) Display_Handle[i2c: fh=3, busno=4], ddc_write_read() succeeded after 1 sleep and retry for DDC Null Response
VCP code 0x1e (Auto setup ): Auto setup not active (sl=0x00)
VCP code 0x1f (Auto color setup ): Auto setup not active (sl=0x00)
VCP code 0x20 (Horizontal Position (Phase) ): current value = 0, max value = 100
VCP code 0x30 (Vertical Position (Phase) ): current value = 50, max value = 100
(ddc_write_read_with_retry) Display_Handle[i2c: fh=3, busno=4], ddc_write_read() succeeded after 1 sleep and retry for DDC Null Response
VCP code 0x3e (Clock phase ): current value = 0, max value = 60
(ddc_write_read_with_retry) Display_Handle[i2c: fh=3, busno=4], ddc_write_read() succeeded after 1 sleep and retry for DDC Null Response
VCP code 0x52 (Active control ): Value: 0x10
(ddc_write_read_with_retry) Display_Handle[i2c: fh=3, busno=4], ddc_write_read() succeeded after 1 sleep and retry for DDC Null Response
(ddc_write_read_with_retry) Display_Handle[i2c: fh=3, busno=4], ddc_write_read() succeeded after 1 sleep and retry for DDC Null Response
VCP code 0x60 (Input Source ): DVI-2 (sl=0x04)
VCP code 0x62 (Audio speaker volume ): current value = 0, max value = 100
(ddc_write_read_with_retry) Display_Handle[i2c: fh=3, busno=4], ddc_write_read() succeeded after 1 sleep and retry for DDC Null Response
VCP code 0x6c (Video black level: Red ): current value = 0, max value = 255
VCP code 0x6e (Video black level: Green ): current value = 0, max value = 255
VCP code 0x70 (Video black level: Blue ): current value = 0, max value = 255
VCP code 0x73 (LUT Size ): Maximum retries exceeded
VCP code 0x74 (Single point LUT operation ): Maximum retries exceeded
VCP code 0x75 (Block LUT operation ): Maximum retries exceeded
VCP code 0x78 (EDID operation ): Maximum retries exceeded
VCP code 0x8a (Color Saturation ): current value = 0, max value = 65535
VCP code 0x8c (TV Sharpness ): current value = 0, max value = 65535
VCP code 0x8d (Audio Mute ): Unmute the audio (sl=0x02)
(ddc_write_read_with_retry) Display_Handle[i2c: fh=3, busno=4], ddc_write_read() succeeded after 1 sleep and retry for DDC Null Response
(ddc_write_read_with_retry) Display_Handle[i2c: fh=3, busno=4], ddc_write_read() succeeded after 1 sleep and retry for DDC Null Response
VCP code 0x9b (6 axis hue control: Red ): current value = 0, max value = 65535
VCP code 0x9c (6 axis hue control: Yellow ): current value = 0, max value = 65535
VCP code 0x9d (6 axis hue control: Green ): current value = 0, max value = 65535
VCP code 0x9e (6 axis hue control: Cyan ): current value = 0, max value = 65535
VCP code 0x9f (6 axis hue control: Blue ): current value = 0, max value = 65535
VCP code 0xa0 (6 axis hue control: Magenta ): current value = 0, max value = 65535
VCP code 0xac (Horizontal frequency ): 58370 hz
(ddc_write_read_with_retry) Display_Handle[i2c: fh=3, busno=4], ddc_write_read() succeeded after 1 sleep and retry for DDC Null Response
VCP code 0xae (Vertical frequency ): 59.90 hz
VCP code 0xb2 (Flat panel sub-pixel layout ): Red/Green/Blue vertical stripe (sl=0x01)
(ddc_write_read_with_retry) Display_Handle[i2c: fh=3, busno=4], ddc_write_read() succeeded after 1 sleep and retry for DDC Null Response
VCP code 0xb6 (Display technology type ): LCD (active matrix) (sl=0x03)
(ddc_write_read_with_retry) Display_Handle[i2c: fh=3, busno=4], ddc_write_read() succeeded after 1 sleep and retry for DDC Null Response
VCP code 0xc0 (Display usage time ): Usage time (hours) = 22511 (0x0057ef) mh=0xff, ml=0xff, sh=0x57, sl=0xef
VCP code 0xc3 (Transmit display descriptor ): Maximum retries exceeded
VCP code 0xc6 (Application enable key ): 0x005a
VCP code 0xc8 (Display controller type ): Mfg: Genesis (sl=0x02), controller number: mh=0x00, ml=0x4a, sh=0x00
VCP code 0xc9 (Display firmware level ): 1.6
VCP code 0xca (OSD ): OSD Enabled (sl=0x02)
VCP code 0xcc (OSD Language ): Danish (sl=0x13)
VCP code 0xd2 (Asset Tag ): Maximum retries exceeded
VCP code 0xd6 (Power mode ): DPM: On, DPMS: Off (sl=0x01)
VCP code 0xdc (Display Mode ): Standard/Default mode (sl=0x00)
VCP code 0xdf (VCP Version ): 2.1
Uit deze informatie blijkt dat we de helderheid (Brightness) kunnen regelen van 0 tot en met 100, en deze nu is ingesteld op 37. Wil je één bepaalde instelling opvragen, bijvoorbeeld de helderheid:
dany@pindabackup:~> ddcutil getvcp 10
VCP code 0x10 (Brightness ): current value = 37, max value = 100
De code voor Brightness is 10, die je kunt achterhalen met de vorige opdracht. Op een gelijkaardige manier pas je een monitor instelling aan:
dany@pindabackup:~> ddcutil setvcp 10 60
Deze opdracht stelt de helderheid (10) van de monitor in op 60.
Wil je alle mogelijkheden van ddcutil ontdekken, raadpleeg dan de manual (man ddcutil
) en/of de help van ddcutil.
Met behulp van een lichtsensor en een script dat bij het aanmelden automatisch gestart wordt, kan je de helderheid van jouw monitor automatisch aanpassen aan het omgevingslicht. Mijn lichtsensor is aan een Raspberry Pi bevestigd en kan via HTTP door elk systeem op het netwerk uitgelezen worden.
Bash is bij velen de eerste keuze om scripts te schrijven. Met het volgend bash script lukt dit:
#!/bin/bash # brightness.sh # https://ledshield.wordpress.com/2012/11/13/led-brightness-to-your-eye-gamma-correction-no/ correction=(65535 65508 65479 65451 65422 65394 65365 65337 65308 65280 65251 65223 65195 65166 65138 65109 65081 65052 65024 64995 64967 64938 64909 64878 64847 64815 64781 64747 64711 64675 64637 64599 64559 64518 64476 64433 64389 64344 64297 64249 64200 64150 64099 64046 63992 63937 63880 63822 63763 63702 63640 63577 63512 63446 63379 63310 63239 63167 63094 63019 62943 62865 62785 62704 62621 62537 62451 62364 62275 62184 62092 61998 61902 61804 61705 61604 61501 61397 61290 61182 61072 60961 60847 60732 60614 60495 60374 60251 60126 59999 59870 59739 59606 59471 59334 59195 59053 58910 58765 58618 58468 58316 58163 58007 57848 57688 57525 57361 57194 57024 56853 56679 56503 56324 56143 55960 55774 55586 55396 55203 55008 54810 54610 54408 54203 53995 53785 53572 53357 53140 52919 52696 52471 52243 52012 51778 51542 51304 51062 50818 50571 50321 50069 49813 49555 49295 49031 48764 48495 48223 47948 47670 47389 47105 46818 46529 46236 45940 45641 45340 45035 44727 44416 44102 43785 43465 43142 42815 42486 42153 41817 41478 41135 40790 40441 40089 39733 39375 39013 38647 38279 37907 37531 37153 36770 36385 35996 35603 35207 34808 34405 33999 33589 33175 32758 32338 31913 31486 31054 30619 30181 29738 29292 28843 28389 27932 27471 27007 26539 26066 25590 25111 24627 24140 23649 23153 22654 22152 21645 21134 20619 20101 19578 19051 18521 17986 17447 16905 16358 15807 15252 14693 14129 13562 12990 12415 11835 11251 10662 10070 9473 8872 8266 7657 7043 6424 5802 5175 4543 3908 3267 2623 1974 1320 662 0) while : do # Haal het omgevingslicht op lux=$(curl -k https://rpipindanet/data/luxtls) if [ $? = 0 ]; then # Ophalen van meting gelukt en kan dus verwerkt worden echo "Omgevingslicht: $lux" maxlux=$(curl -k https://rpipindanet/data/luxmaxtls) minlux=$(curl -k https://rpipindanet/data/luxmintls) echo Maximaal gemeten omgevingslicht: $maxlux echo Minimaal gemeten omgevingslicht: $minlux rangelux=$(awk "BEGIN {printf \"%.2f\", $maxlux - $minlux}") echo Bereik gemeten omgevingslicht: $rangelux rellux=$(awk "BEGIN {printf \"%.2f\", ($lux - $minlux) / $rangelux}") echo Niet gecorrigeerde Relatief omgevingslicht: $rellux echo SQRT Relatief omgevingslicht: $(awk "BEGIN {printf sqrt($rellux)}") # rellux=$(awk "BEGIN {printf sqrt($rellux)}") correctionTableIndex=$(awk "BEGIN {printf \"%.0f\", 255 - ($rellux * 255)}") correctionTableValue=${correction[$correctionTableIndex]} correctionTableBrightness=$(awk "BEGIN {printf $correctionTableValue / ${correction[0]}}") echo CorrectionTable Relatief omgevingslicht: $correctionTableBrightness rellux=$correctionTableBrightness echo Relatief omgevingslicht: $rellux helderheid=$(awk "BEGIN {printf \"%.0f\", 5 + $rellux * 60}") # 0.6, 0.40 # Huidige helderheid huidige=$(ddcutil getvcp 10 | sed -r 's/([^0-9]*([0-9]*)){3}.*/\2/') # Helderheid geleidelijk aanpassen echo "Helderheid aanpassen van $huidige naar $helderheid" if [ ${huidige%.*} -eq ${helderheid%.*} ] && [ ${huidige#*.} \< ${helderheid#*.} ] || [ ${huidige%.*} -lt ${helderheid%.*} ]; then for i in $( LANG=en_US seq $huidige 1 $helderheid ); do echo verhogen: $i ddcutil setvcp 10 $i sleep 1 done else for i in $( LANG=en_US seq $huidige -1 $helderheid ); do echo verlagen: $i ddcutil setvcp 10 $i sleep 1 done fi fi # Wacht 1 minuut sleep 60 done
Daarbij kan je gebruik maken van allerlei correctieberekeningen waardoor de helderheid van de monitor beter de ooggevoeligheid volgt. Onze ogen zijn namelijk veel gevoeliger bij donker en veel minder gevoelig bij fel licht (gelukkig maar).
Hetzelfde kan je bereiken met een PHP script. Bash is OK, maar minder portable naar andere systemen.
#!/usr/bin/php <?php $maxHelderheid = 70; $minHelderheid = 5; # https://ledshield.wordpress.com/2012/11/13/led-brightness-to-your-eye-gamma-correction-no/ $correction = array(65535, 65508, 65479, 65451, 65422, 65394, 65365, 65337, 65308, 65280, 65251, 65223, 65195, 65166, 65138, 65109, 65081, 65052, 65024, 64995, 64967, 64938, 64909, 64878, 64847, 64815, 64781, 64747, 64711, 64675, 64637, 64599, 64559, 64518, 64476, 64433, 64389, 64344, 64297, 64249, 64200, 64150, 64099, 64046, 63992, 63937, 63880, 63822, 63763, 63702, 63640, 63577, 63512, 63446, 63379, 63310, 63239, 63167, 63094, 63019, 62943, 62865, 62785, 62704, 62621, 62537, 62451, 62364, 62275, 62184, 62092, 61998, 61902, 61804, 61705, 61604, 61501, 61397, 61290, 61182, 61072, 60961, 60847, 60732, 60614, 60495, 60374, 60251, 60126, 59999, 59870, 59739, 59606, 59471, 59334, 59195, 59053, 58910, 58765, 58618, 58468, 58316, 58163, 58007, 57848, 57688, 57525, 57361, 57194, 57024, 56853, 56679, 56503, 56324, 56143, 55960, 55774, 55586, 55396, 55203, 55008, 54810, 54610, 54408, 54203, 53995, 53785, 53572, 53357, 53140, 52919, 52696, 52471, 52243, 52012, 51778, 51542, 51304, 51062, 50818, 50571, 50321, 50069, 49813, 49555, 49295, 49031, 48764, 48495, 48223, 47948, 47670, 47389, 47105, 46818, 46529, 46236, 45940, 45641, 45340, 45035, 44727, 44416, 44102, 43785, 43465, 43142, 42815, 42486, 42153, 41817, 41478, 41135, 40790, 40441, 40089, 39733, 39375, 39013, 38647, 38279, 37907, 37531, 37153, 36770, 36385, 35996, 35603, 35207, 34808, 34405, 33999, 33589, 33175, 32758, 32338, 31913, 31486, 31054, 30619, 30181, 29738, 29292, 28843, 28389, 27932, 27471, 27007, 26539, 26066, 25590, 25111, 24627, 24140, 23649, 23153, 22654, 22152, 21645, 21134, 20619, 20101, 19578, 19051, 18521, 17986, 17447, 16905, 16358, 15807, 15252, 14693, 14129, 13562, 12990, 12415, 11835, 11251, 10662, 10070, 9473, 8872, 8266, 7657, 7043, 6424, 5802, 5175, 4543, 3908, 3267, 2623, 1974, 1320, 662, 0); function cURLdownload($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $result = curl_exec($ch); curl_close($ch); return $result; } while (1){ $lux = cURLdownload("http://rpipindanet/data/luxtls"); if (! $lux === FALSE) { echo "Omgevingslicht: $lux"; $maxlux = cURLdownload("http://rpipindanet/data/luxmaxtls"); echo "Maximaal gemeten omgevingslicht: $maxlux"; $minlux = cURLdownload("http://rpipindanet/data/luxmintls"); echo "Minimaal gemeten omgevingslicht: $minlux"; $rangelux = (float) $maxlux - (float) $minlux; echo "Bereik gemeten omgevingslicht: $rangelux\n"; $rellux = ((float) $lux - (float) $minlux) / $rangelux; echo "Niet gecorrigeerde Relatief omgevingslicht: $rellux\n"; echo "SQRT Relatief omgevingslicht: " . sqrt($rellux) . "\n"; $correctionTableIndex = 255 - (int) ($rellux * 255); $correctionTableValue = $correction[$correctionTableIndex]; $correctionTableBrightness = $correctionTableValue / $correction[0]; echo "CorrectionTable Relatief omgevingslicht: $correctionTableBrightness\n"; $rellux = $correctionTableBrightness; echo "Relatief omgevingslicht: $rellux\n"; $helderheid = (int) ($minHelderheid + $rellux * ($maxHelderheid - $minHelderheid)); unset($output); exec("ddcutil getvcp 10", $output, $return); preg_match_all('!\d+!',$output[0],$matches); # var_dump($matches); $huidige = (int) $matches[0][2]; echo "Helderheid aanpassen van $huidige naar $helderheid\n"; if ($huidige < $helderheid) { for ($i = $huidige + 1; $i <= $helderheid; $i++) { echo "Verhogen: $i\n"; exec("ddcutil setvcp 10 $i"); sleep (1); } } else { for ($i = $huidige - 1; $i >= $helderheid; $i--) { echo "Verlagen: $i\n"; exec("ddcutil setvcp 10 $i"); sleep (1); } } } sleep(60); } ?>