From 0400735587c780dbfb5125aeba3086cfe49b6de7 Mon Sep 17 00:00:00 2001
From: Aidar Bikbov <aa.bikbov@gmail.com>
Date: Tue, 6 Jun 2023 01:00:35 +0500
Subject: [PATCH] Add autonight (#838)

---
 .../configs/t10_lite_defconfig                |   1 +
 .../configs/t20_lite_defconfig                |   1 +
 .../configs/t21_lite_defconfig                |   1 +
 .../configs/t30_lite_defconfig                |   1 +
 br-ext-chip-ingenic/configs/t31_fpv_defconfig |   1 +
 .../configs/t31_lite_defconfig                |   1 +
 .../configs/t31_ultimate_defconfig            |   1 +
 .../configs/t40_lite_defconfig                |   1 +
 .../configs/t40_ultimate_defconfig            |   1 +
 general/package/autonight/Config.in           |   4 +
 general/package/autonight/autonight.mk        |  25 ++++
 general/package/autonight/readme.md           |  41 ++++++
 general/package/autonight/src/Makefile        |   9 ++
 general/package/autonight/src/autonight.c     | 117 ++++++++++++++++++
 14 files changed, 205 insertions(+)
 create mode 100644 general/package/autonight/Config.in
 create mode 100644 general/package/autonight/autonight.mk
 create mode 100644 general/package/autonight/readme.md
 create mode 100644 general/package/autonight/src/Makefile
 create mode 100644 general/package/autonight/src/autonight.c

diff --git a/br-ext-chip-ingenic/configs/t10_lite_defconfig b/br-ext-chip-ingenic/configs/t10_lite_defconfig
index 4d1dc28e..736cf4e4 100644
--- a/br-ext-chip-ingenic/configs/t10_lite_defconfig
+++ b/br-ext-chip-ingenic/configs/t10_lite_defconfig
@@ -90,6 +90,7 @@ BR2_PACKAGE_UACME_OPENIPC=y
 BR2_PACKAGE_VTUND_OPENIPC=y
 BR2_PACKAGE_YAML_CLI=y
 BR2_PACKAGE_QUIRC_OPENIPC=y
+# BR2_PACKAGE_AUTONIGHT is not set
 
 # WiFi
 BR2_PACKAGE_WIRELESS_TOOLS=y
diff --git a/br-ext-chip-ingenic/configs/t20_lite_defconfig b/br-ext-chip-ingenic/configs/t20_lite_defconfig
index b45361cd..f5a56cbb 100644
--- a/br-ext-chip-ingenic/configs/t20_lite_defconfig
+++ b/br-ext-chip-ingenic/configs/t20_lite_defconfig
@@ -90,6 +90,7 @@ BR2_PACKAGE_UACME_OPENIPC=y
 BR2_PACKAGE_VTUND_OPENIPC=y
 BR2_PACKAGE_YAML_CLI=y
 BR2_PACKAGE_QUIRC_OPENIPC=y
+# BR2_PACKAGE_AUTONIGHT is not set
 
 # WiFi
 BR2_PACKAGE_WIRELESS_TOOLS=y
diff --git a/br-ext-chip-ingenic/configs/t21_lite_defconfig b/br-ext-chip-ingenic/configs/t21_lite_defconfig
index f36807c5..50126f84 100644
--- a/br-ext-chip-ingenic/configs/t21_lite_defconfig
+++ b/br-ext-chip-ingenic/configs/t21_lite_defconfig
@@ -90,6 +90,7 @@ BR2_PACKAGE_UACME_OPENIPC=y
 BR2_PACKAGE_VTUND_OPENIPC=y
 BR2_PACKAGE_YAML_CLI=y
 BR2_PACKAGE_QUIRC_OPENIPC=y
+# BR2_PACKAGE_AUTONIGHT is not set
 
 # WiFi
 BR2_PACKAGE_WIRELESS_TOOLS=y
diff --git a/br-ext-chip-ingenic/configs/t30_lite_defconfig b/br-ext-chip-ingenic/configs/t30_lite_defconfig
index 2bb8ef68..a40e238c 100644
--- a/br-ext-chip-ingenic/configs/t30_lite_defconfig
+++ b/br-ext-chip-ingenic/configs/t30_lite_defconfig
@@ -90,6 +90,7 @@ BR2_PACKAGE_UACME_OPENIPC=y
 BR2_PACKAGE_VTUND_OPENIPC=y
 BR2_PACKAGE_YAML_CLI=y
 BR2_PACKAGE_QUIRC_OPENIPC=y
+# BR2_PACKAGE_AUTONIGHT is not set
 
 # WiFi
 BR2_PACKAGE_WIRELESS_TOOLS=y
diff --git a/br-ext-chip-ingenic/configs/t31_fpv_defconfig b/br-ext-chip-ingenic/configs/t31_fpv_defconfig
index 554170e4..76c57693 100644
--- a/br-ext-chip-ingenic/configs/t31_fpv_defconfig
+++ b/br-ext-chip-ingenic/configs/t31_fpv_defconfig
@@ -91,6 +91,7 @@ BR2_PACKAGE_MBEDTLS_OPENIPC=y
 BR2_PACKAGE_VTUND_OPENIPC=y
 BR2_PACKAGE_YAML_CLI=y
 # BR2_PACKAGE_QUIRC_OPENIPC is not set
+# BR2_PACKAGE_AUTONIGHT is not set
 
 # WiFi
 BR2_PACKAGE_WIRELESS_TOOLS=y
diff --git a/br-ext-chip-ingenic/configs/t31_lite_defconfig b/br-ext-chip-ingenic/configs/t31_lite_defconfig
index ec94d9ce..a308c387 100644
--- a/br-ext-chip-ingenic/configs/t31_lite_defconfig
+++ b/br-ext-chip-ingenic/configs/t31_lite_defconfig
@@ -91,6 +91,7 @@ BR2_PACKAGE_UACME_OPENIPC=y
 BR2_PACKAGE_VTUND_OPENIPC=y
 BR2_PACKAGE_YAML_CLI=y
 BR2_PACKAGE_QUIRC_OPENIPC=y
+# BR2_PACKAGE_AUTONIGHT is not set
 
 # WiFi
 BR2_PACKAGE_WIRELESS_TOOLS=y
diff --git a/br-ext-chip-ingenic/configs/t31_ultimate_defconfig b/br-ext-chip-ingenic/configs/t31_ultimate_defconfig
index 4b0cce01..2f45477d 100644
--- a/br-ext-chip-ingenic/configs/t31_ultimate_defconfig
+++ b/br-ext-chip-ingenic/configs/t31_ultimate_defconfig
@@ -93,6 +93,7 @@ BR2_PACKAGE_UACME_OPENIPC=y
 BR2_PACKAGE_VTUND_OPENIPC=y
 BR2_PACKAGE_YAML_CLI=y
 BR2_PACKAGE_QUIRC_OPENIPC=y
+# BR2_PACKAGE_AUTONIGHT is not set
 
 # WiFi
 BR2_PACKAGE_WIRELESS_TOOLS=y
diff --git a/br-ext-chip-ingenic/configs/t40_lite_defconfig b/br-ext-chip-ingenic/configs/t40_lite_defconfig
index a276e52a..857a1cae 100644
--- a/br-ext-chip-ingenic/configs/t40_lite_defconfig
+++ b/br-ext-chip-ingenic/configs/t40_lite_defconfig
@@ -91,6 +91,7 @@ BR2_PACKAGE_UACME_OPENIPC=y
 BR2_PACKAGE_VTUND_OPENIPC=y
 BR2_PACKAGE_YAML_CLI=y
 BR2_PACKAGE_QUIRC_OPENIPC=y
+# BR2_PACKAGE_AUTONIGHT is not set
 
 # WiFi
 BR2_PACKAGE_WIRELESS_TOOLS=y
diff --git a/br-ext-chip-ingenic/configs/t40_ultimate_defconfig b/br-ext-chip-ingenic/configs/t40_ultimate_defconfig
index ade191fe..dfeabbdd 100644
--- a/br-ext-chip-ingenic/configs/t40_ultimate_defconfig
+++ b/br-ext-chip-ingenic/configs/t40_ultimate_defconfig
@@ -91,6 +91,7 @@ BR2_PACKAGE_UACME_OPENIPC=y
 BR2_PACKAGE_VTUND_OPENIPC=y
 BR2_PACKAGE_YAML_CLI=y
 BR2_PACKAGE_QUIRC_OPENIPC=y
+# BR2_PACKAGE_AUTONIGHT is not set
 
 # WiFi
 BR2_PACKAGE_WIRELESS_TOOLS=y
diff --git a/general/package/autonight/Config.in b/general/package/autonight/Config.in
new file mode 100644
index 00000000..e02ccf66
--- /dev/null
+++ b/general/package/autonight/Config.in
@@ -0,0 +1,4 @@
+config BR2_PACKAGE_AUTONIGHT
+	bool "autonight"
+	help
+	  autonight - automatic switching of day/night modes depending on the readings of the IR Sensor
diff --git a/general/package/autonight/autonight.mk b/general/package/autonight/autonight.mk
new file mode 100644
index 00000000..f3a28db0
--- /dev/null
+++ b/general/package/autonight/autonight.mk
@@ -0,0 +1,25 @@
+################################################################################
+#
+# autonight
+#
+################################################################################
+
+AUTONIGHT_LICENSE = MIT
+AUTONIGHT_LICENSE_FILES = LICENSE
+
+define AUTONIGHT_EXTRACT_CMDS
+	cp -avr ../general/package/autonight/src/* $(@D)/
+endef
+
+AUTONIGHT_MAKE_OPTS = \
+	CC="$(TARGET_CC)"
+
+define AUTONIGHT_BUILD_CMDS
+	$(MAKE) $(AUTONIGHT_MAKE_OPTS) -C $(@D)
+endef
+
+define AUTONIGHT_INSTALL_TARGET_CMDS
+	install -m 0755 -D $(@D)/autonight $(TARGET_DIR)/usr/bin/autonight
+endef
+
+$(eval $(generic-package))
diff --git a/general/package/autonight/readme.md b/general/package/autonight/readme.md
new file mode 100644
index 00000000..1f873094
--- /dev/null
+++ b/general/package/autonight/readme.md
@@ -0,0 +1,41 @@
+# autonight
+
+## Before usage
+### rebuild uImage and rootfs
+```
+make BOARD=t31_lite br-linux-menuconfig
+    Device Drivers
+        Multifunction device drivers
+            <*> Support for the XBurst SADC AUX
+            <*> Support for the XBurst SADC CORE
+make BOARD=t31_lite br-linux-rebuild
+make BOARD=t31_lite br-all
+```
+### or change `br-ext-chip-ingenic/board/t31/kernel/t31.generic.config` before building
+```
+- # CONFIG_MFD_JZ_SADC_V13 is not set
+- # CONFIG_MFD_JZ_SADC_AUX is not set
++ CONFIG_MFD_JZ_SADC_V13=y
++ CONFIG_MFD_JZ_SADC_AUX=y
+
+```
+
+## Options
+```
+-D - sets jz_adc_aux device
+-c - sets the command to call to set night mode
+-d - delay (in seconds) between ADC reads
+-O - turn on night mode when ADC value drops below this threshold
+-F - turn off night mode when ADC value goes above this threshold
+-h - print usage statement and exit
+```
+
+## Examples usage
+```
+autonight -D /dev/jz_adc_aux_0
+autonight -d 3
+autonight -h
+```
+
+## TODO
+### Need to choose the correct default values of `thresholdOn` and `thresholdOff`
diff --git a/general/package/autonight/src/Makefile b/general/package/autonight/src/Makefile
new file mode 100644
index 00000000..2a224607
--- /dev/null
+++ b/general/package/autonight/src/Makefile
@@ -0,0 +1,9 @@
+.PHONY: all clean
+
+all: autonight
+
+autonight: autonight.o
+	$(CC) -o $@ $^
+
+clean:
+	-rm -rf *.o
diff --git a/general/package/autonight/src/autonight.c b/general/package/autonight/src/autonight.c
new file mode 100644
index 00000000..241abe90
--- /dev/null
+++ b/general/package/autonight/src/autonight.c
@@ -0,0 +1,117 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+
+#define BUF_SIZE 256
+
+const char *device = "/dev/jz_adc_aux_0";
+const char *nightModeCmd = "curl localhost/night/";
+int delayBetweenReads = 3;
+int thresholdOn = 900;
+int thresholdOff = 1000;
+bool nightModeEnabled = false;
+
+void
+jzAuxRead(const char *device, int *value)
+{
+	int fd, size, count;
+
+	fd = open(device, O_RDONLY);
+	if(fd < 0){
+		perror(device);
+		exit(EXIT_FAILURE);
+	}
+	size = sizeof(*value);
+	count = read(fd, (void *)value, size);
+	close(fd);
+	if(count != size){
+		perror("read()");
+		exit(EXIT_FAILURE);
+	}
+}
+
+void
+updateNightMode()
+{
+	int ret;
+	char buf[BUF_SIZE];
+
+	printf("Night Mode %s\n", nightModeEnabled ? "Enabled" : "Disabled");
+	snprintf(buf, BUF_SIZE, "%s%s\n", nightModeCmd, nightModeEnabled ? "on" : "off");
+	ret = system(buf);
+	if(ret != 0){
+		perror("system()");
+		exit(EXIT_FAILURE);
+	}
+}
+
+void
+usage(const char *argv0)
+{
+	fprintf(stderr, "\nusage: %s [options]\n\n"
+	                "options:\n"
+	                "	-D sets jz_adc_aux device (default: %s)\n"
+	                "	-c sets the command to call to set night mode (default: %s)\n"
+	                "	-d delay (in seconds) between ADC reads (default: %d)\n"
+	                "	-O turn on night mode when ADC value drops below this threshold (default: %d)\n"
+	                "	-F turn off night mode when ADC value goes above this threshold (default: %d)\n"
+	                "	-h print this usage statement and exit\n\n",  argv0, device, nightModeCmd, delayBetweenReads, thresholdOn, thresholdOff);
+}
+
+int
+main(int argc, char *argv[])
+{
+	int opt, value;
+
+	while((opt = getopt(argc, argv, "D:c:d:O:F:h:")) != -1){
+		switch(opt){
+			case 'D':
+				device = optarg;
+				break;
+			case 'c':
+				nightModeCmd = optarg;
+				break;
+			case 'd':
+				delayBetweenReads = atoi(optarg);
+				break;
+			case 'O':
+				thresholdOn = atoi(optarg);
+				break;
+			case 'F':
+				thresholdOff = atoi(optarg);
+				break;
+			case 'h':
+				usage(argv[0]);
+				exit(EXIT_SUCCESS);
+			default:
+				usage(argv[0]);
+				exit(EXIT_FAILURE);
+		}
+	}
+
+	if(daemon(0, 0) < 0){
+		perror("daemon()");
+		exit(EXIT_FAILURE);
+	}
+
+	sleep(5);
+
+	while(true){
+		jzAuxRead(device, &value);
+		printf("Current value: %d\n", value);
+		if(!nightModeEnabled && value >= thresholdOn){
+			nightModeEnabled = true;
+			updateNightMode();
+		} else if(nightModeEnabled && value < thresholdOff){
+			nightModeEnabled = false;
+			updateNightMode();
+		}
+		sleep(delayBetweenReads);
+	}
+
+	return 0;
+}