From 72fea370ff20ecb2494ab985c4431b4bd691e7cd Mon Sep 17 00:00:00 2001
From: guowenxue <guowenxue@gmail.com>
Date: Mon, 17 Nov 2025 15:11:05 +0800
Subject: [PATCH] update lighted program
---
/dev/null | 45 --
project/lightd/hal/makefile | 27 +
project/lightd/makefile | 26
.gitignore | 1
project/lightd/config.c | 291 +++++++++++++
project/lightd/etc/lightd.conf | 70 +++
project/lightd/hal/gpio.h | 29
project/lightd/config.h | 76 +++
project/lightd/hal/tsl2561.h | 46 -
project/lightd/lightd.c | 378 ++++++++++++++++++
project/lightd/hal/gpio.c | 112 +---
project/lightd/hal/tsl2561.c | 154 ++++---
12 files changed, 1,004 insertions(+), 251 deletions(-)
diff --git a/.gitignore b/.gitignore
index 005a0ec..e66af8e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,4 +33,5 @@
# binary file
project/gpsd/gpsd
+project/lightd/lightd
project/thingsboard/thingsboard
diff --git a/project/lightd/config.c b/project/lightd/config.c
new file mode 100644
index 0000000..f9c646c
--- /dev/null
+++ b/project/lightd/config.c
@@ -0,0 +1,291 @@
+/*********************************************************************************
+ * Copyright: (C) 2019 LingYun IoT System Studio
+ * All rights reserved.
+ *
+ * Filename: config.c
+ * Description: This file is mqttd configure file parser function
+ *
+ * Version: 1.0.0(2019年06月25日)
+ * Author: Guo Wenxue <guowenxue@gmail.com>
+ * ChangeLog: 1, Release initial version on "2019年06月25日 22时23分55秒"
+ *
+ ********************************************************************************/
+#include "config.h"
+#include "logger.h"
+#include "iniparser.h"
+
+enum
+{
+ _TYPE_INPUT,
+ _TYPE_OUTPUT,
+};
+int parser_gpio_info(int type, gpio_t *gpio, char *conf);
+
+int parser_conf(const char *conf_file, iotd_ctx_t *ctx, int debug)
+{
+ dictionary *ini;
+ const char *str;
+ int val;
+ int rv = 0;
+ logger_t *logger;
+ hwinfo_t *hwinfo;
+ mqtt_ctx_t *mqtt;
+
+ if( !conf_file || !ctx )
+ {
+ fprintf(stderr, "%s() Invalid input arguments\n", __func__);
+ return -1;
+ }
+
+ memset(ctx, 0, sizeof(*ctx));
+ logger = &ctx->logger;
+ hwinfo = &ctx->hwinfo;
+ mqtt = &ctx->mqtt;
+
+ ini = iniparser_load(conf_file);
+ if( !ini )
+ {
+ fprintf(stderr, "ERROR: Configure file '%s' load failed\n", conf_file);
+ return -2;
+ }
+
+ /*+------------------------------------------------------+
+ *| parser logger settings and start logger system |
+ *+------------------------------------------------------+*/
+ if( !debug )
+ {
+ str = iniparser_getstring(ini, "logger:file", "/tmp/thingsboard.log");
+ strncpy(logger->logfile, str, sizeof(logger->logfile));
+ logger->logsize = iniparser_getint(ini, "logger:size", 1024);
+ logger->loglevel = iniparser_getint(ini, "logger:level", LOG_LEVEL_INFO);
+ }
+ else
+ {
+ strncpy(logger->logfile, "console", sizeof(logger->logfile));
+ logger->loglevel = LOG_LEVEL_DEBUG;
+ logger->logsize = 0;
+ }
+
+ if( log_open(logger->logfile, logger->loglevel, logger->logsize, LOG_LOCK_DISABLE) < 0 )
+ {
+ fprintf(stderr, "Logger system initialise failure\n");
+ return -2;
+ }
+
+ log_info("Logger system initialise ok\n");
+
+
+ /*+------------------------------------------------------+
+ *| parser production ID |
+ *+------------------------------------------------------+*/
+
+ if( !(str=iniparser_getstring(ini, "common:devid", NULL)) )
+ {
+ log_error("ERROR: Parser device ID failure\n");
+ rv = -3;
+ goto cleanup;
+ }
+ /* cJSON parser ID will get "" */
+ snprintf(mqtt->devid, sizeof(mqtt->devid), "\"%s\"", str);
+ log_info("Parser device ID [%s]\n", mqtt->devid);
+
+
+ /*+------------------------------------------------------+
+ *| parser hardware module configuration |
+ *+------------------------------------------------------+*/
+
+ /* parser GPIO output pins */
+ if( !(str=iniparser_getstring(ini, "hardware:gpio_outpin", NULL)) )
+ {
+ log_warn("parser no GPIO output pins\n");
+ }
+ else
+ {
+ parser_gpio_info(_TYPE_OUTPUT, &hwinfo->gpio, (char *)str);
+ log_info("parser [%d] GPIO output pins configured\n", hwinfo->gpio.outcnt);
+ }
+
+ hwinfo->light_intval = iniparser_getint(ini, "hardware:light_intval", 20);
+ log_info("parser relay controled light interval time [%d]\n", hwinfo->light_intval);
+
+ /* parser GPIO input pins */
+ if( !(str=iniparser_getstring(ini, "hardware:gpio_inpin", NULL)) )
+ {
+ log_warn("parser no GPIO input pins\n");
+ }
+ else
+ {
+ parser_gpio_info(_TYPE_INPUT, &hwinfo->gpio, (char *)str);
+ log_info("parser [%d] GPIO input pins\n", hwinfo->gpio.incnt);
+ }
+
+ hwinfo->lux_threshold = iniparser_getdouble(ini, "hardware:lux_threshold", 0.1);
+ log_info("parser LUX enable and threshold value set be [%.03f]\n", hwinfo->lux_threshold);
+
+
+ /*+------------------------------------------------------+
+ *| parser broker settings |
+ *+------------------------------------------------------+*/
+
+ if( !(str=iniparser_getstring(ini, "broker:hostname", NULL)) )
+ {
+ log_error("ERROR: Parser MQTT broker server hostname failure\n");
+ rv = -4;
+ goto cleanup;
+ }
+ strncpy(mqtt->host, str, sizeof(mqtt->host) );
+
+ if( (val=iniparser_getint(ini, "broker:port", -1)) < 0 )
+ {
+ log_error("ERROR: Parser MQTT broker server port failure\n");
+ rv = -5;
+ goto cleanup;
+ }
+ mqtt->port = val;
+ log_info("Parser MQTT broker server [%s:%d]\n", mqtt->host, mqtt->port);
+
+ str=iniparser_getstring(ini, "broker:token", NULL);
+ strncpy(mqtt->token, str, sizeof(mqtt->uid) );
+
+ str=iniparser_getstring(ini, "broker:username", NULL);
+ strncpy(mqtt->uid, str, sizeof(mqtt->uid) );
+
+ str=iniparser_getstring(ini, "broker:password", NULL);
+ strncpy(mqtt->pwd, str, sizeof(mqtt->pwd) );
+
+ if( mqtt->uid && mqtt->pwd )
+ log_info("Parser broker author by [%s:%s]\n", mqtt->uid, mqtt->pwd);
+
+ mqtt->keepalive = iniparser_getint(ini, "broker:keepalive", DEF_KEEPALIVE);
+ log_info("Parser broker keepalive timeout [%d] seconds\n", mqtt->keepalive);
+
+ /*+------------------------------------------------------+
+ *| parser publisher settings |
+ *+------------------------------------------------------+*/
+
+ if( !(str=iniparser_getstring(ini, "publisher:pubTopic", NULL)) )
+ {
+ log_error("ERROR: Parser MQTT broker publisher topic failure\n");
+ rv = -6;
+ goto cleanup;
+ }
+ strncpy(mqtt->pubTopic, str, sizeof(mqtt->pubTopic) );
+
+ mqtt->pubQos = iniparser_getint(ini, "publisher:pubQos", DEF_QOS);
+ mqtt->interval = iniparser_getint(ini, "publisher:interval", DEF_PUBINTERVAL);
+ log_info("Parser publisher topic \"%s\" with Qos[%d] interval[%d]\n", mqtt->pubTopic, mqtt->pubQos, mqtt->interval);
+
+ /*+------------------------------------------------------+
+ *| parser subscriber settings |
+ *+------------------------------------------------------+*/
+
+ if( !(str=iniparser_getstring(ini, "subsciber:subTopic", NULL)) )
+ {
+ log_error("ERROR: Parser MQTT broker publisher topic failure\n");
+ rv = -7;
+ goto cleanup;
+ }
+ strncpy(mqtt->subTopic, str, sizeof(mqtt->subTopic) );
+
+ mqtt->subQos = iniparser_getint(ini, "subsciber:subQos", DEF_QOS);
+ log_info("Parser subscriber topic \"%s\" with Qos[%d]\n", mqtt->subTopic, mqtt->subQos);
+
+cleanup:
+ if( ini )
+ iniparser_freedict(ini);
+
+ if( rv )
+ log_close();
+
+ return rv;
+}
+
+/* conf format: "{light_indoor:6:0},{light_hallway:26:0}" */
+int parser_gpio_info(int type, gpio_t *gpio, char *conf)
+{
+ char *ptr;
+ char *pstart;
+ char *pend;
+ char buf[64];
+ int cnt = 0;
+ int rv = 0;
+
+ if( !gpio || !conf || strlen(conf)<3 )
+ {
+ log_error("Invalid input arguments.\n");
+ return -1;
+ }
+
+ pstart = strchr(conf, '{');
+ if( !pstart )
+ return 0;
+
+ pend = strchr(pstart, '}');
+
+ while( pstart && pend )
+ {
+ memset(buf, 0, sizeof(buf));
+
+ strncpy(buf, pstart+1, pend-pstart-1);
+
+ /* parser and get the GPIO name, BCM pin number, active power level */
+
+ {
+ /* check GPIO configure name too long or not */
+ ptr = strchr(buf, ':');
+ if( !ptr )
+ {
+ log_error("Found invalid GPIO configure: %s\n", buf);
+ goto NEXT_LOOP;
+ }
+
+ if( ptr-buf > sizeof(gpio->input[cnt].name) )
+ {
+ log_error("Found GPIO name too long\n", buf);
+ goto NEXT_LOOP;
+ }
+
+ /* use sscanf() to parser GPIO configured values */
+ if(_TYPE_INPUT == type )
+ {
+ rv = sscanf(buf, "%[^:]:%d:%d", gpio->input[cnt].name, &gpio->input[cnt].pin, &gpio->input[cnt].active_level);
+ if( 3 == rv)
+ {
+ log_info("parser GPIO input[%s] BCM[%d] active[%d]\n", gpio->input[cnt].name, gpio->input[cnt].pin, gpio->input[cnt].active_level);
+ if( strstr(gpio->input[cnt].name, "infrared") )
+ {
+ log_info("parser GPIO enable infrared detect\n");
+ }
+ cnt++;
+ gpio->incnt = cnt;
+ }
+ else
+ {
+ log_error("Found invalid GPIO configure: %s\n", buf);
+ }
+ }
+ else
+ {
+ rv = sscanf(buf, "%[^:]:%d:%d", gpio->output[cnt].name, &gpio->output[cnt].pin, &gpio->output[cnt].active_level);
+ if( 3 == rv)
+ {
+ log_info("parser GPIO output[%s] BCM[%d] active[%d]\n", gpio->output[cnt].name, gpio->output[cnt].pin, gpio->output[cnt].active_level);
+ cnt++;
+ gpio->outcnt = cnt;
+ }
+ else
+ {
+ log_error("Found invalid GPIO configure: %s\n", buf);
+ }
+ }
+ }
+
+NEXT_LOOP:
+ pstart = strchr(pend, '{');
+ if( pstart )
+ pend = strchr(pstart, '}');
+ }
+
+
+ return gpio->outcnt;
+}
diff --git a/project/lightd/config.h b/project/lightd/config.h
new file mode 100644
index 0000000..5bff2bc
--- /dev/null
+++ b/project/lightd/config.h
@@ -0,0 +1,76 @@
+/*********************************************************************************
+ * Copyright: (C) 2019 LingYun IoT System Studio
+ * All rights reserved.
+ *
+ * Filename: config.h
+ * Description: This file is mqttd configure file parser function
+ *
+ * Version: 1.0.0(2019年06月25日)
+ * Author: Guo Wenxue <guowenxue@gmail.com>
+ * ChangeLog: 1, Release initial version on "2019年06月25日 22时23分55秒"
+ *
+ ********************************************************************************/
+#ifndef __CONF_H_
+#define __CONF_H_
+
+#include "gpio.h"
+
+enum
+{
+ Qos0, /* 发送者只发送一次消息,不进行重试,Broker不会返回确认消息。在Qos0情况下,Broker可能没有接受到消息 */
+ Qos1, /* 发送者最少发送一次消息,确保消息到达Broker,Broker需要返回确认消息PUBACK。在Qos1情况下,Broker可能接受到重复消息 */
+ Qos2, /* Qos2使用两阶段确认来保证消息的不丢失和不重复。在Qos2情况下,Broker肯定会收到消息,且只收到一次 */
+};
+
+#define DEF_KEEPALIVE 30
+#define DEF_PUBINTERVAL 120
+#define DEF_QOS Qos2
+
+typedef struct mqtt_ctx_s
+{
+ char devid[32]; /* device ID */
+
+ /* Broker settings */
+ char host[128]; /* MQTT broker server name */
+ int port; /* MQTT broker listen port */
+ char token[64]; /* token */
+ char uid[64]; /* username */
+ char pwd[64]; /* password */
+ int keepalive; /* MQTT broker send PING message to subsciber/publisher keepalive timeout<seconds> */
+
+ /* Publisher settings */
+ char pubTopic[256]; /* Publisher topic */
+ int pubQos; /* Publisher Qos */
+ int interval ; /* Publish sensor data interval time, unit seconds */
+
+ /* Subscriber settings */
+ char subTopic[256]; /* Subscriber topic */
+ int subQos; /* Subscriber Qos */
+} mqtt_ctx_t;
+
+typedef struct logger_s
+{
+ /* logger settings */
+ char logfile[128]; /* logger record file */
+ int loglevel; /* logger level */
+ int logsize; /* logger file maxsize, oversize will rollback */
+} logger_t;
+
+typedef struct hwinfo_s
+{
+ gpio_t gpio; /* gpio information */
+ int light_intval; /* light on interval */
+ float lux_threshold;/* lux threshold value */
+} hwinfo_t;
+
+typedef struct iotd_ctx_s
+{
+ logger_t logger;
+ hwinfo_t hwinfo;
+ mqtt_ctx_t mqtt;
+} iotd_ctx_t;
+
+extern int parser_conf(const char *conf_file, iotd_ctx_t *ctx, int debug);
+
+#endif /* ----- #ifndef _CONF_H_ ----- */
+
diff --git a/project/lightd/etc/iotd.conf b/project/lightd/etc/iotd.conf
deleted file mode 100644
index b54f3e6..0000000
--- a/project/lightd/etc/iotd.conf
+++ /dev/null
@@ -1,83 +0,0 @@
-
-[common]
-id="RPI3B#01"
-
-[logger]
-
-# 日志记录文件
-file=/tmp/iotd.log
-
-# 日志级别: 0:error 1:warnning 2:info 3:debug 4:trace
-level=2
-
-# 日志回滚大小
-size=1024
-
-
-#+-------------------------------------------+
-#| Hardware configuration |
-#+-------------------------------------------+
-
-# 树莓派连接的外设信息,0:禁用或未连接 其他: 使能或相关硬件连接的Pin管脚(BCM)
-[hardware]
-
-# LED或继电器等GPIO输出控制, 格式: {名称:BCM编码:控制电平}
-# Relay(1) <-> 19 Relay(2) <-> 26
-gpio_outpin={light_indoor:19:1},{light_hallway:26:1}
-
-# 红外探测到人后,继电器控制灯亮的时长
-light_intval=15
-
-# 按键或红外感应灯GPIO输入控制, 格式: {名称:BCM编码:控制:电平}
-# Indoor(23)<->(black/gray) Hallway(24)<->(yellow/red)
-gpio_inpin={infrared_indoor:23:1},{infrared_hallway:24:1}
-
-# 是否使能 TSL2561 光强传感器模块,0:禁用 X:光强阈值
-lux=1
-lux_threshold=0.10
-
-# 是否使能 DS18b20 温度传感器模块,0:禁用 1:是能
-# ds18b20=1
-
-# 是否使能 SHT2X 温湿度传感器模块,0:禁用 1:使能
-# sht2x=0
-
-#+-------------------------------------------+
-#| MQTT configuration |
-#+-------------------------------------------+
-
-[broker]
-
-# broker 服务器地址和端口号
-hostname="weike-iot.com"
-port=10883
-
-# broker 认证连接的用户名和密码
-username="lingyun"
-password="lingyun"
-
-# broker给subsciber和publisher发送PING报文保持 keepalive 的时间周期,单位是秒
-keepalive=30
-
-# Qos0: 发送者只发送一次消息,不进行重试,Broker不会返回确认消息。在Qos0情况下,Broker可能没有接受到消息
-# Qos1: 发送者最少发送一次消息,确保消息到达Broker,Broker需要返回确认消息PUBACK。在Qos1情况下,Broker可能接受到重复消息
-# Qos2: Qos2使用两阶段确认来保证消息的不丢失和不重复。在Qos2情况下,Broker肯定会收到消息,且只收到一次
-
-
-[subsciber]
-
-subTopic="$Sys/Studio/Downlink/iotd"
-subQos=0
-
-
-[publisher]
-
-enable=0
-
-pubTopic="$Sys/Studio/Uplink/"
-pubQos=0
-
-# Publisher上报传感器数据的周期,单位是秒
-interval=60
-
-
diff --git a/project/lightd/etc/lightd.conf b/project/lightd/etc/lightd.conf
new file mode 100644
index 0000000..13494b9
--- /dev/null
+++ b/project/lightd/etc/lightd.conf
@@ -0,0 +1,70 @@
+[common]
+devid="RaspberryPi#1"
+
+# 树莓派连接的外设信息,使能或相关硬件连接的Pin管脚
+[hardware]
+
+# 红外感应灯GPIO输入控制, 格式: {名称:BCM编码:控制电平}
+# Indoor(#16)<->(black/gray) Hallway(#18)<->(yellow/red)
+gpio_inpin={infrared_indoor:23:1},{infrared_hallway:24:1}
+
+# 继电器GPIO输出控制, 格式: {名称:BCM编码:控制电平}
+# Relay(1) <-> #35 Relay(2) <-> #37
+gpio_outpin={light_indoor:19:1},{light_hallway:26:1}
+
+# TSL2561 光强传感器光强阈值
+lux_threshold=0.10
+
+# 红外探测到人后,继电器控制灯亮的时长
+light_intval=15
+
+
+[logger]
+
+# 日志记录文件
+file=/var/log/lightd.log
+
+# 日志级别: 0:ERROR 1:WARN 2:INFO 3:DEBUG 4:TRACE
+level=2
+
+# 日志回滚大小
+size=1024
+
+
+[broker]
+
+# broker 服务器地址和端口号
+hostname="weike-iot.com"
+port=2262
+
+# broker 认证连接的 token
+token="gu8wq8mfj1gadkyh6yo5"
+
+# broker 认证连接的用户名和密码
+username="lingyun"
+password="lingyun"
+
+# broker给subsciber和publisher发送PING报文保持 keepalive 的时间周期,单位是秒
+keepalive=30
+
+# Qos0: 发送者只发送一次消息,不进行重试,Broker不会返回确认消息。在Qos0情况下,Broker可能没有接受到消息
+# Qos1: 发送者最少发送一次消息,确保消息到达Broker,Broker需要返回确认消息PUBACK。在Qos1情况下,Broker可能接受到重复消息
+# Qos2: Qos2使用两阶段确认来保证消息的不丢失和不重复。在Qos2情况下,Broker肯定会收到消息,且只收到一次
+
+[publisher]
+
+# mosquitto_pub -h weike-iot.com -p 2262 -u "gu8wq8mfj1gadkyh6yo5" -t v1/devices/me/telemetry -m '{"temperature":66.66, "humidity":88.88}'
+pubTopic="v1/devices/me/telemetry"
+pubQos=0
+
+# Publisher上报传感器数据的周期,单位是秒
+interval=60
+
+[subsciber]
+
+# mosquitto_sub -h weike-iot.com -p 2262 -u "gu8wq8mfj1gadkyh6yo5" -t "v1/devices/me/rpc/request/+"
+# {"method":"setValue","params":{"device":"lightIndoor","status":true}}
+# {"method":"setValue","params":{"device":"lightHallway","status":true}}
+subTopic="v1/devices/me/rpc/request/+"
+subQos=0
+
diff --git a/project/lightd/hal/ds18b20.c b/project/lightd/hal/ds18b20.c
deleted file mode 100644
index 2037af5..0000000
--- a/project/lightd/hal/ds18b20.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*********************************************************************************
- * Copyright: (C) 2018 LingYun IoT System Studio
- * All rights reserved.
- *
- * Filename: ds18b20.c
- * Description: This file is temperature sensor DS18B20 code
- *
- * Version: 1.0.0(2018/10/14)
- * Author: Guo Wenxue <guowenxue@gmail.com>
- * ChangeLog: 1, Release initial version on "2018/10/14 12:13:26"
- *
- ********************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-
-#include "logger.h"
-
-/* File Content:
- pi@raspberrypi:~/guowenxue $ cat /sys/bus/w1/devices/28-041731f7c0ff/w1_slave
- 3a 01 4b 46 7f ff 0c 10 a5 : crc=a5 YES
- 3a 01 4b 46 7f ff 0c 10 a5 t=19625
- */
-
-int ds18b20_get_temperature(float *temp)
-{
- char w1_path[50] = "/sys/bus/w1/devices/";
- char chip[20];
- char buf[128];
- DIR *dirp;
- struct dirent *direntp;
- int fd =-1;
- char *ptr;
- int found = 0;
-
- if( !temp )
- {
- return -1;
- }
-
- /*+-------------------------------------------------------------------+
- *| open dierectory /sys/bus/w1/devices to get chipset Serial Number |
- *+-------------------------------------------------------------------+*/
- if((dirp = opendir(w1_path)) == NULL)
- {
- log_error("opendir '%s' error: %s\n", w1_path, strerror(errno));
- return -2;
- }
-
- while((direntp = readdir(dirp)) != NULL)
- {
- if(strstr(direntp->d_name,"28-"))
- {
- /* find and get the chipset SN filename */
- strcpy(chip,direntp->d_name);
- found = 1;
- break;
- }
- }
- closedir(dirp);
-
- if( !found )
- {
- log_error("Can not find ds18b20 in %s\n", w1_path);
- return -3;
- }
-
- /* get DS18B20 sample file full path: /sys/bus/w1/devices/28-xxxx/w1_slave */
- strncat(w1_path, chip, sizeof(w1_path)-strlen(w1_path));
- strncat(w1_path, "/w1_slave", sizeof(w1_path)-strlen(w1_path));
-
- /* open file /sys/bus/w1/devices/28-xxxx/w1_slave to get temperature */
- if( (fd=open(w1_path, O_RDONLY)) < 0 )
- {
- log_error("open %s error: %s\n", w1_path, strerror(errno));
- return -4;
- }
-
- if(read(fd, buf, sizeof(buf)) < 0)
- {
- log_error("read %s error: %s\n", w1_path, strerror(errno));
- return -5;
- }
-
- ptr = strstr(buf, "t=");
- if( !ptr )
- {
- log_error("ERROR: Can not get temperature\n");
- return -6;
- }
-
- ptr+=2;
-
- /* convert string value to float value */
- *temp = atof(ptr)/1000;
-
- close(fd);
-
- return 0;
-}
diff --git a/project/lightd/hal/ds18b20.h b/project/lightd/hal/ds18b20.h
deleted file mode 100644
index 58540a8..0000000
--- a/project/lightd/hal/ds18b20.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*********************************************************************************
- * Copyright: (C) 2018 LingYun IoT System Studio
- * All rights reserved.
- *
- * Filename: ds18b20.c
- * Description: This file is temperature sensor DS18B20 code
- *
- * Version: 1.0.0(2018/10/14)
- * Author: Guo Wenxue <guowenxue@gmail.com>
- * ChangeLog: 1, Release initial version on "2018/10/14 12:13:26"
- *
- ********************************************************************************/
-
-#ifndef __DS18B20_H
-#define __DS18B20_H
-
-extern int ds18b20_get_temperature(float *temp);
-
-#endif
diff --git a/project/lightd/hal/gpio.c b/project/lightd/hal/gpio.c
index 01cc363..d0e781c 100644
--- a/project/lightd/hal/gpio.c
+++ b/project/lightd/hal/gpio.c
@@ -11,13 +11,16 @@
*
********************************************************************************/
-#include <stdio.h>
-#include <stdlib.h>
#include <unistd.h>
-#include <fcntl.h>
-#include <dirent.h>
+#include <stdlib.h>
#include <string.h>
-#include <time.h>
+#include <errno.h>
+
+#include "logger.h"
+#include "util_proc.h"
+#include "gpio.h"
+
+#define RPI_GPIONAME "gpiochip0"
#include <errno.h>
#include "logger.h"
@@ -35,13 +38,11 @@
int rv;
s_gpio = gpio;
-
if( !gpio )
{
log_error("Invalid input arguments $gpio\n");
return -1;
}
-
if( !gpio->incnt && !gpio->outcnt )
{
@@ -58,7 +59,6 @@
}
log_info("gpiod initialise open chip ok\n");
-
/* gpiod request all output pins */
for(i=0; i<gpio->outcnt; i++)
{
@@ -66,19 +66,21 @@
if( !gpio->output[i].line )
{
log_error("gpiod get line for '%s' pin[#%d] failure\n", gpio->output[i].name, gpio->output[i].pin );
- return -2;
+ rv = -3;
+ goto failed;
}
if( gpiod_line_request_output(gpio->output[i].line, gpio->output[i].name, !gpio->output[i].active_level) < 0 )
{
log_error("gpiod request '%s' pin[#%d] output failure: %s\n", gpio->output[i].name, gpio->output[i].pin, strerror(errno));
+ rv = -3;
+ goto failed;
}
else
{
log_info("gpiod request '%s' pin[#%d] output ok\n", gpio->output[i].name, gpio->output[i].pin);
}
}
-
/* gpiod request all input pins */
for(i=0; i<gpio->incnt; i++)
@@ -87,7 +89,8 @@
if( !gpio->input[i].line )
{
log_error("gpiod get line for '%s' pin[#%d] failure\n", gpio->input[i].name, gpio->input[i].pin );
- return -2;
+ rv = -4;
+ goto failed;
}
if( gpio->output[i].active_level )
@@ -99,6 +102,8 @@
{
log_error("gpiod request '%s' pin[#%d] event edge [%s] failure: %s\n",
gpio->input[i].name, gpio->input[i].pin, gpio->output[i].active_level?"rising":"falling", strerror(errno));
+ rv = -4;
+ goto failed;
}
else
{
@@ -108,6 +113,10 @@
}
return 0;
+
+failed:
+ gpiod_chip_close(s_chip);
+ return rv;
}
@@ -122,12 +131,10 @@
return ;
}
-
for(i=0; i<s_gpio->outcnt; i++)
{
gpiod_line_release(s_gpio->output[i].line);
}
-
for(i=0; i<s_gpio->incnt; i++)
{
@@ -137,14 +144,16 @@
gpiod_chip_close(s_chip);
}
-void gpio_out(char *name, char *cmd)
+/* Turn light ON or OFF */
+void turn_light(char *name, int status)
{
int i;
int found = 0;
+ int value;
for( i=0; i<s_gpio->outcnt; i++ )
{
- if( !strncasecmp(s_gpio->output[i].name, name, strlen(name)))
+ if( strstr(s_gpio->output[i].name, name) )
{
found = 1;
break;
@@ -157,60 +166,11 @@
return ;
}
- if( strstr(cmd, "on") )
- {
- gpiod_line_set_value(s_gpio->output[i].line, s_gpio->output[i].active_level);
- }
- else if( strstr(cmd, "off") )
- {
- gpiod_line_set_value(s_gpio->output[i].line, !s_gpio->output[i].active_level);
- }
+ log_info("Turn %s light %s\n", name, status?"on":"off");
+ value = status ? s_gpio->output[i].active_level : !s_gpio->output[i].active_level;
+ gpiod_line_set_value(s_gpio->output[i].line, value);
return ;
-}
-
-
-void *light_on_worker(void *arg)
-{
- int i;
- int found = 0;
- char *name = (char *)arg;
- gpio_info_t *gpiout;
-
- if( !name )
- {
- log_error("Invalid input arugment\n");
- return NULL;
- }
-
- if( s_gpio->light_intval <= 0 )
- {
- log_error("Invalid light_intval value[%d] in configure file\n", s_gpio->light_intval);
- return NULL;
- }
-
- for(i=0; i<s_gpio->outcnt; i++)
- {
- if( strstr(s_gpio->output[i].name, name) )
- {
- gpiout = &(s_gpio->output[i]);
- found = 1;
- }
- }
-
- if( !found )
- {
- log_error("Light '%s' not found\n", name);
- return NULL;
- }
-
- log_info("Trun on %s for [%d] seconds\n", gpiout->name, s_gpio->light_intval);
-
- gpio_out(gpiout->name, "on");
- sleep(s_gpio->light_intval);
- gpio_out(gpiout->name, "off");
-
- return NULL;
}
/* Return value: 0(LOW): Nobody detected, !0: indoor or hallway detected */
@@ -218,14 +178,12 @@
{
int i;
int rv = 0;
- int res = 0;
+ int result = 0;
+ int num_lines = 0;
struct gpiod_line_event ev;
struct gpiod_line_bulk bulk, event_bulk;
struct gpiod_line *line;
-
- int num_lines = 0;
-
gpiod_line_bulk_init(&bulk);
@@ -244,7 +202,7 @@
return 0;
}
- log_debug("infrared start detect event now...\n");
+ log_debug("infrared start detect event(blocked) now...\n");
rv = gpiod_line_event_wait_bulk(&bulk, NULL, &event_bulk);
if( rv <= 0 )
{
@@ -270,25 +228,23 @@
{
if( s_gpio->input[i].active_level != gpiod_line_get_value(line) )
{
- //log_debug("infrared '%s' detect get wrong power level\n", s_gpio->input[i].name);
+ log_debug("infrared '%s' detect get wrong power level\n", s_gpio->input[i].name);
continue;
}
if( strstr(s_gpio->input[i].name, "indoor") )
{
log_debug("indoor infrared gpiod wait get event.\n", s_gpio->input[i].name);
- res |= FLAG_INFRARED_INDOOR;
+ result |= FLAG_INFRARED_INDOOR;
}
else if( strstr(s_gpio->input[i].name, "hallway") )
{
log_debug("hallway infrared gpiod wait get event.\n", s_gpio->input[i].name);
- res |= FLAG_INFRARED_HALLWAY;
+ result |= FLAG_INFRARED_HALLWAY;
}
}
}
}
- return res;
+ return result;
}
-
-
diff --git a/project/lightd/hal/gpio.h b/project/lightd/hal/gpio.h
index 29e970a..3a085e1 100644
--- a/project/lightd/hal/gpio.h
+++ b/project/lightd/hal/gpio.h
@@ -21,33 +21,28 @@
typedef struct gpio_info_s
{
- char name[32]; /* GPIO connected module name */
- int pin; /* GPIO BCM pin number */
- int active_level; /* active power level */
- struct gpiod_line *line; /* gpiod line */
+ struct gpiod_line *line; /* gpiod line */
+ char name[32]; /* GPIO connected module name */
+ int pin; /* GPIO BCM pin number */
+ int active_level; /* active power level */
} gpio_info_t;
-
typedef struct gpio_s
{
- gpio_info_t output[GPIO_MAXOUT]; /* GPIO output pins */
- int outcnt; /* GPIO output numbers */
- int light_intval; /* light on interval time */
+ gpio_info_t output[GPIO_MAXOUT]; /* GPIO output pins */
+ int outcnt; /* GPIO output numbers */
- gpio_info_t input[GPIO_MAXIN]; /* GPIO input pins */
- int incnt; /* GPIO input numbers */
- int infrared_enable; /* infrared enable or not */
+ gpio_info_t input[GPIO_MAXIN]; /* GPIO input pins */
+ int incnt; /* GPIO input numbers */
} gpio_t;
extern int gpio_init(gpio_t *gpio);
extern void gpio_term(void);
-/* turn which light on/off */
-extern void gpio_out(char *name, char *cmd);
-
-
-/*thread work body to turn light $name on for some seconds */
-void *light_on_worker(void *arg);
+/* turn which light ON/OFF */
+#define OFF 0
+#define ON 1
+extern void turn_light(char *name, int status);
/* Return value: 0(LOW): Nobody detected, !0: Which infrared detect incoming */
#define FLAG_INFRARED_INDOOR (1<<0)
diff --git a/project/lightd/hal/hal.c b/project/lightd/hal/hal.c
deleted file mode 100644
index 4c40b0e..0000000
--- a/project/lightd/hal/hal.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*********************************************************************************
- * Copyright: (C) 2019 LingYun IoT System Studio
- * All rights reserved.
- *
- * Filename: hal.c
- * Description: This file is RPi HAL(Hardware Abstract Layer) initial functions
- *
- * Version: 1.0.0(2019年06月24日)
- * Author: Guo Wenxue <guowenxue@gmail.com>
- * ChangeLog: 1, Release initial version on "2019年06月24日 23时46分47秒"
- *
- ********************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-
-#include "logger.h"
-#include "hal.h"
-
-int hal_init(hal_ctx_t *ctx)
-{
- if(!ctx)
- {
- log_error("Invalid input arguments\n");
- return -1;
- }
-
- if( ctx->sht2x_enable )
- {
- if( sht2x_init()< 0 )
- {
- log_error("R&H sensor SHT2X initialise failure\n");
- return -2;
- }
- else
- {
- log_info("R&H sensor SHT2X initialise okay\n");
- }
- }
-
- if( ctx->lux_enable )
- {
- if( tsl2561_init() < 0 )
- {
- log_error("LUX sensor TSL2561 initialise failure\n");
- return -2;
- }
- else
- {
- log_info("LUX sensor TSL2561 initialise okay\n");
- }
- }
-
- gpio_init(&ctx->gpio);
-
- return 0;
-}
-
-
-void hal_term(hal_ctx_t *ctx)
-{
- if(!ctx)
- {
- log_error("Invalid input arguments\n");
- return ;
- }
-
-
- if( ctx->sht2x_enable )
- {
- sht2x_term();
- }
-
- if( ctx->lux_enable )
- {
- tsl2561_term();
- }
-
- gpio_term();
-
- return ;
-}
-
diff --git a/project/lightd/hal/hal.h b/project/lightd/hal/hal.h
deleted file mode 100644
index be4af23..0000000
--- a/project/lightd/hal/hal.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*********************************************************************************
- * Copyright: (C) 2019 LingYun IoT System Studio
- * All rights reserved.
- *
- * Filename: hal.h
- * Description: This file is RPi HAL(Hardware Abstract Layer) initial functions
- *
- * Version: 1.0.0(2019年06月24日)
- * Author: Guo Wenxue <guowenxue@gmail.com>
- * ChangeLog: 1, Release initial version on "2019年06月24日 23时46分47秒"
- *
- ********************************************************************************/
-
-#ifndef _HAL_H_
-#define _HAL_H_
-
-#include "ds18b20.h"
-#include "sht20.h"
-#include "tsl2561.h"
-#include "gpio.h"
-
-
-typedef struct hal_ctx_s
-{
- int ds18b20_enable; /* 0:Disable !0: Enable */
- int sht2x_enable; /* 0:Disable !0: Enable */
-
- int lux_enable; /* 0:Disable !0: Enable */
- float lux_threshold; /* Lux Threshold value */
-
- gpio_t gpio; /* gpio intput/output pins */
-} hal_ctx_t;
-
-
-/* init hardware */
-extern int hal_init(hal_ctx_t *ctx);
-
-/* terminal hardware */
-extern void hal_term(hal_ctx_t *ctx);
-
-#endif /* ----- #ifndef _HAL_H_ ----- */
-
diff --git a/project/lightd/hal/makefile b/project/lightd/hal/makefile
index 608137a..3525db8 100644
--- a/project/lightd/hal/makefile
+++ b/project/lightd/hal/makefile
@@ -1,15 +1,36 @@
+#********************************************************************************
+# Copyright: (C) 2023 LingYun IoT System Studio
+# All rights reserved.
+#
+# Filename: Makefile
+# Description: This file used compile all the source code to static library
+#
+# Version: 1.0.0(11/08/23)
+# Author: Guo Wenxue <guowenxue@gmail.com>
+# ChangeLog: 1, Release initial version on "11/08/23 16:18:43"
+#
+#*******************************************************************************
-PWD=$(shell pwd )
+PWD=$(shell pwd)
+
+BUILD_ARCH=$(shell uname -m)
+ifneq ($(findstring $(BUILD_ARCH), "x86_64" "i386"),)
+ CROSS_COMPILE?=arm-linux-gnueabihf-
+endif
+
+#CROSS_COMPILE=
LIBNAME=$(shell basename ${PWD} )
TOPDIR=$(shell dirname ${PWD} )
all: clean
@rm -f *.o
- @${CROSSTOOL}gcc ${CFLAGS} -I${TOPDIR} -c *.c
- ${CROSSTOOL}ar -rcs lib${LIBNAME}.a *.o
+ @${CROSS_COMPILE}gcc ${CFLAGS} -I${TOPDIR} -c *.c
+ ${CROSS_COMPILE}ar -rcs lib${LIBNAME}.a *.o
clean:
@rm -f *.o
@rm -f *.a
+distclean:
+ @make clean
diff --git a/project/lightd/hal/sht20.c b/project/lightd/hal/sht20.c
deleted file mode 100644
index 25a2dc6..0000000
--- a/project/lightd/hal/sht20.c
+++ /dev/null
@@ -1,466 +0,0 @@
-/*********************************************************************************
- * Copyright: (C) 2018 LingYun IoT System Studio
- * All rights reserved.
- *
- * Filename: sht20.c
- * Description: This file is temperature and relative humidity sensor SHT20 code
- *
- * Version: 1.0.0(2018/10/14)
- * Author: Guo Wenxue <guowenxue@gmail.com>
- * ChangeLog: 1, Release initial version on "2018/10/14 12:13:26"
- *
- ********************************************************************************/
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <linux/types.h>
-#include <sys/stat.h>
-#include <linux/i2c.h>
-#include <linux/i2c-dev.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <string.h>
-#include <stdint.h>
-#include <time.h>
-#include <errno.h>
-#include <string.h>
-
-#include "sht20.h"
-#include "logger.h"
-#include "util_proc.h"
-
-static int s_sht2x_fd = -1;
-
-void sht2x_term(void)
-{
- close(s_sht2x_fd);
- s_sht2x_fd = -1;
- log_warn("Terminate SHT2X\n");
-}
-
-static inline void dump_buf(const char *prompt, uint8_t *buf, int size)
-{
- int i;
-
- if( !buf )
- {
- return ;
- }
-
- if( prompt )
- {
- printf("%s ", prompt);
- }
-
- for(i=0; i<size; i++)
- {
- printf("%02x ", buf[i]);
- }
- printf("\n");
-
- return ;
-}
-
-#ifdef I2C_API_RDWR /* Use I2C userspace driver read/write API */
-
-int sht2x_softreset(int fd)
-{
- uint8_t buf[4];
-
- if( fd<0 )
- {
- log_error("Invalid input arguments\n");
- return -1;
- }
-
- /* software reset SHT2x */
- memset(buf, 0, sizeof(buf));
-
- buf[0] = SOFTRESET;
- write(fd, buf, 1);
-
- msleep(50);
-
- return 0;
-}
-
-int sht2x_init(void)
-{
-
- if( (s_sht2x_fd=open("/dev/i2c-1", O_RDWR)) < 0)
- {
- log_error("i2c device open failed: %s\n", strerror(errno));
- return -1;
- }
-
- /* set I2C mode and SHT2x slave address */
- ioctl(s_sht2x_fd, I2C_TENBIT, 0); /* Not 10-bit but 7-bit mode */
- ioctl(s_sht2x_fd, I2C_SLAVE, 0x40); /* set SHT2x slava address 0x40*/
-
- if( sht2x_softreset(s_sht2x_fd) < 0 )
- {
- log_error("SHT2x softreset failure\n");
- sht2x_term();
- return -2;
- }
-
- log_debug("SHT2X initialise ok, s_sht2x_fd=%d\n", s_sht2x_fd);
- return s_sht2x_fd;
-}
-
-int sht2x_get_temp_humidity(float *temp, float *rh)
-{
- uint8_t buf[4];
-
- if( !temp || !rh )
- {
- log_error("Invalid input arguments\n");
- return -1;
- }
-
- if( s_sht2x_fd < 0 )
- {
- if( sht2x_init() < 0)
- {
- log_error("SHT2x initialise failure\n");
- return -2;
- }
- }
-
- /* send trigger temperature measure command and read the data */
- memset(buf, 0, sizeof(buf));
- buf[0]=TRIGGER_TEMPERATURE_NO_HOLD;
- write(s_sht2x_fd, buf, 1);
-
- msleep(85); /* datasheet: typ=66, max=85 */
-
- memset(buf, 0, sizeof(buf));
- read(s_sht2x_fd, buf, 3);
- //dump_buf("Temperature sample data: ", buf, 3);
- *temp = 175.72 * (((((int) buf[0]) << 8) + buf[1]) / 65536.0) - 46.85;
-
- /* send trigger humidity measure command and read the data */
- memset(buf, 0, sizeof(buf));
- buf[0] = TRIGGER_HUMIDITY_NO_HOLD;
- write(s_sht2x_fd, buf, 1);
-
- msleep(29); /* datasheet: typ=22, max=29 */
- memset(buf, 0, sizeof(buf));
-
- read(s_sht2x_fd, buf, 3);
- //dump_buf("Relative humidity sample data: ", buf, 3);
- *rh = 125 * (((((int) buf[0]) << 8) + buf[1]) / 65536.0) - 6;
-
- return 0;
-}
-
-int sht2x_get_serialnumber(uint8_t *serialnumber, int size)
-{
- uint8_t buf[4];
-
- if( !serialnumber || size!=8 )
- {
- log_error("Invalid input arguments\n");
- return -1;
- }
-
- if( s_sht2x_fd < 0 )
- {
- if( sht2x_init() < 0)
- {
- log_error("SHT2x initialise failure\n");
- return -2;
- }
- }
-
- /* Read SerialNumber from Location 1 */
- memset(buf, 0, sizeof(buf));
- buf[0] = 0xfa; /* command for readout on-chip memory */
- buf[1] = 0x0f; /* on-chip memory address */
- write(s_sht2x_fd, buf, 2);
-
- memset(buf, 0, sizeof(buf));
- read(s_sht2x_fd, buf, 4);
-
- serialnumber[5]=buf[0]; /* Read SNB_3 */
- serialnumber[4]=buf[1]; /* Read SNB_2 */
- serialnumber[3]=buf[2]; /* Read SNB_1 */
- serialnumber[2]=buf[3]; /* Read SNB_0 */
-
- /* Read SerialNumber from Location 2 */
- memset(buf, 0, sizeof(buf) );
- buf[0]=0xfc; /* command for readout on-chip memory */
- buf[1]=0xc9; /* on-chip memory address */
- write(s_sht2x_fd, buf, 2);
-
- memset(buf, 0, sizeof(buf) );
- read(s_sht2x_fd, buf, 4);
-
- serialnumber[1]=buf[0]; /* Read SNC_1 */
- serialnumber[0]=buf[1]; /* Read SNC_0 */
- serialnumber[7]=buf[2]; /* Read SNA_1 */
- serialnumber[6]=buf[3]; /* Read SNA_0 */
-
- //dump_buf("SHT2x Serial number: ", serialnumber, 8);
-
- return 0;
-}
-
-#elif (defined I2C_API_IOCTL) /* Use I2C userspace driver read/write API */
-
-int sht2x_softreset(int fd)
-{
- struct i2c_msg msg;
- struct i2c_rdwr_ioctl_data sht2x_data;
- uint8_t buf[2];
-
- if( fd<0 )
- {
- log_error("Invalid input arguments\n");
- return -1;
- }
-
- msg.addr= 0x40;
- msg.flags=0; //write
- msg.len= 1;
- msg.buf= buf;
- msg.buf[0]=SOFTRESET;
-
- sht2x_data.nmsgs= 1;
- sht2x_data.msgs= &msg;
-
- if( ioctl(fd, I2C_RDWR, &sht2x_data) < 0 )
- {
- log_error("sht2x I2C_RDWR ioctl failure: %s\n", strerror(errno));
- sht2x_term();
- return -2;
- }
-
- msleep(50);
-
- return 0;
-}
-
-
-int sht2x_init(void)
-{
- if( (s_sht2x_fd=open("/dev/i2c-1", O_RDWR)) < 0)
- {
- log_error("i2c device open failed: %s\n", strerror(errno));
- return -1;
- }
-
- if( sht2x_softreset(s_sht2x_fd) < 0 )
- {
- log_error("SHT2x softreset failure\n");
- sht2x_term();
- return -2;
- }
-
- log_debug("SHT2X initialise ok, s_sht2x_fd=%d\n", s_sht2x_fd);
- return 0;
-}
-
-int sht2x_get_serialnumber(uint8_t *serialnumber, int size)
-{
- struct i2c_msg msgs[2];
- struct i2c_rdwr_ioctl_data sht2x_data;
- uint8_t sbuf[2];
- uint8_t rbuf[4];
-
- if( !serialnumber || size!=8 )
- {
- log_error("Invalid input arguments\n");
- return -1;
- }
-
- if( s_sht2x_fd < 0 )
- {
- if( sht2x_init() < 0)
- {
- log_error("SHT2x initialise failure\n");
- return -2;
- }
- }
-
- /*+------------------------------------------+
- *| Read SerialNumber from Location 1 |
- *+------------------------------------------+*/
-
- msgs[0].addr= 0x40;
- msgs[0].flags=0; //write
- msgs[0].len= 2;
- msgs[0].buf= sbuf;
- msgs[0].buf[0]=0xfa; /* command for readout on-chip memory */
- msgs[0].buf[1]=0x0f; /* on-chip memory address */
-
- msgs[1].addr=0x40;
- msgs[1].flags=I2C_M_RD; //write
- msgs[1].len= 4;
- msgs[1].buf= rbuf;
-
- sht2x_data.nmsgs= 2;
- sht2x_data.msgs= msgs;
-
- if( ioctl(s_sht2x_fd, I2C_RDWR, &sht2x_data) < 0 )
- {
- log_error("sht2x I2C_RDWR ioctl failure: %s\n", strerror(errno));
- sht2x_term();
- return -2;
- }
-
- serialnumber[5]=rbuf[0]; /* Read SNB_3 */
- serialnumber[4]=rbuf[1]; /* Read SNB_2 */
- serialnumber[3]=rbuf[2]; /* Read SNB_1 */
- serialnumber[2]=rbuf[3]; /* Read SNB_0 */
-
-
- /*+------------------------------------------+
- *| Read SerialNumber from Location 2 |
- *+------------------------------------------+*/
-
- msgs[0].addr= 0x40;
- msgs[0].flags=0; //write
- msgs[0].len= 2;
- msgs[0].buf= sbuf;
- msgs[0].buf[0]=0xfc; /* command for readout on-chip memory */
- msgs[0].buf[1]=0xc9; /* on-chip memory address */
-
- msgs[1].addr=0x40;
- msgs[1].flags=I2C_M_RD; //write
- msgs[1].len= 4;
- msgs[1].buf= rbuf;
-
- sht2x_data.nmsgs= 2;
- sht2x_data.msgs= msgs;
-
- if( ioctl(s_sht2x_fd, I2C_RDWR, &sht2x_data) < 0 )
- {
- log_error("sht2x I2C_RDWR ioctl failure: %s\n", strerror(errno));
- sht2x_term();
- return -2;
- }
-
- serialnumber[1]=rbuf[0]; /* Read SNC_1 */
- serialnumber[0]=rbuf[1]; /* Read SNC_0 */
- serialnumber[7]=rbuf[2]; /* Read SNA_1 */
- serialnumber[6]=rbuf[3]; /* Read SNA_0 */
-
- //dump_buf("SHT2x Serial number: ", serialnumber, 8);
-
- return 0;
-}
-
-
-int sht2x_get_temp_humidity(float *temp, float *rh)
-{
- struct i2c_msg msg;
- struct i2c_rdwr_ioctl_data sht2x_data;
- uint8_t buf[4];
-
- if( !temp || !rh )
- {
- log_error("Invalid input arguments\n");
- return -1;
- }
-
- if( s_sht2x_fd < 0 )
- {
- if( sht2x_init() < 0)
- {
- log_error("SHT2x initialise failure\n");
- return -2;
- }
- }
-
- /*+------------------------------------------+
- *| measure and get temperature |
- *+------------------------------------------+*/
-
- msg.addr= 0x40;
- msg.flags=0; //write
- msg.len= 1;
- msg.buf= buf;
- msg.buf[0]=TRIGGER_TEMPERATURE_NO_HOLD; /* trigger temperature without hold I2C bus */
-
- sht2x_data.nmsgs= 1;
- sht2x_data.msgs= &msg;
-
- if( ioctl(s_sht2x_fd, I2C_RDWR, &sht2x_data) < 0 )
- {
- log_error("sht2x I2C_RDWR ioctl failure: %s\n", strerror(errno));
- sht2x_term();
- return -2;
- }
-
- msleep(85);
-
- memset(buf, 0, sizeof(buf));
- msg.addr=0x40;
- msg.flags=I2C_M_RD; //write
- msg.len= 3;
- msg.buf= buf;
-
- sht2x_data.nmsgs= 1;
- sht2x_data.msgs= &msg;
-
- if( ioctl(s_sht2x_fd, I2C_RDWR, &sht2x_data) < 0 )
- {
- log_error("sht2x I2C_RDWR ioctl failure: %s\n", strerror(errno));
- sht2x_term();
- return -2;
- }
-
- //dump_buf("Temperature sample data: ", buf, 3);
- *temp = 175.72 * (((((int) buf[0]) << 8) + buf[1]) / 65536.0) - 46.85;
-
-
- /*+------------------------------------------+
- *| measure and get relative humidity |
- *+------------------------------------------+*/
-
- msg.addr= 0x40;
- msg.flags=0; //write
- msg.len= 1;
- msg.buf= buf;
- msg.buf[0]=TRIGGER_HUMIDITY_NO_HOLD; /* trigger humidity without hold I2C bus */
-
- sht2x_data.nmsgs= 1;
- sht2x_data.msgs= &msg;
-
- if( ioctl(s_sht2x_fd, I2C_RDWR, &sht2x_data) < 0 )
- {
- log_error("sht2x I2C_RDWR ioctl failure: %s\n", strerror(errno));
- sht2x_term();
- return -2;
- }
-
- msleep(29);
-
- memset(buf, 0, sizeof(buf));
- msg.addr=0x40;
- msg.flags=I2C_M_RD; //write
- msg.len= 3;
- msg.buf= buf;
-
- sht2x_data.nmsgs= 1;
- sht2x_data.msgs= &msg;
-
- if( ioctl(s_sht2x_fd, I2C_RDWR, &sht2x_data) < 0 )
- {
- log_error("sht2x I2C_RDWR ioctl failure: %s\n", strerror(errno));
- sht2x_term();
- return -2;
- }
-
- //dump_buf("Relative humidity sample data: ", buf, 3);
- *rh = 125 * (((((int) buf[0]) << 8) + buf[1]) / 65536.0) - 6;
-
- return 0;
-}
-
-#endif
-
diff --git a/project/lightd/hal/sht20.h b/project/lightd/hal/sht20.h
deleted file mode 100644
index e327105..0000000
--- a/project/lightd/hal/sht20.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*********************************************************************************
- * Copyright: (C) 2018 LingYun IoT System Studio
- * All rights reserved.
- *
- * Filename: sht20.c
- * Description: This file is temperature and relative humidity sensor SHT20 code
- *
- * Version: 1.0.0(2018/10/14)
- * Author: Guo Wenxue <guowenxue@gmail.com>
- * ChangeLog: 1, Release initial version on "2018/10/14 12:13:26"
- *
- ********************************************************************************/
-#ifndef __SHT20_H
-#define __SHT20_H
-
-#include <stdio.h>
-#include <stdint.h>
-#include <time.h>
-
-#define SOFTRESET 0xFE
-#define TRIGGER_TEMPERATURE_NO_HOLD 0xF3
-#define TRIGGER_HUMIDITY_NO_HOLD 0xF5
-
-//#define I2C_API_IOCTL /* Use I2C userspace driver ioctl API */
-#define I2C_API_RDWR /* Use I2C userspace driver read/write API */
-
-int sht2x_init(void);
-int sht2x_get_serialnumber(uint8_t *serialnumber, int size);
-int sht2x_get_temp_humidity(float *temp, float *rh);
-void sht2x_term(void);
-
-#endif
-
diff --git a/project/lightd/hal/tsl2561.c b/project/lightd/hal/tsl2561.c
index 2a8dcb6..b912433 100644
--- a/project/lightd/hal/tsl2561.c
+++ b/project/lightd/hal/tsl2561.c
@@ -1,14 +1,23 @@
/*********************************************************************************
- * Copyright: (C) 2019 LingYun IoT System Studio
+ * Copyright: (C) 2023 LingYun IoT System Studio
* All rights reserved.
*
* Filename: tsl2561.c
- * Description: This file is the Lux sensor TSL2561 API functions on RaspberryPi,
- * which connected to I2C-1
+ * Description: This file is the Lux sensor TSL2561 code
*
- * Version: 1.0.0(04/07/19)
+ * Version: 1.0.0(10/08/23)
* Author: Guo Wenxue <guowenxue@gmail.com>
- * ChangeLog: 1, Release initial version on "04/07/19 17:39:38"
+ * ChangeLog: 1, Release initial version on "10/08/23 17:52:00"
+ *
+ * Pin connection:
+ * TSL2561 Module Raspberry Pi Board
+ * VCC <-----> #Pin1(3.3V)
+ * SDA0 <-----> #Pin27(SDA, BCM GPIO0)
+ * SCL0 <-----> #Pin28(SCL, BCM GPIO1)
+ * GND <-----> GND
+ *
+ * /boot/config.txt:
+ * dtoverlay=i2c0,pins_0_1
*
********************************************************************************/
@@ -17,57 +26,52 @@
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
-#include <errno.h>
#include <time.h>
-
+#include <errno.h>
+#include <libgen.h>
+#include <getopt.h>
+#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <fcntl.h>
-#include "logger.h"
#include "util_proc.h"
+#include "logger.h"
#include "tsl2561.h"
-int s_tsl_fd = -1;
+
+#define CONTROL_REG 0x80
+#define REG_COUNT 4
+
+#define POWER_UP 0x03
+#define POWER_DOWN 0x00
+
+#define OFF 0
+#define ON 1
+
+/* Register Address */
+enum
+{
+ /* Channel_0 = DATA0HIGH<<8 + DATA0LOW */
+ DATA0LOW = 0x8C,
+ DATA0HIGH,
+
+ /* Channel_1 = DATA1HIGH<<8 + DATA1LOW */
+ DATA1LOW,
+ DATA1HIGH,
+};
static const int regs_addr[REG_COUNT]={DATA0LOW, DATA0HIGH, DATA1LOW, DATA1HIGH};
-int tsl2561_init(void)
-{
- if(s_tsl_fd > 0)
- return 0;
-
- if( (s_tsl_fd=open("/dev/i2c-1", O_RDWR)) < 0)
- {
- log_error("TSL2561 I2C device setup failure: %s\n", strerror(errno));
- return -1;
- }
-
- log_debug("TSL2561 initialise ok, s_tsl_fd=%d\n", s_tsl_fd);
- return s_tsl_fd;
-}
-
-void tsl2561_term(void)
-{
- close(s_tsl_fd);
- s_tsl_fd = -1;
- log_warn("Terminate TSL2561.\n");
-}
-
-
-#define ON 1
-#define OFF 0
-
-int tsl2561_power(int cmd)
+void tsl2561_power(int fd, int cmd)
{
struct i2c_msg msg;
struct i2c_rdwr_ioctl_data data;
unsigned char buf[2];
- msg.addr= TSL2561_I2C_ADDR;
+ msg.addr= TSL2561_I2CADDR;
msg.flags=0; /* write */
msg.len= 1;
msg.buf= buf;
@@ -76,10 +80,10 @@
data.msgs= &msg;
msg.buf[0]=CONTROL_REG;
- if( ioctl(s_tsl_fd, I2C_RDWR, &data) < 0 )
+ if( ioctl(fd, I2C_RDWR, &data) < 0 )
{
log_error("%s() ioctl failure: %s\n", __func__, strerror(errno));
- return -1;
+ return ;
}
@@ -88,22 +92,22 @@
else
msg.buf[0]=POWER_DOWN;
- if( ioctl(s_tsl_fd, I2C_RDWR, &data) < 0 )
+ if( ioctl(fd, I2C_RDWR, &data) < 0 )
{
log_error("%s() ioctl failure: %s\n", __func__, strerror(errno));
- return -1;
+ return ;
}
- return 0;
+ return ;
}
-int tsl2561_readreg(unsigned char regaddr, unsigned char *regval)
+int tsl2561_readreg(int fd, unsigned char regaddr, unsigned char *regval)
{
struct i2c_msg msg;
struct i2c_rdwr_ioctl_data data;
unsigned char buf[2];
- msg.addr= TSL2561_I2C_ADDR;
+ msg.addr= TSL2561_I2CADDR;
msg.flags=0; /* write */
msg.len= 1;
msg.buf= buf;
@@ -112,7 +116,7 @@
data.nmsgs= 1;
data.msgs= &msg;
- if( ioctl(s_tsl_fd, I2C_RDWR, &data) < 0 )
+ if( ioctl(fd, I2C_RDWR, &data) < 0 )
{
log_error("%s() ioctl failure: %s\n", __func__, strerror(errno));
return -1;
@@ -120,7 +124,7 @@
memset(buf, 0, sizeof(buf));
- msg.addr= TSL2561_I2C_ADDR;
+ msg.addr= TSL2561_I2CADDR;
msg.flags=I2C_M_RD; /* read */
msg.len= 1;
msg.buf= buf;
@@ -128,7 +132,7 @@
data.nmsgs= 1;
data.msgs= &msg;
- if( ioctl(s_tsl_fd, I2C_RDWR, &data) < 0 )
+ if( ioctl(fd, I2C_RDWR, &data) < 0 )
{
log_error("%s() ioctl failure: %s\n", __func__, strerror(errno));
return -1;
@@ -138,28 +142,39 @@
return 0;
}
-
-
-float tsl2561_get_lux(void)
+int tsl2561_get_lux(float *lux)
{
- int i;
- unsigned char reg_data[REG_COUNT];
+ int i, fd;
+ int rv = 0;
+ char *dev = TSL2561_I2CDEV;
+ float div = 0.0;
+ unsigned char reg_data[REG_COUNT];
int chn0_data = 0;
int chn1_data = 0;
- float div = 0.0;
- float lux = 0.0;
+ if( !lux )
+ {
+ log_error("Invalid input arguments\n");
+ return -1;
+ }
+ if( (fd=open(dev, O_RDWR)) < 0)
+ {
+ log_error("i2c device '%s' open failed: %s\n", dev, strerror(errno));
+ return -2;
+ }
- tsl2561_power(ON);
+ tsl2561_power(fd, ON);
msleep(410); /* t(CONV) MAX 400ms */
/* Read register Channel0 and channel1 data from register */
for(i=0; i<REG_COUNT; i++)
{
- tsl2561_readreg(regs_addr[i], ®_data[i]);
+ rv = tsl2561_readreg(fd, regs_addr[i], ®_data[i]);
+ if( rv < 0)
+ goto failed;
}
chn0_data = reg_data[1]*256 + reg_data[0]; /* Channel0 = DATA0HIGH<<8 + DATA0LOW */
@@ -167,32 +182,31 @@
if( chn0_data<=0 || chn1_data<0 )
{
- lux = 0.0;
- goto OUT;
+ rv = -2;
+ goto cleanup;
}
div = (float)chn1_data / (float)chn0_data;
if( div>0 && div<=0.5 )
- lux = 0.304*chn0_data-0.062*chn0_data*pow(div,1.4);
+ *lux = 0.304*chn0_data-0.062*chn0_data*pow(div,1.4);
else if( div>0.5 && div<=0.61 )
- lux = 0.0224*chn0_data-0.031*chn1_data;
+ *lux = 0.0224*chn0_data-0.031*chn1_data;
else if( div>0.61 && div<=0.8 )
- lux = 0.0128*chn0_data-0.0153*chn1_data;
+ *lux = 0.0128*chn0_data-0.0153*chn1_data;
else if( div>0.8 && div<=1.3 )
- lux = 0.00146*chn0_data-0.00112*chn1_data;
+ *lux = 0.00146*chn0_data-0.00112*chn1_data;
else if( div>1.3 )
- lux = 0.0;
+ *lux = 0.0;
- log_debug("TSLl2561 get lux: %.3f\n", lux);
+cleanup:
+ tsl2561_power(fd, OFF);
-OUT:
- tsl2561_power(OFF);
- return lux;
+failed:
+ close(fd);
+ return rv;
}
-
-
diff --git a/project/lightd/hal/tsl2561.h b/project/lightd/hal/tsl2561.h
index 3a92a6a..540a0bd 100644
--- a/project/lightd/hal/tsl2561.h
+++ b/project/lightd/hal/tsl2561.h
@@ -1,42 +1,34 @@
-/********************************************************************************
- * Copyright: (C) 2019 LingYun IoT System Studio
+/*********************************************************************************
+ * Copyright: (C) 2023 LingYun IoT System Studio
* All rights reserved.
*
* Filename: tsl2561.h
- * Description: This head file is the Lux sensor TSL2561 API functions on RaspberryPi
+ * Description: This file is the Lux sensor TSL2561 code
*
- * Version: 1.0.0(04/07/19)
+ * Version: 1.0.0(10/08/23)
* Author: Guo Wenxue <guowenxue@gmail.com>
- * ChangeLog: 1, Release initial version on "04/07/19 17:42:35"
+ * ChangeLog: 1, Release initial version on "10/08/23 17:52:00"
+ *
+ * Pin connection:
+ * TSL2561 Module Raspberry Pi Board
+ * VCC <-----> #Pin1(3.3V)
+ * SDA0 <-----> #Pin27(SDA, BCM GPIO0)
+ * SCL0 <-----> #Pin28(SCL, BCM GPIO1)
+ * GND <-----> GND
+ *
+ * /boot/config.txt:
+ * dtoverlay=i2c0,pins_0_1
*
********************************************************************************/
#ifndef _TSL2561_H_
#define _TSL2561_H_
-#define TSL2561_I2C_ADDR 0x39
+#define TSL2561_I2CDEV "/dev/i2c-0"
+#define TSL2561_I2CADDR 0x39
-#define CONTROL_REG 0x80
-#define REG_COUNT 4
-
-#define POWER_UP 0x03
-#define POWER_DOWN 0x00
-
-/* Register Address */
-enum
-{
- /* Channel_0 = DATA0HIGH<<8 + DATA0LOW */
- DATA0LOW = 0x8C,
- DATA0HIGH,
-
- /* Channel_1 = DATA1HIGH<<8 + DATA1LOW */
- DATA1LOW,
- DATA1HIGH,
-};
-
-extern int tsl2561_init(void);
-extern void tsl2561_term(void);
-extern float tsl2561_get_lux(void);
+extern int tsl2561_get_lux(float *lux);
#endif /* ----- #ifndef _TSL2561_H_ ----- */
+
diff --git a/project/lightd/lightd.c b/project/lightd/lightd.c
new file mode 100644
index 0000000..3e70513
--- /dev/null
+++ b/project/lightd/lightd.c
@@ -0,0 +1,378 @@
+/*********************************************************************************
+ * Copyright: (C) 2019 LingYun IoT System Studio
+ * All rights reserved.
+ *
+ * Filename: main.c
+ * Description: This file
+ *
+ * Version: 1.0.0(29/01/19)
+ * Author: Guo Wenxue <guowenxue@gmail.com>
+ * ChangeLog: 1, Release initial version on "29/01/19 15:34:41"
+ *
+ ********************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <getopt.h>
+#include <libgen.h>
+#include <string.h>
+#include <errno.h>
+
+#include <mosquitto.h>
+#include <cjson/cJSON.h>
+
+#include "logger.h"
+#include "util_proc.h"
+#include "config.h"
+#include "tsl2561.h"
+
+#define PROG_VERSION "v1.0.0"
+#define DAEMON_PIDFILE "/tmp/.lightd.pid"
+
+int check_sample_time(time_t *last_time, int interval);
+void *thingsboard_subsciber(void *args);
+void *thingsboard_publisher(void *args);
+
+static void program_usage(char *progname)
+{
+
+ printf("Usage: %s [OPTION]...\n", progname);
+ printf(" %s is LingYun studio MQTT daemon program running on RaspberryPi\n", progname);
+
+ printf("\nMandatory arguments to long options are mandatory for short options too:\n");
+ printf(" -b[daemon ] Running in daemon mode\n");
+ printf(" -d[debug ] Running in debug mode\n");
+ printf(" -c[conf ] Specify configure file\n");
+ printf(" -h[help ] Display this help information\n");
+ printf(" -v[version ] Display the program version\n");
+
+ printf("\n%s version %s\n", progname, PROG_VERSION);
+ return;
+}
+
+int main (int argc, char **argv)
+{
+ int daemon = 0;
+ char *conf_file="/etc/lightd.conf";
+ int debug = 0;
+ int opt;
+ char *progname=NULL;
+ pthread_t tid;
+
+ int rv;
+ float lux = 0.0;
+ time_t last_time = 0;
+ iotd_ctx_t ctx;
+ hwinfo_t *hwinfo = &ctx.hwinfo;
+
+ struct option long_options[] = {
+ {"conf", required_argument, NULL, 'c'},
+ {"daemon", no_argument, NULL, 'b'},
+ {"debug", no_argument, NULL, 'd'},
+ {"version", no_argument, NULL, 'v'},
+ {"help", no_argument, NULL, 'h'},
+ {NULL, 0, NULL, 0}
+ };
+
+ progname = (char *)basename(argv[0]);
+
+ /* parser the command line parameters */
+ while ((opt = getopt_long(argc, argv, "c:bdvh", long_options, NULL)) != -1)
+ {
+ switch (opt)
+ {
+ case 'c': /* Set configure file */
+ conf_file = optarg;
+ break;
+
+ case 'b': /* Set daemon running */
+ daemon = 1;
+ break;
+
+ case 'd': /* Set debug running */
+ debug = 1;
+ break;
+
+ case 'v': /* Get software version */
+ printf("%s version %s\n", progname, PROG_VERSION);
+ return 0;
+
+ case 'h': /* Get help information */
+ program_usage(progname);
+ return 0;
+
+ default:
+ break;
+ }
+
+ }
+
+ /* parser configure file */
+ if( parser_conf(conf_file, &ctx, debug)<0 )
+ {
+ fprintf(stderr, "Parser thingsboard configure file failure\n");
+ return -2;
+ }
+
+ /* install signal proc handler */
+ install_default_signal();
+
+ /* check program already running or not, if already running then exit, or set running as daemon */
+ if( check_set_program_running(daemon, DAEMON_PIDFILE) < 0 )
+ goto cleanup;
+
+ /* initial mosquitto library */
+ mosquitto_lib_init();
+
+ /* initial gpio hardware */
+ gpio_init(&hwinfo->gpio);
+
+ /*
+ * +--------------------------------+
+ * | MQTT Subscriber Thread |
+ * +--------------------------------+
+ */
+ if( thread_start(&tid, thingsboard_subsciber, &ctx.mqtt ) < 0 )
+ {
+ log_error("Start MQTT subsciber worker thread failure\n");
+ goto cleanup;
+ }
+ log_info("Start MQTT subsciber worker thread ok\n");
+
+ /*
+ * +--------------------------------+
+ * | Auto Light Control Thread |
+ * +--------------------------------+
+ */
+
+ log_info("Auto light control thread start\n");
+ while( ! g_signal.stop )
+ {
+ /* TSL2561 update lux in every 5 minutes */
+ if(check_sample_time(&last_time, 300))
+ {
+ if( tsl2561_get_lux(&lux) < 0 )
+ {
+ log_error("TSL2561 sample Lux failed\n");
+ lux = hwinfo->lux_threshold + 100.0;
+ }
+
+ if( lux > hwinfo->lux_threshold )
+ log_info("Lux[%.3f] > Treshold[%.3f], don't auto light\n", lux, hwinfo->lux_threshold);
+ else
+ log_info("Lux[%.3f] <= Treshold[%.3f], need auto light\n", lux, hwinfo->lux_threshold);
+ }
+
+ if( lux > hwinfo->lux_threshold )
+ {
+ sleep(1);
+ continue;
+ }
+
+ rv = infrared_detect();
+ if( rv != 0 )
+ {
+ log_warn("Someone incoming detected by %s infrared\n", rv&FLAG_INFRARED_INDOOR?"indoor":"hallway");
+
+ turn_light("indoor", ON);
+ turn_light("hallway", ON);
+
+ sleep(hwinfo->light_intval);
+
+ turn_light("indoor", ON);
+ turn_light("hallway", ON);
+ }
+
+ msleep(100);
+ }
+
+cleanup:
+ mosquitto_lib_cleanup();
+ log_close();
+
+ return 0;
+}
+
+int check_sample_time(time_t *last_time, int interval)
+{
+ int need = 0; /* no need sample now */
+ time_t now;
+
+ time(&now);
+
+ if( difftime(now, *last_time)>interval )
+ {
+ need = 1; /* need sample now */
+ *last_time = now;
+ }
+
+ return need;
+}
+
+void sub_connect_callback(struct mosquitto *mosq, void *userdata, int result)
+{
+ mqtt_ctx_t *ctx = (mqtt_ctx_t *)userdata;
+
+ if( result )
+ {
+ log_error("Subscriber connect to broker server failed, rv=%d\n", result);
+ return ;
+ }
+
+ log_info("Subscriber connect to broker server[%s:%d] successfully\n", ctx->host, ctx->port);
+ mosquitto_subscribe(mosq, NULL, ctx->subTopic, ctx->subQos);
+}
+
+void sub_disconnect_callback(struct mosquitto *mosq, void *userdata, int result)
+{
+ mqtt_ctx_t *ctx = (mqtt_ctx_t *)userdata;
+
+ log_warn("Subscriber disconnect to broker server[%s:%d], reason=%d\n", ctx->host, ctx->port, result);
+}
+
+void proc_json_items(cJSON *root, mqtt_ctx_t *ctx)
+{
+ cJSON *item_method;
+ cJSON *item_params;
+ cJSON *item_device;
+ cJSON *item_status;
+
+ char *method;
+ char *device;
+ int status;
+
+ /* 获取 method 字段 */
+ item_method = cJSON_GetObjectItem(root, "method");
+ if (item_method == NULL || !cJSON_IsString(item_method))
+ {
+ log_error("JSON missing method\n");
+ return;
+ }
+ method = item_method->valuestring;
+
+ /* 只处理 setValue 命令 */
+ if (strcmp(method, "setValue") != 0)
+ {
+ log_error("Ignore method: %s\n", method);
+ return;
+ }
+
+ /* 获取 params 对象 */
+ item_params = cJSON_GetObjectItem(root, "params");
+ if (item_params == NULL || !cJSON_IsObject(item_params))
+ {
+ log_error("JSON missing params\n");
+ return;
+ }
+
+ /* 获取 params.device */
+ item_device = cJSON_GetObjectItem(item_params, "device");
+ if (item_device == NULL || !cJSON_IsString(item_device))
+ {
+ log_error("JSON missing params.device\n");
+ return;
+ }
+ device = item_device->valuestring;
+
+ /* 获取 params.status (布尔值) */
+ item_status = cJSON_GetObjectItem(item_params, "status");
+ if (item_status == NULL || !(cJSON_IsBool(item_status)))
+ {
+ log_error("JSON missing params.status\n");
+ return;
+ }
+ status = cJSON_IsTrue(item_status) ? ON : OFF;
+
+ log_info("parser JSON message to control '%s' status '%d'\n", device, status);
+
+ /* 映射 Light 名称并调用控制函数 */
+ if ( strstr(device, "Indoor") || strstr(device, "indoor"))
+ {
+ turn_light("indoor", status);
+ }
+ else if ( strstr(device, "Hallway") || strstr(device, "hallway") )
+ {
+ turn_light("hallway", status);
+ }
+
+ return;
+}
+
+void sub_message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)
+{
+ mqtt_ctx_t *ctx = (mqtt_ctx_t *)userdata;
+
+ cJSON *root = NULL;
+
+ if ( !message->payloadlen )
+ {
+ log_error("%s (null)\n", message->topic);
+ return ;
+ }
+
+ log_info("Subscriber receive message: '%s'\n", message->payload);
+
+ root = cJSON_Parse(message->payload);
+ if( !root )
+ {
+ log_error("cJSON_Parse parser failure: %s\n", cJSON_GetErrorPtr());
+ return ;
+ }
+
+ proc_json_items(root, ctx);
+
+ /* must delete it, or it will result memory leak */
+ cJSON_Delete(root);
+
+ return ;
+}
+
+void *thingsboard_subsciber(void *args)
+{
+ mqtt_ctx_t *ctx = (mqtt_ctx_t *)args;
+ struct mosquitto *mosq;
+ bool session = true;
+
+ mosq = mosquitto_new(ctx->devid, session, ctx);
+ if( !mosq )
+ {
+ log_error("mosquitto_new failure\n");
+ return NULL;
+ }
+
+ /* connnect to broker by token or uid/pwd */
+ if( strlen(ctx->token ) > 0)
+ {
+ log_info("Using token authentication\n");
+ mosquitto_username_pw_set(mosq, ctx->token, NULL);
+ }
+ else if( strlen(ctx->uid)> 0 && strlen(ctx->pwd)> 0 )
+ {
+ log_info("Using username/password authentication\n");
+ mosquitto_username_pw_set(mosq, ctx->uid, ctx->pwd);
+ }
+
+ /* set callback functions */
+ mosquitto_connect_callback_set(mosq, sub_connect_callback);
+ mosquitto_disconnect_callback_set(mosq, sub_disconnect_callback);
+ mosquitto_message_callback_set(mosq, sub_message_callback);
+
+ while( !g_signal.stop )
+ {
+ /* connect to MQTT broker */
+ if( mosquitto_connect(mosq, ctx->host, ctx->port, ctx->keepalive) )
+ {
+ log_error("Subscriber connect to broker[%s:%d] failure: %s\n", ctx->host, ctx->port, strerror(errno));
+ msleep(1000);
+ continue;
+ }
+
+ /* -1: use default timeout 1000ms 1: unused */
+ mosquitto_loop_forever(mosq, -1, 1);
+ }
+
+ mosquitto_destroy(mosq);
+ return NULL;
+}
+
diff --git a/project/lightd/main.c b/project/lightd/main.c
deleted file mode 100644
index c72ecce..0000000
--- a/project/lightd/main.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*********************************************************************************
- * Copyright: (C) 2019 LingYun IoT System Studio
- * All rights reserved.
- *
- * Filename: main.c
- * Description: This is the lux/relay/infrared auto light program
- *
- * Version: 1.0.0(29/01/19)
- * Author: Guo Wenxue <guowenxue@gmail.com>
- * ChangeLog: 1, Release initial version on "29/01/19 15:34:41"
- *
- ********************************************************************************/
-#include <stdio.h>
-#include <time.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <libgen.h>
-#include <string.h>
-#include <math.h>
-
-#include <cjson/cJSON.h>
-#include <mosquitto.h>
-
-#include "util_proc.h"
-#include "logger.h"
-#include "hal.h"
-
-#include "conf.h"
-#include "mqtt.h"
-
-#define PROG_VERSION "v1.0.0"
-#define DAEMON_PIDFILE "/tmp/.iotd.pid"
-
-void control_thread_loop(void *args);
-
-static void program_usage(char *progname)
-{
- printf("Usage: %s [OPTION]...\n", progname);
- printf(" %s is LingYun studio MQTT daemon program running on RaspberryPi\n", progname);
-
- printf("\nMandatory arguments to long options are mandatory for short options too:\n");
- printf(" -d[debug ] Running in debug mode\n");
- printf(" -c[conf ] Specify configure file\n");
- printf(" -h[help ] Display this help information\n");
- printf(" -v[version ] Display the program version\n");
-
- printf("\n%s version %s\n", progname, PROG_VERSION);
- return;
-}
-
-int main (int argc, char **argv)
-{
- int daemon = 1;
- pthread_t tid;
- iotd_ctx_t ctx;
- hal_ctx_t *hal_ctx = &ctx.hal_ctx;
- char *conf_file="/etc/iotd.conf";
- int debug = 0;
- int opt;
- char *progname=NULL;
-
- struct option long_options[] = {
- {"conf", required_argument, NULL, 'c'},
- {"debug", no_argument, NULL, 'd'},
- {"version", no_argument, NULL, 'v'},
- {"help", no_argument, NULL, 'h'},
- {NULL, 0, NULL, 0}
- };
-
- progname = (char *)basename(argv[0]);
-
- /* Parser the command line parameters */
- while ((opt = getopt_long(argc, argv, "c:dvh", long_options, NULL)) != -1)
- {
- switch (opt)
- {
- case 'c': /* Set configure file */
- conf_file = optarg;
- break;
-
- case 'd': /* Set debug running */
- daemon = 0;
- debug = 1;
- break;
-
- case 'v': /* Get software version */
- printf("%s version %s\n", progname, PROG_VERSION);
- return 0;
-
- case 'h': /* Get help information */
- program_usage(progname);
- return 0;
-
- default:
- break;
- }
-
- }
-
-
- if( !conf_file )
- debug = 1;
-
- if( parser_conf(conf_file, &ctx, debug)<0 )
- {
- fprintf(stderr, "Parser mqtted configure file failure\n");
- return -2;
- }
-
-
- if( hal_init(hal_ctx) < 0 )
- {
- log_error("Initialise hardware failure\n");
- return -3;
- }
- log_info("Initialise hardware okay.\n");
-
-
- install_default_signal();
- if( check_set_program_running(daemon, DAEMON_PIDFILE) < 0 )
- goto OUT;
-
-
- mosquitto_lib_init();
-
- /*+--------------------------------------------+
- *| Start MQTT subsciber thread if enable |
- *+--------------------------------------------+*/
- if( ctx.mqtt_ctx.sub_enable )
- {
- if( thread_start(&tid, mqtt_sub_worker, &ctx ) < 0 )
- {
- log_error("Start MQTT subsciber worker thread failure\n");
- goto OUT;
- }
- else
- {
- log_info("Start MQTT subsciber worker thread ok\n");
- }
- }
-
- /*+--------------------------------------------+
- *| Start MQTT publisher thread if enable |
- *+--------------------------------------------+*/
- if( ctx.mqtt_ctx.pub_enable )
- {
- if( thread_start(&tid, mqtt_pub_worker, &ctx ) < 0 )
- {
- log_error("Start MQTT publisher worker thread failure\n");
- goto OUT;
- }
- else
- {
- log_info("Start MQTT publisher worker thread ok\n");
- }
- }
-
- /*+--------------------------------------------+
- *| Control thread start dead loop |
- *+--------------------------------------------+*/
- control_thread_loop(&ctx);
-
-OUT:
- mosquitto_lib_cleanup();
- hal_term(hal_ctx);
- log_close();
-
- return 0;
-} /* ----- End of main() ----- */
-
-
-void control_thread_loop(void *args)
-{
- iotd_ctx_t *ctx = (iotd_ctx_t *)args;
- hal_ctx_t *hal_ctx;
- float lux = 0.0;
- int rv;
-
- hal_ctx = &ctx->hal_ctx;
-
- log_debug("infrared configured [%d], lux configured [%d]\n", hal_ctx->gpio.infrared_enable, hal_ctx->lux_enable);
-
- while( ! g_signal.stop )
- {
- if( hal_ctx->gpio.infrared_enable )
- {
- if( hal_ctx->lux_enable )
- {
- lux = tsl2561_get_lux();
-
- log_debug("TSL2561 get Lux[%.3f] Treshold[%.3f].\n", lux, hal_ctx->lux_threshold);
-
- if( lux > hal_ctx->lux_threshold )
- {
- log_info("Lux[%.3f] > Treshold[%.3f], don't need light on and sleep now.\n", lux, hal_ctx->lux_threshold);
- if( hal_ctx->gpio.light_intval > 0)
- sleep( hal_ctx->gpio.light_intval );
- else
- sleep(30);
-
- continue;
- }
- }
-
- rv = infrared_detect();
- if( rv & FLAG_INFRARED_INDOOR )
- {
- log_info("Someone incoming detected by indoor infrared\n");
- thread_start(NULL, light_on_worker, "indoor" );
- }
-
- if( rv & FLAG_INFRARED_HALLWAY )
- {
- log_info("Someone incoming detected by hallway infrared\n");
- thread_start(NULL, light_on_worker, "hallway" );
- }
- }
-
- msleep(100);
- }
-}
-
-
diff --git a/project/lightd/makefile b/project/lightd/makefile
index 3797387..2920afa 100644
--- a/project/lightd/makefile
+++ b/project/lightd/makefile
@@ -12,7 +12,7 @@
#*******************************************************************************
PRJ_PATH=$(shell pwd)
-APP_NAME = iotd
+APP_NAME = lightd
BUILD_ARCH=$(shell uname -m)
ifneq ($(findstring $(BUILD_ARCH), "x86_64" "i386"),)
@@ -25,8 +25,8 @@
# common CFLAGS for our source code
CFLAGS = -Wall -Wshadow -Wundef -Wmaybe-uninitialized -D_GNU_SOURCE
-# sub-directory compiled to a library and need to link
-SRCS=src hal booster
+# C source file in sub-directory
+SRCS=booster hal
SRCS_PATH=$(patsubst %,${PRJ_PATH}/%,$(SRCS))
CFLAGS+=$(patsubst %,-I%,$(SRCS_PATH))
LDFLAGS+=$(patsubst %,-L%,$(SRCS_PATH))
@@ -34,20 +34,24 @@
LDFLAGS+=${LIBS}
# Open source libraries
-LDFLAGS+=-lmosquitto -lgpiod -lcjson -lm
+CFLAGS+=-I ${PRJ_PATH}/openlibs/install/include
+LDFLAGS+=-L ${PRJ_PATH}/openlibs/install/lib
-# sub-directory need to entry and compile
-SUBDIR=${SRCS}
+# libraries
+libs=openlibs ${SRCS}
+LDFLAGS+=-lmosquitto -lcjson -lssl -lcrypto -lgpiod -lm
+
+LDFLAGS+=-lpthread
all: entry subdir
- ${CROSS_COMPILE}gcc ${CFLAGS} main.c -o ${APP_NAME} ${LDFLAGS}
+ ${CROSS_COMPILE}gcc ${CFLAGS} ${SRCFILES} -o ${APP_NAME} ${LDFLAGS}
entry:
@echo "Building ${APP_NAME} on ${BUILD_ARCH}"
subdir:
- @for dir in ${SUBDIR} ; do if [ ! -e $${dir} ] ; then ln -s ../$${dir}; fi; done
- @for dir in ${SUBDIR} ; do make CFLAGS="${CFLAGS}" -C $${dir} ; done
+ @for dir in ${libs} ; do if [ ! -e $${dir} ] ; then ln -s ../$${dir}; fi; done
+ @for dir in ${libs} ; do CFLAGS="${CFLAGS}" make -C $${dir} ; done
install:
cp ${APP_NAME} /tftp
@@ -57,8 +61,8 @@
@rm -f ${APP_NAME}
distclean:
- @for dir in ${SUBDIR} ; do if [ -e $${dir} ] ; then make clean -C $${dir}; fi; done
+ @for dir in ${libs} ; do if [ -e $${dir} ] ; then make clean -C $${dir}; fi; done
+ @for dir in ${libs} ; do if [ -e $${dir} ] ; then unlink $${dir}; fi; done
@rm -f ${APP_NAME}
@rm -f cscope.* tags
- @rm -f *.log *.db
diff --git a/project/lightd/src/conf.c b/project/lightd/src/conf.c
deleted file mode 100644
index da13d01..0000000
--- a/project/lightd/src/conf.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/*********************************************************************************
- * Copyright: (C) 2019 LingYun IoT System Studio
- * All rights reserved.
- *
- * Filename: conf.c
- * Description: This file is iotd configure file parser function
- *
- * Version: 1.0.0(2019年06月25日)
- * Author: Guo Wenxue <guowenxue@gmail.com>
- * ChangeLog: 1, Release initial version on "2019年06月25日 22时23分55秒"
- *
- ********************************************************************************/
-#include "conf.h"
-#include "logger.h"
-#include "iniparser.h"
-
-enum
-{
- _TYPE_INPUT,
- _TYPE_OUTPUT,
-};
-
-/* conf format: "{light_indoor:6:0},{light_livroomL:13:0},{light_livroomR:19:0},{light_hallway:26:0}" */
-int parser_gpio_info(int type, gpio_t *gpio, char *conf)
-{
- char *ptr;
- char *pstart;
- char *pend;
- char buf[64];
- int cnt = 0;
- int rv = 0;
-
- if( !gpio || !conf || strlen(conf)<3 )
- {
- log_error("Invalid input arguments.\n");
- return -1;
- }
-
- pstart = strchr(conf, '{');
- if( !pstart )
- return 0;
-
- pend = strchr(pstart, '}');
-
- while( pstart && pend )
- {
- memset(buf, 0, sizeof(buf));
-
- strncpy(buf, pstart+1, pend-pstart-1);
-
- /* parser and get the GPIO name, BCM pin number, active power level */
-
- {
- /* check GPIO configure name too long or not */
- ptr = strchr(buf, ':');
- if( !ptr )
- {
- log_error("Found invalid GPIO configure: %s\n", buf);
- goto NEXT_LOOP;
- }
-
- if( ptr-buf > sizeof(gpio->input[cnt].name) )
- {
- log_error("Found GPIO name too long\n", buf);
- goto NEXT_LOOP;
- }
-
- /* use sscanf() to parser GPIO configured values */
- if(_TYPE_INPUT == type )
- {
- rv = sscanf(buf, "%[^:]:%d:%d", gpio->input[cnt].name, &gpio->input[cnt].pin, &gpio->input[cnt].active_level);
- if( 3 == rv)
- {
- log_info("parser GPIO input[%s] BCM[%d] active[%d]\n", gpio->input[cnt].name, gpio->input[cnt].pin, gpio->input[cnt].active_level);
- if( strstr(gpio->input[cnt].name, "infrared") )
- {
- log_info("parser GPIO enable infrared detect\n");
- gpio->infrared_enable = 1;
- }
- cnt++;
- gpio->incnt = cnt;
- }
- else
- {
- log_error("Found invalid GPIO configure: %s\n", buf);
- }
- }
- else
- {
- rv = sscanf(buf, "%[^:]:%d:%d", gpio->output[cnt].name, &gpio->output[cnt].pin, &gpio->output[cnt].active_level);
- if( 3 == rv)
- {
- log_info("parser GPIO output[%s] BCM[%d] active[%d]\n", gpio->output[cnt].name, gpio->output[cnt].pin, gpio->output[cnt].active_level);
- cnt++;
- gpio->outcnt = cnt;
- }
- else
- {
- log_error("Found invalid GPIO configure: %s\n", buf);
- }
- }
- }
-
-NEXT_LOOP:
- pstart = strchr(pend, '{');
- if( pstart )
- pend = strchr(pstart, '}');
- }
-
-
- return gpio->outcnt;
-}
-
-int parser_conf(const char *conf_file, iotd_ctx_t *ctx, int debug)
-{
- dictionary *ini;
- const char *str;
- int val;
- log_ctx_t *log_ctx;
- hal_ctx_t *hal_ctx;
- mqtt_ctx_t *mqtt_ctx;
- gpio_t *gpio;
-
-
- if( !conf_file || !ctx )
- {
- fprintf(stderr, "ERROR: parser configure file or ctx is NULL\n");
- return 0;
- }
-
- memset(ctx, 0, sizeof(*ctx));
-
- log_ctx = &ctx->log_ctx;
- hal_ctx = &ctx->hal_ctx;
- mqtt_ctx = &ctx->mqtt_ctx;
-
-
- ini = iniparser_load(conf_file);
- if( !ini )
- {
- fprintf(stderr, "ERROR: cannot parse file: '%s'\n", conf_file);
- return -1;
- }
-
-
- /*+------------------------------------------------------+
- *| parser logger settings and start logger system |
- *+------------------------------------------------------+*/
- if( !debug )
- {
- str = iniparser_getstring(ini, "logger:file", "/tmp/iotd.log");
- strncpy(log_ctx->logfile, str, sizeof(log_ctx->logfile));
- log_ctx->logsize = iniparser_getint(ini, "logger:size", 1024);
- log_ctx->loglevel = iniparser_getint(ini, "logger:level", LOG_LEVEL_DEBUG);
- }
- else
- {
- strncpy(log_ctx->logfile, "console", sizeof(log_ctx->logfile));
- log_ctx->loglevel = LOG_LEVEL_DEBUG;
- }
-
- if( log_open(log_ctx->logfile, log_ctx->loglevel, log_ctx->logsize, LOG_LOCK_DISABLE) < 0 )
- {
- fprintf(stderr, "Logger system initialise failure\n");
- return -2;
- }
-
- log_info("Logger system initialise ok\n");
-
-
- /*+------------------------------------------------------+
- *| parser production ID |
- *+------------------------------------------------------+*/
-
- if( !(str=iniparser_getstring(ini, "common:id", NULL)) )
- {
- log_error("ERROR: parser production ID failure\n");
- return -2;
- }
- /* cJSON parser ID will get "" */
- snprintf(mqtt_ctx->id, sizeof(mqtt_ctx->id), "\"%s\"", str);
- log_info("parser production ID [%s]\n", mqtt_ctx->id);
-
-
- /*+------------------------------------------------------+
- *| parser hardware module configuration ID |
- *+------------------------------------------------------+*/
-
- gpio = &hal_ctx->gpio;
-
- /* parser GPIO output pins */
- if( !(str=iniparser_getstring(ini, "hardware:gpio_outpin", NULL)) )
- {
- log_warn("parser no GPIO output pins\n");
- }
- else
- {
- parser_gpio_info(_TYPE_OUTPUT, gpio, (char *)str);
- log_info("parser [%d] GPIO output pins configured\n", gpio->outcnt);
- }
-
- gpio->light_intval = iniparser_getint(ini, "hardware:light_intval", 20);
- log_info("parser relay controled light interval time [%d]\n", gpio->light_intval);
-
- /* parser GPIO input pins */
- if( !(str=iniparser_getstring(ini, "hardware:gpio_inpin", NULL)) )
- {
- log_warn("parser no GPIO input pins\n");
- }
- else
- {
- parser_gpio_info(_TYPE_INPUT, gpio, (char *)str);
- log_info("parser [%d] GPIO input pins\n", gpio->incnt);
- }
-
- hal_ctx->lux_enable = iniparser_getint(ini, "hardware:lux", 0);
- if( hal_ctx->lux_enable )
- {
- hal_ctx->lux_threshold = iniparser_getdouble(ini, "hardware:lux_threshold", 0.1);
- log_info("parser LUX enable and threshold value set be [%.03f]\n", hal_ctx->lux_threshold);
- }
-
- hal_ctx->sht2x_enable = iniparser_getint(ini, "hardware:sht2x", 0);
- if( hal_ctx->sht2x_enable )
- {
- log_info("parser SHT2x sensor enabled\n");
- }
-
- hal_ctx->ds18b20_enable = iniparser_getint(ini, "hardware:ds18b20", 0);
- if( hal_ctx->ds18b20_enable )
- {
- log_info("parser DS18B20 sensor enabled\n");
- }
-
-
- /*+------------------------------------------------------+
- *| parser broker settings |
- *+------------------------------------------------------+*/
-
- if( !(str=iniparser_getstring(ini, "broker:hostname", NULL)) )
- {
- log_error("ERROR: Parser broker server hostname failure\n");
- return -2;
- }
- strncpy(mqtt_ctx->host, str, sizeof(mqtt_ctx->host) );
-
- if( (val=iniparser_getint(ini, "broker:port", -1)) < 0 )
- {
- log_error("ERROR: Parser broker server port failure\n");
- return -2;
- }
- mqtt_ctx->port = val;
- log_info("Parser broker server [%s:%d]\n", mqtt_ctx->host, mqtt_ctx->port);
-
- str=iniparser_getstring(ini, "broker:username", NULL);
- strncpy(mqtt_ctx->uid, str, sizeof(mqtt_ctx->uid) );
-
- str=iniparser_getstring(ini, "broker:password", NULL);
- strncpy(mqtt_ctx->pwd, str, sizeof(mqtt_ctx->pwd) );
-
- log_info("Parser broker author by [%s:%s]\n", mqtt_ctx->uid, mqtt_ctx->pwd);
-
- mqtt_ctx->keepalive = iniparser_getint(ini, "broker:keepalive", 30);
- log_info("Parser broker keepalive timeout [%d] seconds\n", mqtt_ctx->keepalive);
-
- /*+------------------------------------------------------+
- *| parser subscriber settings |
- *+------------------------------------------------------+*/
-
- if( !(str=iniparser_getstring(ini, "subsciber:subTopic", NULL)) )
- {
- log_warn("WARNNING: Parser MQTT subscribe topic failure\n");
- }
- else
- {
- strncpy(mqtt_ctx->subTopic, str, sizeof(mqtt_ctx->subTopic) );
- mqtt_ctx->subQos = iniparser_getint(ini, "subsciber:subQos", 0);
- mqtt_ctx->sub_enable = 1;
-
- log_info("Parser subscriber topic \"%s\" with Qos[%d]\n", mqtt_ctx->subTopic, mqtt_ctx->subQos);
- }
-
- /*+------------------------------------------------------+
- *| parser publisher settings |
- *+------------------------------------------------------+*/
-
- if( !(str=iniparser_getstring(ini, "publisher:pubTopic", NULL)) )
- {
- log_warn("WARNNING: Parser MQTT publisher topic failure\n");
- return 0;
- }
-
-
- mqtt_ctx->pub_enable = iniparser_getint(ini, "publisher:enable", 0);
- if( !mqtt_ctx->pub_enable )
- {
- log_warn("WARNNING: Parser MQTT publisher disabled\n");
- return 0;
- }
-
- strncpy(mqtt_ctx->pubTopic, str, sizeof(mqtt_ctx->pubTopic) );
- mqtt_ctx->pubQos = iniparser_getint(ini, "publisher:pubQos", 0);
- mqtt_ctx->interval = iniparser_getint(ini, "publisher:interval", 60);
-
- log_info("Parser publisher topic \"%s\" with Qos[%d]\n", mqtt_ctx->pubTopic, mqtt_ctx->pubQos);
-
- return 0;
-}
-
diff --git a/project/lightd/src/conf.h b/project/lightd/src/conf.h
deleted file mode 100644
index 0c37f03..0000000
--- a/project/lightd/src/conf.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*********************************************************************************
- * Copyright: (C) 2019 LingYun IoT System Studio
- * All rights reserved.
- *
- * Filename: conf.h
- * Description: This file is iotd configure file parser function
- *
- * Version: 1.0.0(2019年06月25日)
- * Author: Guo Wenxue <guowenxue@gmail.com>
- * ChangeLog: 1, Release initial version on "2019年06月25日 22时23分55秒"
- *
- ********************************************************************************/
-#ifndef __CONF_H_
-#define __CONF_H_
-
-#include "hal.h"
-#include "mqtt.h"
-
-enum
-{
- Qos0, /* 发送者只发送一次消息,不进行重试,Broker不会返回确认消息。在Qos0情况下,Broker可能没有接受到消息 */
- Qos1, /* 发送者最少发送一次消息,确保消息到达Broker,Broker需要返回确认消息PUBACK。在Qos1情况下,Broker可能接受到重复消息 */
- Qos2, /* Qos2使用两阶段确认来保证消息的不丢失和不重复。在Qos2情况下,Broker肯定会收到消息,且只收到一次 */
-};
-
-
-typedef struct log_ctx_s
-{
- /* logger settings */
- char logfile[128]; /* logger record file */
- int loglevel; /* logger level */
- int logsize; /* logger file maxsize, oversize will rollback */
-} log_ctx_t;
-
-typedef struct iotd_ctx_s
-{
- log_ctx_t log_ctx;
- hal_ctx_t hal_ctx;
- mqtt_ctx_t mqtt_ctx;
-} iotd_ctx_t;
-
-
-extern int parser_conf(const char *conf_file, iotd_ctx_t *ctx, int debug);
-
-#endif /* ----- #ifndef _CONF_H_ ----- */
-
diff --git a/project/lightd/src/makefile b/project/lightd/src/makefile
deleted file mode 100644
index 3b18c24..0000000
--- a/project/lightd/src/makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-
-PWD=$(shell pwd )
-
-LIBNAME=$(shell basename ${PWD} )
-TOPDIR=$(shell dirname ${PWD} )
-
-all: clean
- @rm -f *.o
- ${CROSSTOOL}gcc ${CFLAGS} -I${TOPDIR} -c *.c
- ${CROSSTOOL}ar -rcs lib${LIBNAME}.a *.o
-
-clean:
- @rm -f *.o
- @rm -f *.a
-
diff --git a/project/lightd/src/mqtt.c b/project/lightd/src/mqtt.c
deleted file mode 100644
index 05707b6..0000000
--- a/project/lightd/src/mqtt.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/********************************************************************************
- * Copyright: (C) 2021 LingYun IoT System Studio
- * All rights reserved.
- *
- * Filename: mqtt.h
- * Description: This head file is MQTT subscriber and publisher thread code
- *
- * Version: 1.0.0(20/04/21)
- * Author: Guo Wenxue <guowenxue@gmail.com>
- * ChangeLog: 1, Release initial version on "20/04/21 15:46:42"
- *
- ********************************************************************************/
-
-#include <string.h>
-#include <math.h>
-#include <cjson/cJSON.h>
-#include <mosquitto.h>
-#include <errno.h>
-
-#include "util_proc.h"
-#include "logger.h"
-#include "hal.h"
-#include "conf.h"
-
-
-/*+-------------------------------------------+
- *| |
- *| MQTT publisher thread worker code |
- *| |
- *+-------------------------------------------+*/
-
-
-void pub_connect_callback(struct mosquitto *mosq, void *userdata, int result)
-{
- iotd_ctx_t *ctx = (iotd_ctx_t *)userdata;
- mqtt_ctx_t *mqtt_ctx;
- hal_ctx_t *hal_ctx;
- int rv = 0;
- char msg[128];
- float temp = 0.0; /* temperature */
- float rh = 0.0; /* relative humidity */
- int retain = 0;
-
- mqtt_ctx = &ctx->mqtt_ctx;
- hal_ctx = &ctx->hal_ctx;
-
-
- if( result )
- {
- log_error("Publisher connect to broker server[%s:%d] failed, rv=%d\n", mqtt_ctx->host, mqtt_ctx->port, result);
- return ;
- }
- log_info("Publisher connect to broker server[%s:%d] successfully\n", mqtt_ctx->host, mqtt_ctx->port);
-
-
- if( hal_ctx->ds18b20_enable )
- {
- memset(msg, 0, sizeof(msg));
-
- if( ds18b20_get_temperature(&temp) < 0 )
- snprintf(msg, sizeof(msg), "{ \"id\":%s, \"temp\":\"error\" }", mqtt_ctx->id);
- else
- snprintf(msg, sizeof(msg), "{ \"id\":%s, \"temp\":\"%.2f\" }", mqtt_ctx->id, temp);
-
- rv = mosquitto_publish(mosq, NULL, mqtt_ctx->pubTopic, strlen(msg), msg, mqtt_ctx->pubQos, retain);
- if( rv )
- {
- log_error("Publisher broadcast message '%s' failure: %d\n", msg, rv);
- }
- else
- {
- log_info("Publisher broadcast message '%s' ok\n", msg);
- }
- }
-
- if( hal_ctx->sht2x_enable )
- {
- memset(msg, 0, sizeof(msg));
-
- if( sht2x_get_temp_humidity(&temp, &rh) < 0 )
- snprintf(msg, sizeof(msg), "{ \"id\":%s, \"temp\":\"error\", \"RH\":\"error\" }", mqtt_ctx->id);
- else
- snprintf(msg, sizeof(msg), "{ \"id\":%s, \"temp\":\"%.2f\", \"RH\":\"%.2f\" }", mqtt_ctx->id, temp, rh);
-
- rv = mosquitto_publish(mosq, NULL, mqtt_ctx->pubTopic, strlen(msg), msg, mqtt_ctx->pubQos, retain);
- if( rv )
- {
- log_error("Publisher broadcast message '%s' failure: %d\n", msg, rv);
- }
- else
- {
- log_info("Publisher broadcast message '%s' ok\n", msg);
- }
- }
-
-
- log_info("Publisher broadcast over and disconnect broker now\n", mqtt_ctx->host, mqtt_ctx->port);
- mosquitto_disconnect(mosq);
-
- return ;
-}
-
-
-void *mqtt_pub_worker(void *args)
-{
- struct mosquitto *mosq;
- bool session = true;
-
- iotd_ctx_t *ctx = (iotd_ctx_t *)args;
- mqtt_ctx_t *mqtt_ctx;
-
- if( !ctx )
- {
- log_error("Invalid input arguments\n");
- return NULL;
- }
-
- mqtt_ctx = &ctx->mqtt_ctx;
-
-
- mosq = mosquitto_new(NULL, session, ctx);
- if( !mosq )
- {
- log_error("mosquitto_new failure\n");
- return NULL;
- }
-
- /* set connnect to broker username and password */
- if( strlen(mqtt_ctx->uid)> 0 && strlen(mqtt_ctx->pwd)> 0 )
- mosquitto_username_pw_set(mosq, mqtt_ctx->uid, mqtt_ctx->pwd);
-
- /* set callback functions */
- mosquitto_connect_callback_set(mosq, pub_connect_callback);
-
- while( !g_signal.stop )
- {
- /* connect to MQTT broker */
- if( mosquitto_connect(mosq, mqtt_ctx->host, mqtt_ctx->port, mqtt_ctx->keepalive) )
- {
- log_error("Publisher connect to broker[%s:%d] failure: %s\n", mqtt_ctx->host, mqtt_ctx->port, strerror(errno));
- msleep(1000);
- continue;
- }
-
- /* -1: use default timeout 1000ms 1: unused */
- mosquitto_loop_forever(mosq, -1, 1);
-
- /* Publisher broadcast sensors data message interval time, unit seconds */
- sleep( mqtt_ctx->interval );
- }
-
- mosquitto_destroy(mosq);
- return NULL;
-}
-
-/*+-------------------------------------------+
- *| |
- *| MQTT Subscriber thread worker code |
- *| |
- *+-------------------------------------------+*/
-
-void sub_connect_callback(struct mosquitto *mosq, void *userdata, int result)
-{
- iotd_ctx_t *ctx = (iotd_ctx_t *)userdata;
-
- if( result )
- {
- log_error("Subscriber connect to broker server failed, rv=%d\n", result);
- return ;
- }
-
- log_info("Subscriber connect to broker server[%s:%d] successfully\n", ctx->mqtt_ctx.host, ctx->mqtt_ctx.port);
-
- log_info("Subscriber subTopic '%s' with Qos[%d]\n", ctx->mqtt_ctx.subTopic, ctx->mqtt_ctx.subQos);
- mosquitto_subscribe(mosq, NULL, ctx->mqtt_ctx.subTopic, ctx->mqtt_ctx.subQos);
-}
-
-void sub_disconnect_callback(struct mosquitto *mosq, void *userdata, int result)
-{
- iotd_ctx_t *ctx = (iotd_ctx_t *)userdata;
-
- log_warn("Subscriber disconnect to broker server[%s:%d], reason=%d\n",
- ctx->mqtt_ctx.host, ctx->mqtt_ctx.port, result);
-}
-
-void proc_json_items(cJSON *root)
-{
- int i;
- char *value;
- cJSON *item;
-
- if( !root )
- {
- log_error("Invalid input arguments $root\n");
- return ;
- }
-
- for( i=0; i<cJSON_GetArraySize(root); i++ )
- {
- item = cJSON_GetArrayItem(root, i);
- if( !item )
- break;
-
- /* if item is cJSON_Object, then recursive call proc_json */
- if( cJSON_Object == item->type )
- {
- proc_json_items(item);
- }
- else if( cJSON_Array != item->type )
- {
- value = cJSON_Print(item);
-
- log_debug("JSON Parser key: %s value: %s\n", item->string, value);
- if( strstr(item->string, "light") || strstr(item->string, "led") || strstr(item->string, "relay"))
- {
- if( strstr(value, "on") || strstr(value, "off") )
- {
- log_info("parser get turn '%s' %s from JSON string\n", item->string, value);
- gpio_out(item->string, value);
- }
- }
-
- free(value); /* must free it, or it will result memory leak */
- }
- }
-}
-
-void sub_message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)
-{
- iotd_ctx_t *ctx = (iotd_ctx_t *)userdata;
-
- cJSON *root = NULL;
- cJSON *item;
- char *value;
-
-
- if ( !message->payloadlen )
- {
- log_error("%s (null)\n", message->topic);
- return ;
- }
-
- log_debug("Subscriber receive message: '%s'\n", message->payload);
-
- root = cJSON_Parse(message->payload);
- if( !root )
- {
- log_error("cJSON_Parse parser failure: %s\n", cJSON_GetErrorPtr());
- return ;
- }
-
- /* check ID matched or not */
- item = cJSON_GetObjectItem(root, "id");
- if( !item )
- {
- log_error("cJSON_Parse get ID failure: %s\n", cJSON_GetErrorPtr());
- goto OUT;
- }
-
- value = cJSON_PrintUnformatted(item);
- if( strcasecmp(value, ctx->mqtt_ctx.id) )
- {
- log_warn("cJSON_Parse get ID not matchs [%s<->%s], drop this message!\n", value, ctx->mqtt_ctx.id);
- free(value);
- goto OUT;
- }
-
- free(value);
-
- /* proc JSON mesage */
- proc_json_items(root);
-
-OUT:
- cJSON_Delete(root); /* must delete it, or it will result memory leak */
- return ;
-}
-
-
-void *mqtt_sub_worker(void *args)
-{
- struct mosquitto *mosq;
- bool session = true;
-
- iotd_ctx_t *ctx = (iotd_ctx_t *)args;
- mqtt_ctx_t *mqtt_ctx;
-
- if( !ctx )
- {
- log_error("Invalid input arguments\n");
- return NULL;
- }
-
- mqtt_ctx = &ctx->mqtt_ctx;
-
-
- mosq = mosquitto_new(NULL, session, ctx);
- if( !mosq )
- {
- log_error("mosquitto_new failure\n");
- return NULL;
- }
-
- /* set connnect to broker username and password */
- if( strlen(mqtt_ctx->uid)> 0 && strlen(mqtt_ctx->pwd)> 0 )
- mosquitto_username_pw_set(mosq, mqtt_ctx->uid, mqtt_ctx->pwd);
-
- /* set callback functions */
- mosquitto_connect_callback_set(mosq, sub_connect_callback);
- mosquitto_disconnect_callback_set(mosq, sub_disconnect_callback);
- mosquitto_message_callback_set(mosq, sub_message_callback);
-
- while( !g_signal.stop )
- {
- /* connect to MQTT broker */
- if( mosquitto_connect(mosq, mqtt_ctx->host, mqtt_ctx->port, mqtt_ctx->keepalive) )
- {
- log_error("Subscriber connect to broker[%s:%d] failure: %s\n", mqtt_ctx->host, mqtt_ctx->port, strerror(errno));
- msleep(1000);
- continue;
- }
-
- /* -1: use default timeout 1000ms 1: unused */
- mosquitto_loop_forever(mosq, -1, 1);
- }
-
- mosquitto_destroy(mosq);
- return NULL;
-}
-
diff --git a/project/lightd/src/mqtt.h b/project/lightd/src/mqtt.h
deleted file mode 100644
index 6e2605a..0000000
--- a/project/lightd/src/mqtt.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/********************************************************************************
- * Copyright: (C) 2021 LingYun IoT System Studio
- * All rights reserved.
- *
- * Filename: mqtt.h
- * Description: This head file is MQTT subscriber and publisher thread code
- *
- * Version: 1.0.0(20/04/21)
- * Author: Guo Wenxue <guowenxue@gmail.com>
- * ChangeLog: 1, Release initial version on "20/04/21 15:46:42"
- *
- ********************************************************************************/
-#ifndef _MQTT_H_
-#define _MQTT_H_
-
-
-typedef struct mqtt_ctx_s
-{
- char id[32]; /* production ID */
-
- /* Broker settings */
- char host[128]; /* MQTT broker server name */
- int port; /* MQTT broker listen port */
- char uid[64]; /* username */
- char pwd[64]; /* password */
- int keepalive; /* MQTT broker send PING message to subsciber/publisher keepalive timeout<seconds> */
-
- /* Subscriber settings */
- int sub_enable; /* Subscriber enable or not */
- char subTopic[256]; /* Subscriber topic */
- int subQos; /* Subscriber Qos */
-
- /* Publisher settings */
- int pub_enable; /* Publisher enable or not */
- char pubTopic[256]; /* Publisher topic */
- int pubQos; /* Publisher Qos */
- int interval; /* Publish interval */
-} mqtt_ctx_t;
-
-
-extern void *mqtt_pub_worker(void *args);
-extern void *mqtt_sub_worker(void *args);
-
-#endif /* ----- #ifndef _MQTT_H_ ----- */
-
--
Gitblit v1.9.1