forked from WinEunuuchs2Unix/eyesome
-
Notifications
You must be signed in to change notification settings - Fork 0
/
eyesome-cfg.sh
1143 lines (899 loc) · 40.2 KB
/
eyesome-cfg.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/bin/bash
# NAME: eyesome-cfg.sh
# PATH: /usr/local/bin
# DESC: Configuration for eyessome.sh's min/max values, sun rise/set time
# and transition minutes.
# CALL: Called from terminal with `sudo` permissions.
# DATE: Feb 17, 2017. Modified: July 7, 2020.
# UPDT: Oct 5 2018: Allow lower setting for monitor test from "5" to "1" second
# Add new field "Watch external monitor plugging / power switch?"
# Dec 26 2018: Change screen to reflect test time of `1 to 20 seconds`.
# May 18 2020: Add override window to pause eyesome daemon. This allows
# user to manually set brightness / color temperature. Set yad window
# geometry default to '--center' instead of top left. Main Menu now
# allows 'X' to close window or Escpae Key to exit.
# Jun 2 2020: Expand Override window with Get, Preview and Apply
# buttons. Add monitor fields and Help button to Override window.
# Make $KEY randomized rather than hard coded for restart after crash.
# Jun 3 2020: Yetserday's version never published to github. Remove
# notebook --active-tab which doesn't work anyway and iconic reports to
# break things in Ubuntu 19.04.
# Jun 13 2020: Override button instructions on Main Menu. Add Sun Times
# tab to notebook for manual setting / daily override of sunrise and
# sunset times. When Overide exits set brightness to current time.
# Jul 07 2020: Old bug when $Retn not global then time remaining countdown
# when nothing clicked causes exit when countdown ends.
# May 09, 2021 Support for German and Russian locale date formats
source eyesome-src.sh # Common code for eyesome___.sh bash scripts
if [[ $(id -u) != 0 ]]; then # root powers needed to call this script
echo >&2 "$0 must be called with sudo powers"
exit 1
fi
# Must have the yad package.
command -v yad >/dev/null 2>&1 || { echo >&2 \
"'yad' package required but it is not installed. Aborting."; \
exit 2; }
# Must have the bc package.
command -v bc >/dev/null 2>&1 || { echo >&2 \
"'bc' package required but it is not installed. Aborting."; \
exit 2; }
# $TERM variable may be missing when called via desktop shortcut
CurrentTERM=$(env | grep TERM)
if [[ $CurrentTERM == "" ]] ; then
notify-send --urgency=critical \
"$0 cannot be run from GUI without TERM environment variable."
exit 3
fi
# Only one instance of eyesome-cfg.sh can be running
if pidof -o %PPID -x "$EyesomeCfgProgram">/dev/null; then
notify-send --urgency=critical \
"Eyesome configuration is already running."
exit 4
fi
# Read configuration and create if it doesn't exist.
ReadConfiguration
# Key for tying Notebook tabs together. Cannot be same key twice.
KEY=$(echo $[($RANDOM % ($[10000 - 32000] + 1)) + 10000] )
GEOMETRY="--center" # Center windows on screen
# Temporary files for Notebook output
res1=$(mktemp --tmpdir iface1.XXXXXXXX) # Notebook Overview Page (Tab 1)
res2=$(mktemp --tmpdir iface2.XXXXXXXX) # Notebook Monitor 1 Page (Tab 2)
res3=$(mktemp --tmpdir iface3.XXXXXXXX) # Notebook Monitor 2 Page (Tab 3)
res4=$(mktemp --tmpdir iface4.XXXXXXXX) # Notebook Monitor 3 Page (Tab 4)
res5=$(mktemp --tmpdir iface4.XXXXXXXX) # Notebook Sun times Page (Tab 5)
Cleanup () {
# Remove temporary files
rm -f "$res1" "$res2" "$res3" "$res4" "$res5"
IFS=$OLD_IFS; # Restore Input File Separator
} # Cleanup
BuildMonitorPage () {
# Move configuration array monitor 1-3 to Working Screen fields
# $1 = CfgArr Starting Index Number
aMonPage=()
i="$1"
aMonPage+=("--field=Monitor Number::RO")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Monitor Status::CB")
Status=("${CfgArr[$((i++))]}")
cbStatus="Enabled!Disabled"
cbStatus="${cbStatus/$Status/\^$Status}"
aMonPage+=("$cbStatus")
aMonPage+=("--field=Monitor Type::CB")
Type=("${CfgArr[$((i++))]}")
cbType="Hardware!Software"
cbType="${cbType/$Type/\^$Type}"
aMonPage+=("$cbType")
aMonPage+=("--field=Monitor Name:")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Internal Name:")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Xrandr Name:")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Daytime Brightness::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..9999!.01!2)
aMonPage+=("--field=Daytime Red::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Daytime Green::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Daytime Blue::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Nighttime Brightness::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..9999!.01!2)
aMonPage+=("--field=Nighttime Red::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Nighttime Green::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Nighttime Blue::NUM")
aMonPage+=("${CfgArr[$((i++))]}"!0.1..2.0!.01!2)
aMonPage+=("--field=Current Brightness::RO")
aMonPage+=("${CfgArr[$((i++))]}")
aMonPage+=("--field=Current Gamma::RO")
aMonPage+=("${CfgArr[$((i++))]}")
} # BuildMonitorPage
AddEmptyFields () {
# Add empty fields to Configuration File
# Allows fields for future use without having to modify configuration file
# $1 = Number of fields to add
for ((i=1; i<="$1"; i++)); do
printf " |" >> "$ConfigFilename"
done
} # AddEmptyFields
MakeHourMin () {
# Assumes time passed in "$3" is valid
# Declare reference to argument 1 & 2 provided (Bash 4.3 or greater)
declare -n Hour=$1 # 1-12
declare -n Min=$2 # 0-59
Time="$3" # Format: "hh:mm xm" where x='a' or 'p'
Major="${Time%% *}" # Strip of ' xm' = 'hh:mm'
Hour="${Major%%:*}" # Get left ':' = 'hh'
Min="${Major##*:}" # Get right ':' = 'mm'
#echo "Time: $Time Major: $Major Hour: $Hour Min: $Min"
} # MakeHourMin
EditConfiguration () {
# Not enough room in panel anymore for:
# Set internval between 5 and 300 seconds (5 minutes).
# 15 to 60 seconds should provide the best results.
local Retn ButnRefresh=10 ButnSave=20
# Prevent eyesome daemon from changing brightness/gamma while configuration
# is being edited. This allows other programs to change settings while
# this function is running. The Override () function does same thing.
PauseMonitors
# Test if files exist and have valid content, if not use 7:00 am / 9:00 pm
if [[ -e "$SunriseFilename" && -e "$SunriseFilename" ]] ; then
NetSunrise="$(cat $SunriseFilename)"
NetSunset="$(cat $SunsetFilename)"
else
NetSunrise="7:00 am"
NetSunset="9:00 pm"
fi
# Variables must be global for called functions to see
# Note 'Make' functions take variable name , not contents using $
MakeHourMin SunriseHour SunriseMinute "$NetSunrise"
MakeHourMin SunsetHour SunsetMinute "$NetSunset"
# Loop while BTN calls bash -c and kills notebook dialog
while true ; do # Dummy loop, always exists after first time.
# General notebook page
yad --plug=$KEY --tabnum=1 --form \
--field="
The web page with sunrise/sunset hours must begin
with <b>https://www.timeanddate.com/sun/</b> and
followed by your country/city name.
Well known cities might only contain your city
name or just a number. Usually the correct web
address is found automatically. If not, navigate
to www.timeanddate.com and search for your city.
Copy browser's web address and paste it below:\n:TXT" \
"${CfgArr[CFG_SUNCITY_NDX]}" \
--field="
Transition brightness/gamma interval in
seconds. Longer interval saves resources.
If interval is longer noticable brightness
and gamma adjustments occur. 60 seconds
is a good compromise::NUM" \
"${CfgArr[CFG_SLEEP_NDX]}"!5..300!1!0 \
--field="Transition minutes after sunrise::NUM" \
"${CfgArr[CFG_AFTER_SUNRISE_NDX]}"!0..180!1!0 \
--field="Transition minutes before sunset::NUM" \
"${CfgArr[CFG_BEFORE_SUNSET_NDX]}"!0..180!1!0 \
--field="
Test button duration. 1 to 20 seconds.:
:NUM" \
"${CfgArr[CFG_TEST_SECONDS_NDX]}"!1..20!1!0 \
--field="Watch external monitor plugging / power switching:CHK" \
"${CfgArr[CFG_DBUS_MONITOR_NDX]}" \
> "$res1" &
# Monitor 1 notebook page
BuildMonitorPage "$CFG_MON1_NDX"
yad --plug=$KEY --tabnum=2 --form \
"${aMonPage[@]}" \
> "$res2" &
# Monitor 2 notebook page
BuildMonitorPage "$CFG_MON2_NDX"
yad --plug=$KEY --tabnum=3 --form \
"${aMonPage[@]}" \
> "$res3" &
# Monitor 3 notebook page
BuildMonitorPage "$CFG_MON3_NDX"
yad --plug=$KEY --tabnum=4 --form \
"${aMonPage[@]}" \
> "$res4" &
Indent=" "
# Sun times
yad --plug=$KEY --tabnum=5 --form \
--field="
Although sunrise and sunset times are automatically
retrieved from internet, you can enter them here.
Do this if you don't have internet access or don't
want to use the internet for getting sun times.
Another example is when curtains closed for movie
watching or extremely dark storm clouds are out at
3:00 pm. In this case set sunset time to 2:00 pm
and your monitors will instantly dim for nightttime
settings when you click <b><i>Save</i></b> button.
Tomorrow sun times are automatically retrieved via
internet (if country/city provided) and changes
made here are reset. Sun times are in AM/PM format
not 24 hour clock. 12 AM is before 1 AM and 12 PM
is before 1 PM.:LBL" "" \
--field="$Indent Sunrise setting::RO" \
"$NetSunrise" \
--field="$Indent Sunset setting::RO" \
"$NetSunset" \
--field="$Indent Sunrise Hour 1-12::NUM" \
"$SunriseHour"!1..12!1!0 \
--field="$Indent Sunrise Minute 0-59: :NUM" \
"$SunriseMinute"!0..59!1!0 \
--field="$Indent Sunset Hour 1-12::NUM" \
"$SunsetHour"!1..12!1!0 \
--field="$Indent Sunset Minute 0-59::NUM" \
"$SunsetMinute"!0..59!1!0 \
> "$res5" &
# run main dialog that swallows tabs
# --image=gnome-calculator
yad --notebook --key=$KEY --tab="General" --tab="Monitor 1" \
--tab="Monitor 2" --tab="Monitor 3" --tab="Sun times" \
--image=sleep --image-on-top "$GEOMETRY" \
--title="eyesome setup" --width=400 \
--text="<big><b>eyesome</b></big> - edit configuration" \
--button="_Save:$ButnSave" \
--button="_Cancel:$ButnQuit" \
2>/dev/null
Retn="$?"
[[ $Retn == "$ButnSave" ]] && break # Save changes
UnPauseMonitors
return # Quit button, Escape Key, Alt-F4, X close window
done
# Save configuration
truncate -s -1 "$res1" # Remove new line at EOF
cat "$res1" > "$ConfigFilename"
AddEmptyFields 4 # Extra fields for future use
truncate -s -1 "$res2" # Remove new line at EOF
cat "$res2" >> "$ConfigFilename"
AddEmptyFields 4 # Extra fields for future use
truncate -s -1 "$res3" # Remove new line at EOF
cat "$res3" >> "$ConfigFilename"
AddEmptyFields 4
truncate -s -1 "$res4"
cat "$res4" >> "$ConfigFilename"
AddEmptyFields 4
echo "" >> "$ConfigFilename" # Add EOF (new line) marker
# Save sunrise/sunset files
local Arr
IFS='|' read -ra Arr < "$res5"
# Skip over Arr[0]=empty, Arr[1]=Sunrise time, Arr[2]=Sunset time
NetSunrise=$(date -d "${Arr[3]%%.*}:${Arr[4]%%.*} am" +"%I:%M %P")
NetSunset=$(date -d "${Arr[5]%%.*}:${Arr[6]%%.*} pm" +"%I:%M %P")
# Don't allow invalid times (date function returns zero length variable)
[[ "${#NetSunrise}" == 0 ]] && Netsunrise="7:00 am"
[[ "${#NetSunset}" == 0 ]] && Netsunset="9:00 pm"
echo "$NetSunrise" > "$SunriseFilename" # Save Sunrise time
echo "$NetSunset" > "$SunsetFilename" # Save Sunset time
# We do NOT want to unpause monitors because we will override the
# Enabled/Disabled settings the user just saved!
# UnPauseMonitors
} # EditConfiguration
MainMenu () {
ReadConfiguration
SecondsToUpdate=$("$WakeEyesome" post eyesome-cfg.sh nosleep remain)
# Blowout protection blank, 0 or negative (bug)
if [[ $SecondsToUpdate == "" ]] || [[ $SecondsToUpdate == 0 ]] \
|| [[ $SecondsToUpdate == -* ]] ; then
log "Seconds to update invalid value: $SecondsToUpdate"
SecondsToUpdate="${CfgArr[$CFG_SLEEP_NDX]%.*}"
fi
# May 9, 2021 Use epcoh seconds to correct error:
# date: invalid date ‘So 9. Mai 07:32:52 MDT 2021’
NextDate=$(date --date="$SecondsToUpdate seconds" +%s) # Sleep seconds Epoch
# Germany has 24 hour clock: https://stackoverflow.com/a/60335820/6929343
# So am/pm will be blank so: Last: 08:00:00 AM / Next: 07:00:00 PM
# becomes: Last: 08:00:00 / Next: 07:00:00
var=$(date +'%I:%M:%S %p') # Create test date
var="${var%"${var##*[![:space:]]}"}" # Remove trailing space(s)
if [[ "${#var}" -gt 8 ]] ; then
# Test date longer than 8 then AM/PM is supported use 12 hour clock
NextCheckTime=$(date --date=@"$NextDate" +'%I:%M:%S %p') # Now + Sleep
LastCheckTime=$(date +'%I:%M:%S %p') # Now
else
# Test date <= 8 then AM/PM is NOT supported use 24 hour clock
NextCheckTime=$(date --date=@"$NextDate" +'%H:%M:%S') # Now + Sleep
LastCheckTime=$(date +'%H:%M:%S') # Now
fi
# Getting dozens of Green Beakers (yad icons) in taskbar when left running
# and auto updating every 15 seconds. Use --skip-taskbar
Result=$(yad --form --skip-taskbar "$GEOMETRY" \
--image=preferences-desktop-screensaver \
--window-icon=preferences-desktop-screensaver \
--margins=10 \
--title="eyesome setup" \
--text="<big><b>eyesome</b></big> - main menu" \
--timeout="$SecondsToUpdate" --timeout-indicator=top \
--field="Eyesome daemon sleep time checked at::RO" \
--field="Seconds until eyesome daemon wakes::RO" \
--field="The next time eyesome daemon wakes::RO" \
--field="
This window refreshes when eyesome daemon wakes up to check
your monitor(s) brightness.
Click the <b><i>Remaining</i></b> button below to update how many seconds
remain until brightness is checked by eyesome daemon.
Click the <b><i>Edit</i></b> button below to change the brighness and/or
gamma monitor levels for Daytime and Nighttime. There you
can also change your city name used to obtain sunrise and
sunset times daily from the internet.
After using <b><i>Edit</i></b>, tests are done to ensure sunrise time was
recently updated. Also to ensure eyesome daemon is running.
Click the <b><i>Daytime</i></b> button below for a $TestSeconds second test of what
the monitors will look like in daytime. The same $TestSeconds second
test can be used for nighttime using the <b><i>Nighttime</i></b> button.
Click the <b><i>Override</i></b> button below to pause eyesome daemon.
A color temperature slider can be used to calculate red,
green and blue gamma channels. Gamma in turn can be
applied to the configuration for any monitor.
Click the <b><i>Quit</i></b> button to close this program.
:LBL" \
--button="_Remaining:$ButnRemaining" \
--button="_Edit:$ButnEdit" \
--button="_Daytime:$ButnDay" \
--button="_Nighttime:$ButnNight" \
--button="_Override:$ButnOverride" \
--button="_Quit:$ButnQuit" \
"$LastCheckTime" "$SecondsToUpdate" "$NextCheckTime" 2>/dev/null)
Retn="$?"
} # MainMenu
TestBrightness () {
# $1 = Day or Ngt for short test
# $1 = Gam for gamma preview applied to all monitors
SetBrightness "$1" # SetBrightnes function also used by eyesome.sh
eol=$'\n'
line="${aAllMon[*]}" # Convert array to string
line="${line//|/$eol}" # Search "|" replace with "\n" (new line).
[[ $TestSeconds == "" ]] || [[ $TestSeconds == 0 ]] && TestSeconds=5
SleepSec=$(bc <<< "scale=6; $TestSeconds/100")
for (( i=0; i<100; i++ )) ; do # 100 interations of sleep .xxx
echo $i # Percent complete for progress bar
[[ $i == 1 ]] && echo "$line" # dump aAllMon[*] array to progess log
[[ $i -gt 100 ]] && break
sleep "$SleepSec"
local TitleString
if [[ $1 == "Gam" ]] ; then
TitleString="eyesome Color Temperature Preview"
else
TitleString="eyesome Monitor Brightness Test"
fi
done | yad --progress --auto-close \
--title="$TitleString" \
--enable-log "$TestSeconds second time progress" \
--width=400 --height=550 \
--log-expanded --log-height=400 \
--log-on-top --percentage=0 \
--no-cancel --center \
--bar=RTL 2>/dev/nul
$WakeEyesome post eyesome-cfg.sh nosleep # $4 remaining sec not used
} # TestBrightness
math () {
# Written for: https://askubuntu.com/a/1241983/307523 and eyesomed-cfg.sh
[[ $2 != "=" ]] && { echo "Second parm must be '='"; return 1; }
# Declare mathres as reference to argument 1 provided (Bash 4.3 or greater)
declare -n mathres=$1
math_op="$4" # '*' as parameter changes operator to 'aptfielout' and
# operand2 to 'aptfilein' so force 'x' instead.
case "$math_op" in
x | \- | \/ | \+ | % ) # echo "Good"
;;
*)
echo "Invalid: $1 $2 $3 $4 $5 (For mutiplication use 'x' not '*')"
echo 'Usage: math c = $a operator $b'
echo 'Where operator is: "+", "-", "/", or "x" (without quotes)'
;;
esac
[[ $math_op == "x" ]] && math_op="*"
mathres=$(awk "BEGIN { print ($3 $math_op $5) }")
} # math
adjust_channel () {
local last_temp current multiplier
local added subtracted
last_val="$2"
current="$3"
multiplier="$4"
# Declare mathres as reference to argument 1 provided (Bash 4.3 or greater)
declare -n retn="$1"
if [[ $current > "$last_val" ]]; then
# normal increasing values
math added = "$current" - "$last_val"
math added = "$added" x "$multiplier"
math retn = "$last_val" + "$added"
else
# decreasing values
math subtracted = "$last_val" - "$current"
math subtracted = "$subtracted" x "$multiplier"
math retn = "$last_val" - "$subtracted"
fi
} # adjust_channel
TempToGamma () {
# May 18, 2020 - Python code from mmm's temp_to_gamma (srch_temp) function
# Convert Temp to Gamma (Xrandr Inverted or REAL Gamma returned)
local srch_temp i red green blue temp
local last_red last_green last_blue last_temp
local full_gap multiplier r g b Retn
# global variables set are Red, Green, Blue
# Override breaking values
srch_temp="$1"
[[ $srch_temp -lt 1000 ]] && srch_temp=1000
[[ $srch_temp -gt 10000 ]] && srch_temp=10000
# Get array entries before and after search temperature
for ((i=0; i<"${#GammaRampArr[@]}"; i=i+GRA_ENT_LEN)); do
red="${GammaRampArr[i+GRA_RED_OFF]}"
green="${GammaRampArr[i+GRA_GRN_OFF]}"
blue="${GammaRampArr[i+GRA_BLU_OFF]}"
temp="${GammaRampArr[i+GRA_TMP_OFF]}"
[[ $srch_temp -lt "$temp" ]] && break
last_red="$red"
last_green="$green"
last_blue="$blue"
last_temp="$temp"
done
# Calculate percentange (multiplier) search temperature between entries
math full_gap = "$temp" - "$last_temp"
math multiplier = "$srch_temp" - "$last_temp"
math multiplier = "$multiplier" / "$full_gap"
adjust_channel r "$last_red" "$red" "$multiplier"
adjust_channel g "$last_green" "$green" "$multiplier"
adjust_channel b "$last_blue" "$blue" "$multiplier"
# Deviation from mmm old line returned concatenated string for xrandr:
# return (str(round(r,2)) + ":" + str(round(g,2)) + ":" + str(round(b,2)))
# Here though we simply set global variables Red, Greeen, Blue
Red="$r"
Green="$g"
Blue="$b"
xRed=$(printf '%.*f\n' 2 "$Red")
xGreen=$(printf '%.*f\n' 2 "$Green")
xBlue=$(printf '%.*f\n' 2 "$Blue")
XrandrGammaString="$xRed:$xGreen:$xBlue"
} # TempToGamma
GammaToTemp() {
# Based on gamma_to_temp(srch_gamma) from mmm Python Program
# Convert Gamma to Temp (normal and NOT Xrandr Inverted Gamma passed)
# Returns $Temperature already defined globally
# Requires $Red $Green and $Blue passed as $1 $2 $3
local srch_red srch_green srch_blue i red green blue temp
local last_red last_green last_blue last_temp
local cutoff full_gap multiplier r g b
srch_red="$1"
srch_green="$2"
srch_blue="$3"
# Override breaking values
[[ $srch_red > "1.0" ]] && srch_red=1.0
[[ $srch_green > "1.0" ]] && srch_green=1.0
[[ $srch_blue > "1.0" ]] && srch_blue=1.0
# Get array entries before and after search colors
cutoff=$(( ${#GammaRampArr[@]} - ($GRA_ENT_LEN * 2) ))
for ((i=0; i<"${#GammaRampArr[@]}"; i=i+GRA_ENT_LEN)); do
red="${GammaRampArr[i+GRA_RED_OFF]}"
green="${GammaRampArr[i+GRA_GRN_OFF]}"
blue="${GammaRampArr[i+GRA_BLU_OFF]}"
temp="${GammaRampArr[i+GRA_TMP_OFF]}"
if [[ $srch_red == 1.0* ]] && [[ $blue == 0.0* ]] ; then
# Temperature is 1000K to 2000K
# Test srch_green <= green
if [[ "$green" > "$srch_green" ]] && [[ $i -ne 0 ]] ; then
# red static at 1 and blue static at 0 whilst green increasing
math full_gap = "$green" - "$last_green"
math multiplier = "$srch_green" - "$last_green"
math multiplier = "$multiplier" / "$full_gap"
break
fi
elif [[ $srch_red == 1.0* ]] && [[ $blue != 0.0* ]] ; then
# Temperature is 2001K to 6499K
# Test srch_blue <= blue
if [[ "$blue" > "$srch_blue" ]] ; then
# red static at 1 whilst green and blue are increasing
math full_gap = "$blue" - "$last_blue"
math multiplier = "$srch_blue" - "$last_blue"
math multiplier = "$multiplier" / "$full_gap"
break
fi
else
# Temperature is over 6499K and cannot be last index 10500 K
# Test srch_red >= red
if [[ "$red" < "$srch_red" ]] ; then
# blue static at 1.0 whilst red and green are decreasing
math full_gap = "$last_red" - "$red"
math multiplier = "$last_red" - "$srch_red"
math multiplier = "$multiplier" / "$full_gap"
break
fi
fi
[[ $i -ge "$cutoff" ]] && { Temperature="$temp" ; return ; }
last_red="$red"
last_green="$green"
last_blue="$blue"
last_temp="$temp"
done
Temperature=500.0
math Temperature = "$Temperature" x "$multiplier"
math Temperature = "$Temperature" + "$last_temp"
Temperature=$(printf "%.0f" "$Temperature")
} # GammaToTemp
ColorTemperature () {
ButnConvert=10
[[ $Temperature == "$EmptyString" ]] && Temperature=6500
Result=$(yad --scale --mouse \
--image=preferences-desktop-screensaver \
--window-icon=preferences-desktop-screensaver \
--value="$Temperature" --step=100 \
--min-value=1000 --max-value=10000 \
--mark=Night:3500 --mark=Day:6500 \
--margins=10 \
--title="eyesome color convertor" \
--text="
<big><b>eyesome</b></big> - Convert color temperature to gamma
Recommended nighttime color is 3500 K (Kelvins).
Recommended daytime color is 6500 K." \
--button="_Convert:$ButnConvert" \
--button="_Quit:$ButnQuit" \
2>/dev/null)
Retn="$?"
if [[ $Retn == "$ButnConvert" ]] ; then
Temperature="$Result"
TempToGamma "$Temperature"
return 0
fi
return 1
} # ColorTemperature
PauseMonitors () {
# Code lifted from movie.sh update on May 18, 2020.
# Get current monitor status to restore when exiting.
sMon1Status=$(grep -oP '(?<=\|1\|).*?(?=\|)' "$ConfigFilename")
sMon2Status=$(grep -oP '(?<=\|2\|).*?(?=\|)' "$ConfigFilename")
sMon3Status=$(grep -oP '(?<=\|3\|).*?(?=\|)' "$ConfigFilename")
# Change each Enabled monitor status to Paused.
[[ $sMon1Status == Enabled ]] && \
sed -i "s/|1|$sMon1Status|/|1|Paused|/g" "$ConfigFilename"
[[ $sMon2Status == Enabled ]] && \
sed -i "s/|2|$sMon2Status|/|2|Paused|/g" "$ConfigFilename"
[[ $sMon3Status == Enabled ]] && \
sed -i "s/|3|$sMon3Status|/|3|Paused|/g" "$ConfigFilename"
} # PauseMonitors
UnPauseMonitors () {
# Restore each paused monitor status to enabled setting.
sed -i "s/|1|Paused|/|1|Enabled|/g" "$ConfigFilename"
sed -i "s/|2|Paused|/|2|Enabled|/g" "$ConfigFilename"
sed -i "s/|3|Paused|/|3|Enabled|/g" "$ConfigFilename"
} # UnPauseMonitors
ErrMsg () {
# Parmater 1 = message to display
yad --image "dialog-error" --title "eyesome - Logical Error" \
--mouse --button=gtk-ok:0 --text "$1" 2>/dev/null
} # ErrMsg
InfoMsg () {
# Parmater 1 = message to display
yad --image "dialog-information" --title "eyesome - Information" \
--mouse --button=gtk-ok:0 --text "$1" 2>/dev/null
} # InfoMsg
ConfirmUpdate () {
local ButnUpdate
ButnUpdate=10
yad --image "gtk-dialog-question" --title "eyesome - Confirm Update" \
--text="<big><b>eyesome</b></big> - Apply changes to configuration
Are you sure you want to permenantly apply Monitor $OverrideMonitor - $OverrideDayNight
gamma settings ('$XrandrGammaString') to eyesome's configuration file? " \
--mouse \
--button="_Update settings:$ButnUpdate" \
--button="_Cancel update:$ButnQuit" \
2>/dev/null
[[ "$?" != "$ButnUpdate" ]] && return 1
return 0
} # ConfirmUpdate
OverrideHelp () {
# Parent window stays active and this function is called in sub-shell.
# Parent variables are not visible here unless they are exported.
Tip="Use Escape key, Alt+F4 or click X in top window coner to close."
yad --form --mouse \
--image=preferences-desktop-screensaver \
--window-icon=preferences-desktop-screensaver \
--margins=10 \
--title="eyesome Override Help" \
--text="<big><b>eyesome</b></big> - Override Help" \
--field="
You can now manually reset brightness or tint for monitor(s). Eyesome daemon
has been paused and will not change monitor(s) until Override window is closed.
Click the <b><i>Get</i></b> button to get the Day or Night settings for a monitor
into memory.
Click the <b><i>Color</i></b> button to pop up a window for converting color temperature
to gamma channels of Red, Green and Blue. The gamma channels can be used
with xrandr to control screen color temperature (also called tint):
xrandr --output <b>Monitor_Name</b> --brigthness <b>0.85</b> --gamma <b>Red:Green:Blue</b>
Substitute <b>bold fields</b> above with desired values:
<b>Monitor_Name</b> = Xrandr monitor name, e.g. 'eDP-1'.
<b>0.85</b> = Set brightness to 0.85 which is 85%.
If ommitted 1.0 brightness (100%) is used.
<b>Red:Green:Blue</b> = Xrandr gamma string e.g. '1.00:0.94:0:89'.
The starting color value will be 6500 K (daytime) unless <b><i>Get</i></b> button was
used to get a given monitor's day or night settings into memory.
Click the <b><i>Preview</i></b> button to test what ALL monitors look like with the color
temperature in memory.
Click the <b><i>Apply</i></b> button to change Daytime or Nighttime setting for the
SINGLE monitor in memory using the current Color Temperature set with <b><i>Color</i></b>
button. This permanently updates eyesome's configuration file.
<b>NOTE:</b> The 'xrandr --gamma string' appears as an input field but it is not. The
string can be copied into the clipboard and pasted into the terminal.
:LBL" \
--field="<b>Tip:</b> $Tip:RO" " " \
--button="_Back:$ButnQuit" \
2>/dev/null
# At least one Read Only (:RO) field is needed or window goes super large
} # OverrideHelp
export -f OverrideHelp # Make available to OVerride functions Help button
Override () {
local ButnGet ButnColor ButnPreview ButnApply aMonNdx Result Arr
local EmptyString cbMonitor cbDayNight Retn
ButnGet=10
ButnColor=20
ButnPreview=30
ButnApply=40
EmptyString="Nothing in memory."
# Define global fields
Temperature="$EmptyString"
Red="$EmptyString"
Green="$EmptyString"
Blue="$EmptyString"
XrandrGammaString="1.00:1.00:1.00"
# MonNdx must be global for ConfirmUpdate function
MonNdx="$EmptyString"
# Monitor number (1-3) to monitor index in Cfg Arr
aMonNdx=( $CFG_MON1_NDX $CFG_MON2_NDX $CFG_MON3_NDX )
MonName="$EmptyString" # "Laptop Display" / '50" Sony TV'
MonHardwareName="$EmptyString" # "intel_backlight" / "xrandr"
MonXrandrName="$EmptyString" # "eDP-1-1" (primary) / "HDMI-0", etc
InitXrandrArray # Run $(xrandr --verbose --current) to build array
# If eyesome daemon wakes it won't change our monitors whilst paused
PauseMonitors
# Global Monitor number and time kept in memory between Override buttons
OverrideMonitor="1"
OverrideDayNight="Night"
while true ; do
# Build monitor number and Day/Night Choice Boxes for yad
cbMonitor="1!2!3"
cbMonitor="${cbMonitor/$OverrideMonitor/\^$OverrideMonitor}"
cbDayNight="Day!Night"
cbDayNight="${cbDayNight/$OverrideDayNight/\^$OverrideDayNight}"
# Set default highlighted time (denoted by ^)
Result=$(yad --form "$GEOMETRY" \
--image=preferences-desktop-screensaver \
--window-icon=preferences-desktop-screensaver \
--margins=10 \
--title="eyesome Override" \
--text="
<big><b>eyesome</b></big> - Override (Pause eyesome daemon) " \
--field="Monitor Number::CB" \
"$cbMonitor" \
--field="Day or Night::CB" \
"$cbDayNight" \
--field="Monitor Name::RO" "$MonName" \
--field="Internal Name::RO" "$MonHardwareName" \
--field="Xrandr Plug Name::RO" "$MonXrandrName" \
--field="Color temperature::RO" "$Temperature" \
--field="Red gamma channel::RO" "$Red" \
--field="Green gamma channel::RO" "$Green" \
--field="Blue gamma channel::RO" "$Blue" \
--field="_Help using this window:FBTN" \
'bash -c "OverrideHelp"' \
--field="xrandr --gamma string:" "$XrandrGammaString" \
--button="_Get:$ButnGet" \
--button="_Color:$ButnColor" \
--button="_Preview:$ButnPreview" \
--button="_Apply:$ButnApply" \
--button="_Back:$ButnQuit" \
2>/dev/null)
Retn="$?" # Button return value, 254 = Escape or Alt+F4
# Convert Yad result string into an array
IFS='|' read -r -a Arr <<< "$Result" # Result string has | delimiters
OverrideMonitor="${Arr[0]}" # Extract Monitor Number
OverrideDayNight="${Arr[1]}" # Extract Day or Night
MonNdx="${aMonNdx[$(($OverrideMonitor - 1))]}"
[[ $Retn == "$ButnQuit" || $Retn == "$ButnEscape" ]] && break
if [[ $Retn == "$ButnColor" ]] ; then
ColorTemperature || continue
Red=$(printf '%.*f\n' 2 "$Red")
Green=$(printf '%.*f\n' 2 "$Green")
Blue=$(printf '%.*f\n' 2 "$Blue")
XrandrGammaString="$Red:$Green:$Blue"
elif [[ $Retn == "$ButnPreview" ]] ; then
[[ $Red == "$EmptyString" ]] && { \
ErrMsg "\n\n\nGamma must be in memory before 'Preview'. " ;
continue ; }
UnPauseMonitors
TestBrightness Gam
PauseMonitors
elif [[ $Retn == "$ButnGet" ]] ; then
# Set OverrideMonitor and OverrideDayNight fields
# Read values from CfgArr into work fields for:
# - Brightness (not used yet), Red, Green & Blue.
# Then calculate approximate Temperature from RGB
GetMonitorWorkSpace "$MonNdx"
if [[ $OverrideDayNight == Day ]] ; then
Red=$(printf '%.*f\n' 2 "$MonDayRed")
Green=$(printf '%.*f\n' 2 "$MonDayGreen")
Blue=$(printf '%.*f\n' 2 "$MonDayBlue")
else
Red=$(printf '%.*f\n' 2 "$MonNgtRed")
Green=$(printf '%.*f\n' 2 "$MonNgtGreen")
Blue=$(printf '%.*f\n' 2 "$MonNgtBlue")
fi
XrandrGammaString="$Red:$Green:$Blue"
GammaToTemp "$Red" "$Green" "$Blue"
elif [[ $Retn == "$ButnApply" ]] ; then
# Apply current gamma settings to selected monitor and time of day.
[[ $MonName == "$EmptyString" ]] && { \
ErrMsg "\n\n\nYou must 'Get' a monitor into memory first. " ;
continue ; }
ConfirmUpdate || continue
# Update configuration file
UnPauseMonitors
ReadConfiguration
GetMonitorWorkSpace "$MonNdx"
if [[ $OverrideDayNight == Day ]] ; then
# Yad uses 6 decimal places internally
MonDayRed=$(printf '%.*f\n' 6 "$Red")
MonDayGreen=$(printf '%.*f\n' 6 "$Green")
MonDayBlue=$(printf '%.*f\n' 6 "$Blue")
else
MonNgtRed=$(printf '%.*f\n' 6 "$Red")
MonNgtGreen=$(printf '%.*f\n' 6 "$Green")
MonNgtBlue=$(printf '%.*f\n' 6 "$Blue")
fi
SetMonitorWorkSpace "$MonNdx"
WriteConfiguration
PauseMonitors
local Msg
Msg="\n\n\nGamma settings have been updated for monitor:"
Msg="$Msg $OverrideMonitor - $OverrideDayNight "
InfoMsg "$Msg"
else
ErrMsg "eyesome - Override function - unknown button: $Retn"
fi
done
# Allow eyesome daemon to control monitors when he wakes
UnPauseMonitors
} # Override
CheckSunHours () {
[[ $fSunHoursCheckedOnce == true ]] && return
fSunHoursCheckedOnce=true
local Retn ButnRetrieve=10
while true ; do
# If date of sun rise/set files are more than 2 days old then
# /etc/cron.daily/daily-eyesome-sun may not be setup or when it
# called /usr/local/bin/eyesome-sun.sh it crashed or there was
# no internet access.
if [[ $(find "$SunsetFilename" -mtime +2 -print) ]]; then
: # echo "File $SunsetFilename exists and is older than 2 days"
else
return 0 # Sunrise / sunset file times are up-to-date.
fi
Result=$(yad --form "$GEOMETRY" \
--image=preferences-desktop-screensaver \
--window-icon=preferences-desktop-screensaver \
--margins=10 \
--height=500 \
--title="eyesome setup" \
--text="
<big><b>eyesome</b></big> - Sunrise / Sunset hours files are > 2 days old" \
--field="
The web address for sunrise/sunset hours might be incorrect:\n:tXT" \
"${CfgArr[CFG_SUNCITY_NDX]}" \
--field="
NOTE: You cannot change the website address from this screen.
You must use main menu's <b><i>Edit</i></b> button to change the address.
Once a day the web page is checked by 'cron' (Command Run ON).
The 'cron' script: '$CronSunHours' should call
the bash script: '$EyesomeSunProgram' each morning.
Sunrise time in '$SunriseFilename' is: <b>$(cat "$SunriseFilename")</b>
Sunset time in '$SunsetFilename' is: <b>$(cat "$SunsetFilename")</b>