Minor updates

master v1.0g
shaun feakes 2019-07-21 15:17:24 -05:00
parent b6b96e1415
commit 9648433ef8
17 changed files with 415 additions and 191 deletions

View File

@ -27,7 +27,6 @@ CFLAGS = $(GCCFLAGS) -I. -I./minIni $(DBG) $(LIBS) -D MG_DISABLE_MD5 -D MG_DISAB
# define the C source files
SRCS = sprinkler.c utils.c config.c net_services.c json_messages.c zone_ctrl.c sd_cron.c mongoose.c minIni/minIni.c $(sd_GPIO_C)
TSRC = test.c config.c utils.c minIni/minIni.c
# define the C object files
#
@ -38,11 +37,11 @@ TSRC = test.c config.c utils.c minIni/minIni.c
# with the .o suffix
#
OBJS = $(SRCS:.c=.o)
TOBJ = $(TSRC:.c=.o)
# define the executable file
MAIN = ./release/sprinklerd
TEST = ./release/testing
GMON = ./release/gpio_monitor
GPIO = ./release/gpio
#
# The following part of the makefile is generic; it can be used to
@ -58,11 +57,9 @@ all: $(MAIN)
$(MAIN): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS)
test: $(TEST)
@echo: $(TEST) have been compiled
$(TEST): $(TOBJ)
$(CC) $(CFLAGS) $(INCLUDES) -o $(TEST) $(TOBJ) $(LFLAGS) $(LIBS)
gpio_tools:
$(CC) -o $(GMON) sd_GPIO.c -lm -lpthread -D GPIO_MONITOR
$(CC) -o $(GPIO) sd_GPIO.c -lm -lpthread -D GPIO_RW
# this is a suffix replacement rule for building .o's from .c's
# it uses automatic variables $<: the name of the prerequisite of

View File

@ -9,10 +9,11 @@
#include <wiringPi.h>
#define PIN_CFG_NAME "WPI_PIN"
#else
#include "sd_GPIO.h"
//#include "sd_GPIO.h"
#define PIN_CFG_NAME "GPIO_PIN"
#endif
#include "sd_GPIO.h"
#include "minIni.h"
#include "utils.h"
#include "config.h"
@ -308,13 +309,13 @@ void readCfg(char *inifile)
_sdconfig_.zonecfg[i].default_runtime = ini_getl(str, "DEFAULT_RUNTIME", 10, inifile);
//ini_gets(str, "NAME", NULL, _sdconfig_.zonecfg[idx].name, sizearray(_sdconfig_.zonecfg[idx].name), inifile);
ini_gets(str, "NAME", NULL, _sdconfig_.zonecfg[i].name, sizearray(_sdconfig_.zonecfg[i].name), inifile);
#ifndef USE_WIRINGPI
//#ifndef USE_WIRINGPI
if ( ! validGPIO(pin) ) {
logMessage (LOG_ERR, "GPIO %d is not valid, found in ZONE:%d of configuration file %s \n",pin, i, inifile);
pin = GPIO_MAX; // Set pin to MAX so we can continue to run if error is not fixed.
sprintf(_sdconfig_.zonecfg[i].name, "ERROR in cfg");
logMessage (LOG_ERR, "GPIO pin %d is not valid, found in ZONE:%d of configuration file %s \n",pin, i, inifile);
pin = -1;
sprintf(_sdconfig_.zonecfg[i].name, "ERROR");
}
#endif
//#endif
/*
logMessage (LOG_DEBUG,"Zone Config : %s\n%25s : %d\n%25s : %d\n%25s : %d\n%25s : %d\n%25s : %d\n",
_sdconfig_.zonecfg[i].name,
@ -354,6 +355,60 @@ void readCfg(char *inifile)
logMessage (LOG_ERR," no config zones set\n");
exit (EXIT_FAILURE);
}
// Caculate how many inputs we have
for (i=1; i <= 24; i++) // 24 = Just some arbutary number (max GPIO without expansion board)
{
sprintf(str, "INPUT:%d", i);
pin = ini_getl(str, PIN_CFG_NAME, -1, inifile);
if (pin == -1)
break;
else
_sdconfig_.inputs = i;
}
logMessage (LOG_DEBUG, "Found %d INPUTS\n", _sdconfig_.inputs);
if ( _sdconfig_.inputs != 0) {
// n= _sdconfig_.zones+1;
_sdconfig_.inputcfg = malloc((_sdconfig_.inputs + 1) * sizeof(struct GPIOcfg));
for (i=0; i < _sdconfig_.inputs; i++)
{
sprintf(str, "INPUT:%d", i+1);
pin = ini_getl(str, PIN_CFG_NAME, -1, inifile);
if (! validGPIO(pin) ) {
logMessage (LOG_ERR, "GPIO pin %d is not valid, found in INPUT:%d of configuration file %s \n",pin, i+1, inifile);
continue;
}
logMessage (LOG_DEBUG, "INPUT = %d\n", i+1);
_sdconfig_.inputcfg[i].input_output = INPUT; // Zone is always input
_sdconfig_.inputcfg[i].receive_mode = BOTH; // Zone always needs trigger on both (high or low)
_sdconfig_.inputcfg[i].zone = i+1;
_sdconfig_.inputcfg[i].pin = pin;
_sdconfig_.inputcfg[i].on_state = ini_getl(str, "GPIO_ON_STATE", NO, inifile);
//_sdconfig_.inputcfg[i].startup_state = !_sdconfig_.inputcfg[i].on_state;
//_sdconfig_.inputcfg[i].shutdown_state = !_sdconfig_.inputcfg[i].on_state;
_sdconfig_.inputcfg[i].set_pull_updown = ini_getl(str, "GPIO_PULL_UPDN", -1, inifile);
_sdconfig_.inputcfg[i].dz_idx = ini_getl(str, "DOMOTICZ_IDX", -1, inifile); // Not used at the moment.
ini_gets(str, "NAME", NULL, _sdconfig_.inputcfg[i].name, sizearray(_sdconfig_.inputcfg[i].name), inifile);
_sdconfig_.inputcfg[i].command_on = malloc(COMMAND_SIZE * sizeof(char));
_sdconfig_.inputcfg[i].command_off = malloc(COMMAND_SIZE * sizeof(char));
ini_gets(str, "COMMAND_ON", NULL, _sdconfig_.inputcfg[i].command_on, COMMAND_SIZE, inifile);
ini_gets(str, "COMMAND_OFF", NULL, _sdconfig_.inputcfg[i].command_off, COMMAND_SIZE, inifile);
logMessage (LOG_DEBUG,"Input Config : %s\n%25s : %d\n%25s : %d\n%25s : %d\n%25s : %d\n",
_sdconfig_.inputcfg[i].name,
"PIN",_sdconfig_.inputcfg[i].pin,
"Set pull up/down", _sdconfig_.inputcfg[i].set_pull_updown,
"ON state", _sdconfig_.inputcfg[i].on_state,
"Domoticz IDX", _sdconfig_.inputcfg[i].dz_idx);
}
}
/*
idx=0;
pin=-1;

View File

@ -46,6 +46,8 @@ struct GPIOcfg {
//int ignore_requests;
int zone;
int default_runtime;
char *command_on;
char *command_off;
//bool master_valve;
//struct GPIOextra *extra;
};
@ -74,6 +76,7 @@ struct sprinklerdcfg {
bool enableMQTTdz;
bool enableMQTTaq;
int zones;
int inputs;
//int pincfgs;
bool calendar;
bool delay24h;
@ -84,6 +87,7 @@ struct sprinklerdcfg {
float precipInchDelay2day;
struct DZcache *dz_cache;
struct GPIOcfg *zonecfg;
struct GPIOcfg *inputcfg;
//struct GPIOcfg *gpiocfg;
struct CALENDARday cron[7];
//time_t cron_update;

View File

@ -39,7 +39,7 @@ int build_sprinkler_cal_JSON(char* buffer, int size)
for (day=0; day <= 6; day++) {
if (_sdconfig_.cron[day].hour >= 0 && _sdconfig_.cron[day].minute >= 0) {
length += sprintf(buffer+length, ", \"d%d-starttime\" : \"%.2d:%.2d\" ",day,_sdconfig_.cron[day].hour,_sdconfig_.cron[day].minute);
for (zone=0; zone < _sdconfig_.zones; zone ++) {
for (zone=1; zone < _sdconfig_.zones; zone ++) {
if (_sdconfig_.cron[day].zruntimes[zone] >= 0) {
length += sprintf(buffer+length, ", \"d%dz%d-runtime\" : %d",day,zone+1,_sdconfig_.cron[day].zruntimes[zone]);
//logMessage(LOG_DEBUG, "Zone %d, length %d limit %d\n",zone,length,size);
@ -105,6 +105,7 @@ int build_advanced_sprinkler_JSON(char* buffer, int size)
int i, day;
memset(&buffer[0], 0, size);
int length = 0;
bool cal = false;
/*
length += sprintf(buffer+length, "{ \"title\" : \"%s\",\"calendar\" : \"%s\", \"24hdelay\" : \"%s\", \"allz\" : \"%s\", \"#zones\" : %d, \"24hdelay-offtime\" : %li",
_sdconfig_.name,
@ -146,8 +147,9 @@ int build_advanced_sprinkler_JSON(char* buffer, int size)
for (day=0; day <= 6; day++) {
if (_sdconfig_.cron[day].hour >= 0 && _sdconfig_.cron[day].minute >= 0) {
cal = true;
length += sprintf(buffer+length, "\"day %d\" : { \"start time\" : \"%.2d:%.2d\", ",day,_sdconfig_.cron[day].hour,_sdconfig_.cron[day].minute);
for (i=0; i < _sdconfig_.zones; i ++) {
for (i=1; i < _sdconfig_.zones; i ++) {
if (_sdconfig_.cron[day].zruntimes[i] >= 0) {
length += sprintf(buffer+length, "\"Zone %d\" : %d,",i+1,_sdconfig_.cron[day].zruntimes[i]);
//logMessage(LOG_DEBUG, "Zone %d, length %d limit %d\n",i+1,length,size);
@ -157,8 +159,11 @@ int build_advanced_sprinkler_JSON(char* buffer, int size)
length += sprintf(buffer+length, "},");
}
}
length -= 1;
if (cal) {
length -= 1;
}
length += sprintf(buffer+length, "}}");
buffer[length] = '\0';
return strlen(buffer);

View File

@ -197,8 +197,6 @@ void publish_zone_mqtt(struct mg_connection *nc, struct GPIOcfg *gpiopin) {
static char mqtt_topic[250];
static char mqtt_msg[50];
printf("PUBLISH pin %d\n",gpiopin->pin);
if (_sdconfig_.enableMQTTaq == true) {
// sprintf(mqtt_topic, "%s/%s", _sdconfig_.mqtt_topic, gpiopin->name);
sprintf(mqtt_topic, "%s/zone%d", _sdconfig_.mqtt_topic, gpiopin->zone);

BIN
release/gpio Executable file

Binary file not shown.

BIN
release/gpio_monitor Executable file

Binary file not shown.

Binary file not shown.

View File

@ -4,16 +4,17 @@ NAME=My Sprinklers
DOCUMENTROOT = /nas/data/Development/Raspberry/SprinklerD/web/
CACHE = /var/cache/sprinklerd.cache
# The log level. [DEBUG, INFO, NOTICE, WARNING, ERROR]
LOG_LEVEL = DEBUG
#LOG_LEVEL = NOTICE
#LOG_LEVEL = DEBUG
#LOG_LEVEL = NOTICE
LOG_LEVEL = INFO
# mqtt stuff
MQTT_ADDRESS = trident:1883
#MQTT_USER = someusername
#MQTT_PASSWD = somepassword
MQT_TOPIC = sd_test
#MQTT_DZ_PUB_TOPIC = domoticz/in
#MQTT_DZ_SUB_TOPIC = domoticz/out
MQTT_DZ_PUB_TOPIC = domoticz/in
MQTT_DZ_SUB_TOPIC = domoticz/out
DZIDX_CALENDAR = 197
DZIDX_24HDELAY = 198
@ -39,51 +40,61 @@ DZIDX_RAINSENSOR = 48
# Don't use ZONE:0 for anything other than master valve, if you don't have a master valve simply delete it and start from ZONE:1
[ZONE]
#[ZONE:0]
#NAME=Master Valve
#MASTER_VALVE=1
#GPIO_PIN=17
#WPI_PIN=0
#GPIO_PULL_UPDN=1
#GPIO_ON_STATE=0
[ZONE:0]
NAME=Master Valve
MASTER_VALVE=1
GPIO_PIN=2
WPI_PIN=0
GPIO_PULL_UPDN=1
GPIO_ON_STATE=0
[ZONE:1]
NAME=Island
DEFAULT_RUNTIME=10
#GPIO_PIN=18
GPIO_PIN=2
GPIO_PIN=3
WPI_PIN=1
GPIO_PULL_UPDN=1
GPIO_ON_STATE=0
DOMOTICZ_IDX=200
DOMOTICZ_IDX=2000
[ZONE:2]
NAME=Driveway
DEFAULT_RUNTIME=10
#GPIO_PIN=27
GPIO_PIN=3
GPIO_PIN=40
WPI_PIN=2
GPIO_PULL_UPDN=1
GPIO_ON_STATE=0
DOMOTICZ_IDX=201
DOMOTICZ_IDX=2010
[ZONE:3]
NAME=Diningroom Flowerbeds
DEFAULT_RUNTIME=10
GPIO_PIN=22
GPIO_PIN=5
WPI_PIN=3
GPIO_PULL_UPDN=1
GPIO_ON_STATE=0
DOMOTICZ_IDX=202
DOMOTICZ_IDX=2020
[ZONE:4]
NAME=Diningroom error
DEFAULT_RUNTIME=10
GPIO_PIN=28
[INPUT]
[INPUT:1]
NAME=Test Switch
GPIO_PIN=6
WPI_PIN=3
GPIO_PULL_UPDN=1
GPIO_ON_STATE=0
DOMOTICZ_IDX=202
COMMAND_ON=/usr/bin/curl -s -o /dev/null 'http://localhost?type=option&option=24hdelay&state=on'
COMMAND_OFF=/usr/bin/curl -s -o /dev/null 'http://localhost?type=option&option=24hdelay&state=off'
#[ZONE:4]
#NAME=Diningroom error
#DEFAULT_RUNTIME=10
#GPIO_PIN=28
#WPI_PIN=3
#GPIO_PULL_UPDN=1
#GPIO_ON_STATE=0
#DOMOTICZ_IDX=2020
#[ZONE:4]
#NAME=Front Flowerbeds

193
sd_GPIO.c
View File

@ -161,6 +161,9 @@ bool gpioSetup() {
int pinMode(unsigned gpio, unsigned mode) {
int reg, shift;
if (! validGPIO(gpio))
return -1;
reg = gpio / 10;
shift = (gpio % 10) * 3;
@ -172,6 +175,9 @@ int pinMode(unsigned gpio, unsigned mode) {
int getPinMode(unsigned gpio) {
int reg, shift;
if (! validGPIO(gpio))
return -1;
reg = gpio / 10;
shift = (gpio % 10) * 3;
@ -181,6 +187,9 @@ int getPinMode(unsigned gpio) {
int digitalRead(unsigned gpio) {
unsigned bank, bit;
if (! validGPIO(gpio))
return -1;
bank = gpio >> 5;
bit = (1 << (gpio & 0x1F));
@ -194,6 +203,9 @@ int digitalRead(unsigned gpio) {
int digitalWrite(unsigned gpio, unsigned level) {
unsigned bank, bit;
if (! validGPIO(gpio))
return -1;
bank = gpio >> 5;
bit = (1 << (gpio & 0x1F));
@ -203,13 +215,16 @@ int digitalWrite(unsigned gpio, unsigned level) {
else
*(_gpioReg + GPSET0 + bank) = bit;
return 0;
return true;
}
int setPullUpDown(unsigned gpio, unsigned pud)
{
unsigned bank, bit;
if (! validGPIO(gpio))
return -1;
bank = gpio >> 5;
bit = (1 << (gpio & 0x1F));
@ -240,6 +255,9 @@ int pinMode (unsigned pin, unsigned mode)
{
//static const char s_directions_str[] = "in\0out\0";
if (! validGPIO(pin))
return -1;
char path[SYSFS_PATH_MAX];
int fd;
/*
@ -274,6 +292,9 @@ int getPinMode(unsigned gpio) {
char value_str[SYSFS_READ_MAX];
int fd;
if (! validGPIO(gpio))
return -1;
snprintf(path, SYSFS_PATH_MAX, "/sys/class/gpio/gpio%d/direction", gpio);
fd = open(path, O_RDONLY);
if (-1 == fd) {
@ -302,6 +323,9 @@ int digitalRead (unsigned pin)
char path[SYSFS_PATH_MAX];
char value_str[SYSFS_READ_MAX];
int fd;
if (! validGPIO(pin))
return -1;
snprintf(path, SYSFS_PATH_MAX, "/sys/class/gpio/gpio%d/value", pin);
fd = open(path, O_RDONLY);
@ -329,6 +353,9 @@ int digitalWrite (unsigned pin, unsigned value)
char path[SYSFS_PATH_MAX];
int fd;
if (! validGPIO(pin))
return -1;
snprintf(path, SYSFS_PATH_MAX, "/sys/class/gpio/gpio%d/value", pin);
fd = open(path, O_WRONLY);
@ -381,6 +408,9 @@ bool pinExport(unsigned pin)
ssize_t bytes_written;
int fd;
if (! validGPIO(pin))
return -1;
fd = open("/sys/class/gpio/export", O_WRONLY);
if (-1 == fd) {
//fprintf(stderr, "Failed to open export for writing!\n");
@ -400,6 +430,9 @@ bool pinUnexport(unsigned pin)
ssize_t bytes_written;
int fd;
if (! validGPIO(pin))
return -1;
fd = open("/sys/class/gpio/unexport", O_WRONLY);
if (-1 == fd) {
//fprintf(stderr, "Failed to open unexport for writing!\n");
@ -420,6 +453,9 @@ bool edgeSetup (unsigned pin, unsigned value)
char path[SYSFS_PATH_MAX];
int fd;
if (! validGPIO(pin))
return -1;
snprintf(path, SYSFS_PATH_MAX, "/sys/class/gpio/gpio%d/edge", pin);
fd = open(path, O_WRONLY);
if (-1 == fd) {
@ -485,7 +521,7 @@ void gpioShutdown() {
for (i=0; i< MAX_FDS; i++) {
if (_sysFds[i] != -1) {
printf("Closing fd\n");
//printf("Closing fd %d\n",i);
close(_sysFds[i]);
_sysFds[i] = -1;
} else {
@ -567,6 +603,10 @@ bool registerGPIOinterrupt(int pin, int mode, void (*function)(void *args), void
{
pthread_t threadId ;
struct threadGPIOinterupt stuff;
if (! validGPIO(pin))
return false;
// Check it's exported
if (! isExported(pin))
pinExport(pin);
@ -598,32 +638,22 @@ bool registerGPIOinterrupt(int pin, int mode, void (*function)(void *args), void
}
//#define TEST_HARNESS
#ifdef TEST_HARNESS
#define GPIO_OFF 0x00005000 /* Offset from IO_START to the GPIO reg's. */
/* IO_START and IO_BASE are defined in hardware.h */
#define GPIO_START (IO_START_2 + GPIO_OFF) /* Physical addr of the GPIO reg. */
#define GPIO_BASE_NEW (IO_BASE_2 + GPIO_OFF) /* Virtual addr of the GPIO reg. */
#if defined(TEST_HARNESS) || defined(GPIO_MONITOR) || defined(GPIO_RW)
#include <stdarg.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
void *myCallBack(void * args) {
printf("Ping\n");
//struct threadGPIOinterupt *stuff = (struct threadGPIOinterupt *) args;
//printf("Pin is %d\n",stuff->pin);
}
int _log_level = LOG_DEBUG;
void logMessage(int level, char *format, ...)
{
//if (_debuglog_ == false && level == LOG_DEBUG)
// return;
if (level > _log_level)
return;
char buffer[256];
va_list args;
@ -645,9 +675,134 @@ void displayLastSystemError (const char *on_what)
}
#endif //TEST_HARNESS || GPIO_MONITOR
#ifdef GPIO_RW
void errorParms()
{
printf("Missing Parameters:-\n\t[read|write] pin <value>\n\tgpio write 17 1\n");
exit(1);
}
int main(int argc, char *argv[]) {
bool isWrite=false;
int pin = 0;
int value = 0;
_log_level = LOG_ERR;
if (argc < 3) {
errorParms();
}
if (strcmp (argv[1], "read") == 0)
{
isWrite = false;
} else if (strcmp (argv[1], "write") == 0) {
isWrite = true;
if (argc < 4)
errorParms();
} else {
errorParms();
}
pin = atoi(argv[2]);
if (! gpioSetup()) {
logMessage (LOG_ERR, "Failed to setup GPIO\n");
return 1;
}
if (isWrite) {
value = atoi(argv[3]);
int pmode = getPinMode(pin);
pinMode (pin, OUTPUT);
digitalWrite(pin, value);
//if (pmode != OUTPUT)
// pinMode (pin, pmode);
}
printf ("%d\n", digitalRead(pin));
return 0;
}
#endif
#ifdef GPIO_MONITOR
bool FOREVER = true;
void intHandler(int signum) {
static int called=0;
logMessage (LOG_INFO, "Stopping! - signel(%d)\n",signum);
gpioShutdown();
FOREVER = false;
called++;
if (called > 3)
exit(1);
}
void event_trigger (int pin)
{
printf("Pin %d triggered, state=%d\n",pin,digitalRead(pin));
}
int main(int argc, char *argv[]) {
int i;
if (! gpioSetup()) {
logMessage (LOG_ERR, "Failed to setup GPIO\n");
return 1;
}
signal(SIGINT, intHandler);
signal(SIGTERM, intHandler);
signal(SIGSEGV, intHandler);
for (i=GPIO_MIN; i <= GPIO_MAX; i++) {
printf ("Pin %d is %d\n", i, digitalRead(i));
if (registerGPIOinterrupt (i, INT_EDGE_BOTH, (void *)&event_trigger, (void *)i) != true)
{
displayLastSystemError ("Unable to set interrupt handler for specified pin, exiting");
gpioShutdown();
return 1;
}
}
while(FOREVER) {
sleep(10);
}
return 0;
}
#endif //GPIO_MONITOR
//#define TEST_HARNESS
#ifdef TEST_HARNESS
#define GPIO_OFF 0x00005000 /* Offset from IO_START to the GPIO reg's. */
/* IO_START and IO_BASE are defined in hardware.h */
#define GPIO_START (IO_START_2 + GPIO_OFF) /* Physical addr of the GPIO reg. */
#define GPIO_BASE_NEW (IO_BASE_2 + GPIO_OFF) /* Virtual addr of the GPIO reg. */
void *myCallBack(void * args) {
printf("Ping\n");
//struct threadGPIOinterupt *stuff = (struct threadGPIOinterupt *) args;
//printf("Pin is %d\n",stuff->pin);
}
#define PIN 17
#define POUT 27
int main(int argc, char *argv[]) {
int repeat = 3;
// if (-1 == GPIOExport(POUT) || -1 == GPIOExport(PIN))

View File

@ -11,6 +11,19 @@
#include <syslog.h>
#include <stdbool.h>
// check number is between 2 and 27
#ifndef USE_WIRINGPI
#define GPIO_MIN 2
#define GPIO_MAX 27
#else // WiringPI valid numbers
#define GPIO_MIN 0
#define GPIO_MAX 30
#endif
#define validGPIO(X) ((X) <= (GPIO_MAX) ? ( ((X) >= (GPIO_MIN) ? (1) : (0)) ) : (0))
#ifndef USE_WIRINGPI // Don't include anything below this line if using wiringpi.
#define INPUT 0
#define OUTPUT 1
@ -69,13 +82,6 @@
#endif
// check number is between 2 and 27
#define GPIO_MIN 2
#define GPIO_MAX 27
#define validGPIO(X) ((X) <= (GPIO_MAX) ? ( ((X) >= (GPIO_MIN) ? (1) : (0)) ) : (0))
//#ifndef SYSFS_MODE
bool pinExport(unsigned pin);
bool pinUnexport(unsigned pin);
@ -98,4 +104,5 @@ bool digitalWrite (int pin, int value);
#endif
*/
#endif /* WiringPI */
#endif /* _SD_GPIO_H_ */

View File

@ -153,9 +153,10 @@ void write_cron() {
//length += sprintf(buffer+length, ", \"d%d-starttime\" : \"%.2d:%.2d\" ",day,_sdconfig_.cron[day].hour,_sdconfig_.cron[day].minute);
min = _sdconfig_.cron[day].minute;
hour = _sdconfig_.cron[day].hour;
for (zone=0; zone < _sdconfig_.zones; zone ++) {
for (zone=1; zone < _sdconfig_.zones; zone ++) {
if (_sdconfig_.cron[day].zruntimes[zone] > 0) {
fprintf(fp, "%d %d * * %d root /usr/bin/curl -s -o /dev/null 'localhost?type=cron&zone=%d&runtime=%d&state=on'\n",min,hour,day,zone+1,_sdconfig_.cron[day].zruntimes[zone]);
fprintf(fp, "%d %d * * %d root /usr/bin/curl -s -o /dev/null 'localhost:%s?type=cron&zone=%d&runtime=%d&state=on'\n",min,hour,day,_sdconfig_.socket_port,zone+1,_sdconfig_.cron[day].zruntimes[zone]);
//fprintf(fp, "%d %d * * %d root /usr/bin/curl -s -o /dev/null 'localhost?type=cron&zone=%d&runtime=%d&state=on'\n",min,hour,day,zone+1,_sdconfig_.cron[day].zruntimes[zone]);
min = min + _sdconfig_.cron[day].zruntimes[zone];
// NSF Check if to incrument hour.
if (min >= 60) {
@ -170,8 +171,8 @@ void write_cron() {
}
}
}
fprintf(fp, "0 0 * * * root /usr/bin/curl -s -o /dev/null 'localhost?type=sensor&sensor=chanceofrain&value=0'\n");
fprintf(fp, "0 0 * * * root /usr/bin/curl -s -o /dev/null 'localhost?type=sensor&sensor=raintotal&value=0'\n");
fprintf(fp, "0 0 * * * root /usr/bin/curl -s -o /dev/null 'localhost:%s?type=sensor&sensor=chanceofrain&value=0'\n",_sdconfig_.socket_port);
fprintf(fp, "0 0 * * * root /usr/bin/curl -s -o /dev/null 'localhost:%s?type=sensor&sensor=raintotal&value=0'\n",_sdconfig_.socket_port);
fprintf(fp, "#***** AUTO GENERATED DO NOT EDIT *****\n");
fclose(fp);
@ -204,7 +205,7 @@ void read_cron() {
for (day=0; day <= 6; day++) {
_sdconfig_.cron[day].hour = -1;
_sdconfig_.cron[day].minute = -1;
for (zone=0; zone < _sdconfig_.zones; zone ++) {
for (zone=1; zone < _sdconfig_.zones; zone ++) {
_sdconfig_.cron[day].zruntimes[zone] = 0;
}
}

View File

@ -10,10 +10,12 @@
#ifdef USE_WIRINGPI
#define WIRINGPI_CODES 1
#include <wiringPi.h>
#else
#include "sd_GPIO.h"
//#else
// #include "sd_GPIO.h"
#endif
#include "sd_GPIO.h"
#include "mongoose.h"
#include "utils.h"
@ -39,31 +41,31 @@ void intHandler(int signum);
//extern _sdconfig_;
#ifdef USE_WIRINGPI
/* BS functions due to limitations in wiringpi of not supporting a pointer in callback event */
// Let's hope no one wants mroe than 24 zones
void event_trigger_0 (void) { event_trigger (&_sdconfig_.zonecfg[0]) ; }
void event_trigger_1 (void) { event_trigger (&_sdconfig_.zonecfg[1]) ; }
void event_trigger_2 (void) { event_trigger (&_sdconfig_.zonecfg[2]) ; }
void event_trigger_3 (void) { event_trigger (&_sdconfig_.zonecfg[3]) ; }
void event_trigger_4 (void) { event_trigger (&_sdconfig_.zonecfg[4]) ; }
void event_trigger_5 (void) { event_trigger (&_sdconfig_.zonecfg[5]) ; }
void event_trigger_6 (void) { event_trigger (&_sdconfig_.zonecfg[6]) ; }
void event_trigger_7 (void) { event_trigger (&_sdconfig_.zonecfg[7]) ; }
void event_trigger_8 (void) { event_trigger (&_sdconfig_.zonecfg[8]) ; }
void event_trigger_9 (void) { event_trigger (&_sdconfig_.zonecfg[9]) ; }
void event_trigger_10 (void) { event_trigger (&_sdconfig_.zonecfg[10]) ; }
void event_trigger_11 (void) { event_trigger (&_sdconfig_.zonecfg[11]) ; }
void event_trigger_12 (void) { event_trigger (&_sdconfig_.zonecfg[12]) ; }
void event_trigger_13 (void) { event_trigger (&_sdconfig_.zonecfg[13]) ; }
void event_trigger_14 (void) { event_trigger (&_sdconfig_.zonecfg[14]) ; }
void event_trigger_15 (void) { event_trigger (&_sdconfig_.zonecfg[15]) ; }
void event_trigger_16 (void) { event_trigger (&_sdconfig_.zonecfg[16]) ; }
void event_trigger_17 (void) { event_trigger (&_sdconfig_.zonecfg[17]) ; }
void event_trigger_18 (void) { event_trigger (&_sdconfig_.zonecfg[18]) ; }
void event_trigger_19 (void) { event_trigger (&_sdconfig_.zonecfg[19]) ; }
void event_trigger_20 (void) { event_trigger (&_sdconfig_.zonecfg[20]) ; }
void event_trigger_21 (void) { event_trigger (&_sdconfig_.zonecfg[21]) ; }
void event_trigger_22 (void) { event_trigger (&_sdconfig_.zonecfg[22]) ; }
void event_trigger_23 (void) { event_trigger (&_sdconfig_.zonecfg[23]) ; }
// Let's hope no one wants mroe than 24 inputs
void event_trigger_0 (void) { event_trigger (&_sdconfig_.inputcfg[0]) ; }
void event_trigger_1 (void) { event_trigger (&_sdconfig_.inputcfg[1]) ; }
void event_trigger_2 (void) { event_trigger (&_sdconfig_.inputcfg[2]) ; }
void event_trigger_3 (void) { event_trigger (&_sdconfig_.inputcfg[3]) ; }
void event_trigger_4 (void) { event_trigger (&_sdconfig_.inputcfg[4]) ; }
void event_trigger_5 (void) { event_trigger (&_sdconfig_.inputcfg[5]) ; }
void event_trigger_6 (void) { event_trigger (&_sdconfig_.inputcfg[6]) ; }
void event_trigger_7 (void) { event_trigger (&_sdconfig_.inputcfg[7]) ; }
void event_trigger_8 (void) { event_trigger (&_sdconfig_.inputcfg[8]) ; }
void event_trigger_9 (void) { event_trigger (&_sdconfig_.inputcfg[9]) ; }
void event_trigger_10 (void) { event_trigger (&_sdconfig_.inputcfg[10]) ; }
void event_trigger_11 (void) { event_trigger (&_sdconfig_.inputcfg[11]) ; }
void event_trigger_12 (void) { event_trigger (&_sdconfig_.inputcfg[12]) ; }
void event_trigger_13 (void) { event_trigger (&_sdconfig_.inputcfg[13]) ; }
void event_trigger_14 (void) { event_trigger (&_sdconfig_.inputcfg[14]) ; }
void event_trigger_15 (void) { event_trigger (&_sdconfig_.inputcfg[15]) ; }
void event_trigger_16 (void) { event_trigger (&_sdconfig_.inputcfg[16]) ; }
void event_trigger_17 (void) { event_trigger (&_sdconfig_.inputcfg[17]) ; }
void event_trigger_18 (void) { event_trigger (&_sdconfig_.inputcfg[18]) ; }
void event_trigger_19 (void) { event_trigger (&_sdconfig_.inputcfg[19]) ; }
void event_trigger_20 (void) { event_trigger (&_sdconfig_.inputcfg[20]) ; }
void event_trigger_21 (void) { event_trigger (&_sdconfig_.inputcfg[21]) ; }
void event_trigger_22 (void) { event_trigger (&_sdconfig_.inputcfg[22]) ; }
void event_trigger_23 (void) { event_trigger (&_sdconfig_.inputcfg[23]) ; }
typedef void (*FunctionCallback)();
@ -139,10 +141,10 @@ int main (int argc, char *argv[])
else
_sdconfig_.log_level = LOG_INFO;
readCfg(cfg);
logMessage(LOG_NOTICE,"Starting %s version %s\n",argv[0],SD_VERSION);
readCfg(cfg);
_sdconfig_.calendar = true;
_sdconfig_.currentZone.type = zcNONE;
_sdconfig_.cron_update = 0;
@ -264,27 +266,23 @@ void main_loop ()
pinMode (_sdconfig_.zonecfg[i].pin, _sdconfig_.zonecfg[i].input_output);
if ( _sdconfig_.zonecfg[i].startup_state != -1)
digitalWrite(_sdconfig_.zonecfg[i].pin, _sdconfig_.zonecfg[i].startup_state);
/*
// We actually don't need to register a interupt handeler for outputs. But we will for inputs, so leave this here for future use.
if (registerGPIOinterrupt (_sdconfig_.zonecfg[i].pin, _sdconfig_.zonecfg[i].receive_mode, (void *)&event_trigger, (void *)&_sdconfig_.zonecfg[i]) != true)
logMessage (LOG_DEBUG, "Set GPIO %d to %s\n", _sdconfig_.zonecfg[i].pin,(_sdconfig_.zonecfg[i].input_output==OUTPUT?"OUTPUT":"INPUT") );
}
for (i=0; i < _sdconfig_.inputs ; i++)
{
logMessage (LOG_DEBUG, "Setting up Input %d\n", i);
pinMode (_sdconfig_.inputcfg[i].pin, _sdconfig_.inputcfg[i].input_output);
if (registerGPIOinterrupt (_sdconfig_.inputcfg[i].pin, _sdconfig_.inputcfg[i].receive_mode, (void *)&event_trigger, (void *)&_sdconfig_.inputcfg[i]) != true)
{
displayLastSystemError ("Unable to set interrupt handler for specified pin, exiting");
exit (EXIT_FAILURE);
}
*/
logMessage (LOG_DEBUG, "Set GPIO %d to %s\n", _sdconfig_.zonecfg[i].pin,(_sdconfig_.zonecfg[i].input_output==OUTPUT?"OUTPUT":"INPUT") );
}
#endif
/*
for (i=0; i < _sdconfig_.pinscfgs ; i++)
{
if ( _sdconfig_.zonecfg[i].startup_state == 0 || _sdconfig_.zonecfg[i].startup_state == 1 ) {
logMessage (LOG_DEBUG, "Setting pin %d to state %d\n", _sdconfig_.zonecfg[i].pin, _sdconfig_.zonecfg[i].startup_state);
digitalWrite(_sdconfig_.zonecfg[i].pin, _sdconfig_.zonecfg[i].startup_state);
}
}
*/
logMessage (LOG_DEBUG, "GPIO setup complete\n");
logMessage (LOG_DEBUG, "Starting HTTPD\n");
@ -385,56 +383,34 @@ void event_trigger (struct GPIOcfg *gpiopin)
//int out_state_toset;
int in_state_read;
time_t rawtime;
struct tm * timeinfo;
char timebuffer[20];
//struct tm * timeinfo;
//char timebuffer[20];
//bool changed=false;
time (&rawtime);
timeinfo = localtime (&rawtime);
strftime (timebuffer,20,"%T",timeinfo);
//timeinfo = localtime (&rawtime);
//strftime (timebuffer,20,"%T",timeinfo);
//printf("Received trigger %d - at %s - last trigger %d\n",digitalRead (gpioconfig->pin), timebuffer, gpioconfig->last_event_state);
logMessage (LOG_DEBUG,"%s Received input change on pin %d - START\n",timebuffer, gpiopin->pin);
logMessage (LOG_INFO,"Received input change on pin %d\n", gpiopin->pin);
if ( (rawtime - gpiopin->last_event_time) < 1 && gpiopin->input_output == INPUT)
{
logMessage (LOG_DEBUG," ignoring, time between triggers too short (%d-%d)=%d\n",rawtime, gpiopin->last_event_time, (rawtime - gpiopin->last_event_time));
logMessage (LOG_DEBUG,"Ignoring input event on pin %d, time between triggers too short (%d-%d)=%d\n",gpiopin->pin,rawtime, gpiopin->last_event_time, (rawtime - gpiopin->last_event_time));
return;
}
gpiopin->last_event_time = rawtime;
//logMessage (LOG_DEBUG,"Diff between last event %d (%d, %d)\n",rawtime - gpioconfig->last_event_time, rawtime, gpioconfig->last_event_time);
/* Handle button pressed interrupts */
in_state_read = digitalRead (gpiopin->pin);
//logMessage (LOG_DEBUG, " Init pin state %d, previous state %d\n", in_state_read, gpiopin->last_event_state);
//if ( gpioconfig->receive_state == BOTH || in_state_read == gpioconfig->receive_state)
//{
gpiopin->last_event_state = in_state_read;
if ( in_state_read == gpiopin->on_state && strlen(gpiopin->command_on) > 0)
run_external(gpiopin->command_on);
else if ( in_state_read == !gpiopin->on_state && strlen(gpiopin->command_off) > 0)
run_external(gpiopin->command_off);
/*
if (gpiopin->ext_cmd != NULL && strlen(gpiopin->ext_cmd) > 0) {
//logMessage (LOG_DEBUG, "command '%s'\n", gpioconfig->ext_cmd);
run_external(gpiopin->ext_cmd, in_state_read);
}
*/
//sleep(1);
//} else {
// logMessage (LOG_DEBUG," ignoring, reseived state does not match cfg\n");
// return;
//if (_mgr.active_connections != NULL) {
// _sdconfig_.eventToUpdateHappened = true;
//}
// Sleep for 1 second just to limit duplicte events
//sleep(1);
logMessage (LOG_DEBUG,"%s Receive input change on pin %d - END\n",timebuffer, gpiopin->pin);
//if (changed ==true )
if (_mgr.active_connections != NULL) {
_sdconfig_.eventToUpdateHappened = true;
//broadcast_zonestate(_mgr.active_connections, gpiopin);
}
}

View File

@ -301,13 +301,11 @@ char * replace(char const * const original, char const * const pattern, char con
}
}
void run_external(char *command, int state)
void run_external(char *command)
{
char *cmd = replace(command, "%STATE%", (state==1?"1":"0"));
system(cmd);
logMessage (LOG_DEBUG, "Ran command '%s'\n", cmd);
free(cmd);
system(command);
logMessage (LOG_DEBUG, "Ran command '%s'\n", command);
return;
}

View File

@ -16,7 +16,7 @@ void daemonise ( char *pidFile, void (*main_function)(void) );
void displayLastSystemError (const char *on_what);
void logMessage(int level, char *format, ...);
int count_characters(const char *str, char character);
void run_external(char *command, int state);
void run_external(char *command);
int str2int(const char* str, int len);
float str2float(const char* str, int len);
//void readCfg (char *cfgFile);

View File

@ -1,6 +1,6 @@
#ifndef SD_VERSION_H
#define SD_VERSION_H
#define SD_VERSION "1.0f"
#define SD_VERSION "1.0g"
#endif

View File

@ -42,8 +42,9 @@ int start_next_zone(int startz) {
int zone = startz+1;
while( _sdconfig_.zonecfg[zone].default_runtime <= 0 ) {
logMessage (LOG_INFO, "Run Zone, skipping zone %d due to runtime of %d\n",zone,_sdconfig_.zonecfg[zone].default_runtime);
while( _sdconfig_.zonecfg[zone].default_runtime <= 0 || !validGPIO( _sdconfig_.zonecfg[zone].pin) ) {
//logMessage (LOG_INFO, "Run Zone, skipping zone %d due to runtime of %d\n",zone,_sdconfig_.zonecfg[zone].default_runtime);
logMessage (LOG_INFO, "Run Zone, skipping zone %d due to %s\n",zone,_sdconfig_.zonecfg[zone].default_runtime<=0?" runtime of 0":" bad GPIO pin#");
zone++;
if (zone > _sdconfig_.zones) { // No more zones left to run, turn everything off
_sdconfig_.currentZone.type=zcNONE;
@ -54,12 +55,17 @@ int start_next_zone(int startz) {
}
}
_sdconfig_.currentZone.zone=zone;
zc_start(_sdconfig_.currentZone.zone);
zc_master(zcON);
time(&_sdconfig_.currentZone.started_time);
_sdconfig_.currentZone.duration=_sdconfig_.zonecfg[_sdconfig_.currentZone.zone].default_runtime;
calc_timeleft();
if ( zc_start(zone) == true) {
_sdconfig_.currentZone.zone=zone;
zc_master(zcON);
time(&_sdconfig_.currentZone.started_time);
_sdconfig_.currentZone.duration=_sdconfig_.zonecfg[_sdconfig_.currentZone.zone].default_runtime;
calc_timeleft();
} else {
logMessage (LOG_ERR, "Run Zone, failed to start zone %d, check GPIO\n",zone);
return start_next_zone(zone);
}
return zone;
}
@ -178,15 +184,19 @@ bool zc_zone(zcRunType type, int zone, zcState state, int length) {
zc_stop(i);
}
}
zc_start(zone);
zc_master(zcON);
_sdconfig_.currentZone.type=type;
_sdconfig_.currentZone.zone=zone;
_sdconfig_.currentZone.duration=length;
logMessage (LOG_DEBUG, "set runtime to %d and %d\n",length,_sdconfig_.currentZone.duration);
time(&_sdconfig_.currentZone.started_time);
calc_timeleft();
return true;
if ( zc_start(zone) == true) {
zc_master(zcON);
_sdconfig_.currentZone.type=type;
_sdconfig_.currentZone.zone=zone;
_sdconfig_.currentZone.duration=length;
logMessage (LOG_DEBUG, "set runtime to %d and %d\n",length,_sdconfig_.currentZone.duration);
time(&_sdconfig_.currentZone.started_time);
calc_timeleft();
return true;
} else {
logMessage (LOG_ERR, "Request to turn on zone %d failed, check GPIO\n",zone);
return false;
}
} else {
logMessage (LOG_WARNING, "Request to turn zone %d on. Ignored due to runtime being %d\n",zone,length);
return false;
@ -206,38 +216,45 @@ bool zc_zone(zcRunType type, int zone, zcState state, int length) {
return false;
}
bool zc_start(/*zcRunType type,*/ int zone) {
// check anything on, turn off
// Turn on master valve if we have one
// turn on zone
// Check if zone is already on
if ( _sdconfig_.zonecfg[zone].on_state == digitalRead (_sdconfig_.zonecfg[zone].pin)) {
logMessage (LOG_DEBUG, "Request to turn zone %d on. Zone %d is already on, ignoring!\n",zone,zone);
return false;
}
logMessage (LOG_NOTICE, "Turning on Zone %d\n",zone);
#ifndef USE_WIRINGPI
int rtn = digitalWrite(_sdconfig_.zonecfg[zone].pin, _sdconfig_.zonecfg[zone].on_state );
#else
digitalWrite(_sdconfig_.zonecfg[zone].pin, _sdconfig_.zonecfg[zone].on_state );
int rtn = true;
#endif
_sdconfig_.eventToUpdateHappened = true;
// store what's running
return true;
if (rtn == true)
return true;
else
return false;
}
bool zc_stop(/*zcRunType type,*/ int zone) {
// Turn on master valve if we have one
// Check if zone is alreay off
if ( _sdconfig_.zonecfg[zone].on_state != digitalRead (_sdconfig_.zonecfg[zone].pin)) {
logMessage (LOG_DEBUG, "Request to turn zone %d off. Zone %d is already off, ignoring!\n",zone,zone);
return false;
}
logMessage (LOG_NOTICE, "Turning off Zone %d\n",zone);
#ifndef USE_WIRINGPI
int rtn = digitalWrite(_sdconfig_.zonecfg[zone].pin, !_sdconfig_.zonecfg[zone].on_state );
#else
digitalWrite(_sdconfig_.zonecfg[zone].pin, !_sdconfig_.zonecfg[zone].on_state );
int rtn = true;
#endif
_sdconfig_.eventToUpdateHappened = true;
//_sdconfig_.zonecfg[zone]
// turn off zone
// delete what's running
return true;
if (rtn == true)
return true;
else
return false;
}