parent
e93ad44028
commit
cb920a03d3
9
Makefile
9
Makefile
|
@ -49,7 +49,14 @@ GPIO = ./release/gpio
|
||||||
# deleting dependencies appended to the file from 'make depend'
|
# deleting dependencies appended to the file from 'make depend'
|
||||||
#
|
#
|
||||||
|
|
||||||
.PHONY: depend clean
|
.PHONY: depend clean release
|
||||||
|
|
||||||
|
release:
|
||||||
|
sudo docker run -it --mount type=bind,source=./,target=/build aqualinkd-releasebin make armhf
|
||||||
|
$(info Binaries for release have been built)
|
||||||
|
|
||||||
|
armhf: CC = arm-linux-gnueabihf-gcc
|
||||||
|
armhf: $(MAIN)
|
||||||
|
|
||||||
all: $(MAIN)
|
all: $(MAIN)
|
||||||
@echo: $(MAIN) have been compiled
|
@echo: $(MAIN) have been compiled
|
||||||
|
|
29
config.c
29
config.c
|
@ -368,6 +368,7 @@ void readCfg(char *inifile)
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_sdconfig_.inputs = 0;
|
||||||
// Caculate how many inputs we have
|
// Caculate how many inputs we have
|
||||||
for (i=1; i <= 24; i++) // 24 = Just some arbutary number (max GPIO without expansion board)
|
for (i=1; i <= 24; i++) // 24 = Just some arbutary number (max GPIO without expansion board)
|
||||||
{
|
{
|
||||||
|
@ -420,6 +421,34 @@ void readCfg(char *inifile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_sdconfig_.runBeforeCmds = 0;
|
||||||
|
// Caculate how many external command to run
|
||||||
|
for (i=1; i <= 10; i++) // 10 = Just some arbutary number
|
||||||
|
{
|
||||||
|
sprintf(str, "EXTERNAL:%d", i);
|
||||||
|
pin = ini_getl(str, "RUNB4STARTTIME", -1, inifile);
|
||||||
|
if (pin == -1)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
_sdconfig_.runBeforeCmds = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( _sdconfig_.runBeforeCmds != 0) {
|
||||||
|
// n= _sdconfig_.zones+1;
|
||||||
|
_sdconfig_.runBeforeCmd = malloc((_sdconfig_.runBeforeCmds) * sizeof(struct RunB4CalStart));
|
||||||
|
for (i=0; i < _sdconfig_.runBeforeCmds; i++)
|
||||||
|
{
|
||||||
|
sprintf(str, "EXTERNAL:%d", i+1);
|
||||||
|
_sdconfig_.runBeforeCmd[i].mins = ini_getl(str, "RUNB4STARTTIME", -1, inifile);
|
||||||
|
ini_gets(str, "COMMAND", NULL, _sdconfig_.runBeforeCmd[i].command, sizearray(_sdconfig_.runBeforeCmd[i].command), inifile);
|
||||||
|
//if (_sdconfig_.runBeforeCmd[i].mins <= 0 || _sdconfig_.runBeforeCmd[i].mins > 120) {
|
||||||
|
// logMessage (LOG_ERR, "RUNB4STARTTIME %d is not valid, found in EXTERNAL:%d of configuration file %s \n",_sdconfig_.runBeforeCmd[i].mins, i+1, inifile);
|
||||||
|
// continue;
|
||||||
|
//}
|
||||||
|
logMessage (LOG_DEBUG,"Run external command '%s', %d mins before start time\n",_sdconfig_.runBeforeCmd[i].command, _sdconfig_.runBeforeCmd[i].mins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
idx=0;
|
idx=0;
|
||||||
|
|
31
config.h
31
config.h
|
@ -24,6 +24,11 @@ struct CALENDARday {
|
||||||
int minute;
|
int minute;
|
||||||
int *zruntimes;
|
int *zruntimes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RunB4CalStart {
|
||||||
|
int mins;
|
||||||
|
char command[256];
|
||||||
|
};
|
||||||
/*
|
/*
|
||||||
struct GPIOextra {
|
struct GPIOextra {
|
||||||
char command_high[COMMAND_SIZE];
|
char command_high[COMMAND_SIZE];
|
||||||
|
@ -96,8 +101,11 @@ struct sprinklerdcfg {
|
||||||
long cron_update;
|
long cron_update;
|
||||||
int log_level;
|
int log_level;
|
||||||
struct szRunning currentZone;
|
struct szRunning currentZone;
|
||||||
|
struct RunB4CalStart *runBeforeCmd;
|
||||||
|
int runBeforeCmds;
|
||||||
char cache_file[512];
|
char cache_file[512];
|
||||||
bool eventToUpdateHappened;
|
//bool eventToUpdateHappened;
|
||||||
|
uint8_t updateEventMask;
|
||||||
int todayRainChance;
|
int todayRainChance;
|
||||||
float todayRainTotal;
|
float todayRainTotal;
|
||||||
};
|
};
|
||||||
|
@ -127,5 +135,26 @@ void read_cache();
|
||||||
#define ON 0
|
#define ON 0
|
||||||
#define OFF 1
|
#define OFF 1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define UPDATE_RAINTOTAL (1 << 0) //
|
||||||
|
#define UPDATE_RAINPROBABILITY (1 << 1) //
|
||||||
|
#define UPDATE_ZONES (1 << 2) //
|
||||||
|
#define UPDATE_STATUS (1 << 3) //
|
||||||
|
|
||||||
|
#define isEventRainTotal ((_sdconfig_.updateEventMask & UPDATE_RAINTOTAL) == UPDATE_RAINTOTAL)
|
||||||
|
#define isEventRainProbability ((_sdconfig_.updateEventMask & UPDATE_RAINPROBABILITY) == UPDATE_RAINPROBABILITY)
|
||||||
|
#define isEventZones ((_sdconfig_.updateEventMask & UPDATE_ZONES) == UPDATE_ZONES)
|
||||||
|
#define isEventStatus ((_sdconfig_.updateEventMask & UPDATE_STATUS) == UPDATE_STATUS)
|
||||||
|
|
||||||
|
#define setEventRainTotal (_sdconfig_.updateEventMask |= UPDATE_RAINTOTAL)
|
||||||
|
#define setEventRainProbability (_sdconfig_.updateEventMask |= UPDATE_RAINPROBABILITY)
|
||||||
|
#define setEventZones (_sdconfig_.updateEventMask |= UPDATE_ZONES)
|
||||||
|
#define setEventStatus (_sdconfig_.updateEventMask |= UPDATE_STATUS)
|
||||||
|
|
||||||
|
#define clearEventRainTotal (_sdconfig_.updateEventMask &= ~UPDATE_RAINTOTAL)
|
||||||
|
#define clearEventRainProbability (_sdconfig_.updateEventMask &= ~UPDATE_RAINPROBABILITY)
|
||||||
|
#define clearEventZones (_sdconfig_.updateEventMask &= ~UPDATE_ZONES)
|
||||||
|
#define clearEventStatus (_sdconfig_.updateEventMask &= ~UPDATE_STATUS)
|
||||||
|
|
||||||
#define NO_CHANGE 2
|
#define NO_CHANGE 2
|
||||||
#endif /* CONFIG_H_ */
|
#endif /* CONFIG_H_ */
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
#
|
|
||||||
# darkskyAPI = your DarkSky API key below, it's free to get one
|
|
||||||
# location = your location lat,long
|
|
||||||
# probabilityOver = Enable rain delay if probability of rain today is grater than this number.
|
|
||||||
# Range is 0 to 1, so 0.5 is 50%
|
|
||||||
# sprinklerdEnableDelay = the URL to SprinklerD
|
|
||||||
#
|
|
||||||
# The below are NOT valid, you MUST chaneg them to your information.
|
|
||||||
darkskyAPI='xxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
|
||||||
location='42.3601,-71.0589'
|
|
||||||
|
|
||||||
probabilityOver=1.0 # 1.0 means don't set delay from this script, use the SprinklerD config (webUI) to decide if to set delay
|
|
||||||
|
|
||||||
sprinklerdEnableDelay="http://localhost/?type=option&option=24hdelay&state=reset"
|
|
||||||
sprinklerdProbability="http://localhost/?type=sensor&sensor=chanceofrain&value="
|
|
||||||
|
|
||||||
echoerr() { printf "%s\n" "$*" >&2; }
|
|
||||||
echomsg() { if [ -t 1 ]; then echo "$@" 1>&2; fi; }
|
|
||||||
|
|
||||||
command -v curl >/dev/null 2>&1 || { echoerr "curl is not installed. Aborting!"; exit 1; }
|
|
||||||
command -v jq >/dev/null 2>&1 || { echoerr "jq is not installed. Aborting!"; exit 1; }
|
|
||||||
command -v bc >/dev/null 2>&1 || { echoerr "bc not installed. Aborting!"; exit 1; }
|
|
||||||
|
|
||||||
darkskyJSON=$(curl -s "https://api.darksky.net/forecast/"$darkskyAPI"/"$location)
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echoerr "Error reading DarkSkys URL, please check!"
|
|
||||||
echoerr "Maybe you didn't configure your API and location?"
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
|
|
||||||
probability=$(echo $darkskyJSON | jq '.["daily"].data[0].precipProbability' )
|
|
||||||
|
|
||||||
#if [ $? -ne 0 ]; then
|
|
||||||
if [ "$probability" == "null" ]; then
|
|
||||||
echoerr "Error reading DarkSkys JSON, please check!"
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
echomsg -n "Probability of rain today is "`echo "$probability * 100" | bc`"%"
|
|
||||||
|
|
||||||
curl -s "$sprinklerdProbability`echo \"$probability * 100\" | bc`" > /dev/null
|
|
||||||
|
|
||||||
if (( $(echo "$probability > $probabilityOver" | bc -l) )); then
|
|
||||||
echomsg -n ", enabeling rain delay"
|
|
||||||
curl -s "$sprinklerdEnableDelay" > /dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
echomsg ""
|
|
|
@ -1,30 +0,0 @@
|
||||||
|
|
||||||
#
|
|
||||||
# Change the URL's below to point to Meteohub server and SprinklerD server
|
|
||||||
#
|
|
||||||
|
|
||||||
meteohubRainTotal="http://hurricane/meteograph.cgi?text=day1_rain0_total_in"
|
|
||||||
#meteohubRainTotal="http://192.168.144.101/meteograph.cgi?text=last24h_rain0_total_in"
|
|
||||||
#meteohubRainTotal="http://192.168.144.101/meteograph.cgi?text=alltime_rain0_total_in"
|
|
||||||
|
|
||||||
sprinklerdSetRainTotal="http://localhost/?type=sensor&sensor=raintotal&value="
|
|
||||||
|
|
||||||
echoerr() { printf "%s\n" "$*" >&2; }
|
|
||||||
echomsg() { if [ -t 1 ]; then echo "$@" 1>&2; fi; }
|
|
||||||
|
|
||||||
command -v curl >/dev/null 2>&1 || { echoerr "curl is not installed. Aborting!"; exit 1; }
|
|
||||||
|
|
||||||
rainTotal=$(curl -s "$meteohubRainTotal")
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echoerr "Error reading Metrohub URL, please check!"
|
|
||||||
echoerr "Assuming rain sensor is not responding, not sending rain total to SprinklerD"
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
|
|
||||||
echomsg -n "Rain total is $rainTotal\" at `date`"
|
|
||||||
|
|
||||||
|
|
||||||
curl -s "$sprinklerdSetRainTotal$rainTotal" > /dev/null
|
|
||||||
|
|
||||||
echomsg ""
|
|
|
@ -1,53 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
#
|
|
||||||
# openweatherAPI = your Openweather API key below, it's free to get one
|
|
||||||
# lat = your latitude
|
|
||||||
# lon = your longitude
|
|
||||||
# probabilityOver = Enable rain delay if probability of rain today is grater than this number.
|
|
||||||
# Range is 0 to 1, so 0.5 is 50%
|
|
||||||
# sprinklerdEnableDelay = the URL to SprinklerD
|
|
||||||
#
|
|
||||||
# The below are NOT valid, you MUST chaneg them to your information.
|
|
||||||
openweatherAPI='xxxxxxxxxxxxxxxxxxxxxxxxxx'
|
|
||||||
lat='42.3601'
|
|
||||||
lon='-71.0589'
|
|
||||||
|
|
||||||
probabilityOver=1.0 # 1.0 means don't set delay from this script, use the SprinklerD config (webUI) to decide if to set delay
|
|
||||||
|
|
||||||
sprinklerdEnableDelay="http://localhost/?type=option&option=24hdelay&state=reset"
|
|
||||||
sprinklerdProbability="http://localhost/?type=sensor&sensor=chanceofrain&value="
|
|
||||||
|
|
||||||
echoerr() { printf "%s\n" "$*" >&2; }
|
|
||||||
echomsg() { if [ -t 1 ]; then echo "$@" 1>&2; fi; }
|
|
||||||
|
|
||||||
command -v curl >/dev/null 2>&1 || { echoerr "curl is not installed. Aborting!"; exit 1; }
|
|
||||||
command -v jq >/dev/null 2>&1 || { echoerr "jq is not installed. Aborting!"; exit 1; }
|
|
||||||
command -v bc >/dev/null 2>&1 || { echoerr "bc not installed. Aborting!"; exit 1; }
|
|
||||||
|
|
||||||
openweatherJSON=$(curl -s "https://api.openweathermap.org/data/2.5/onecall?lat="$lat"&lon="$lon"&appid="$openweatherAPI"&exclude=current,minutely,hourly,alerts")
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echoerr "Error reading OpenWeather URL, please check!"
|
|
||||||
echoerr "Maybe you didn't configure your API and location?"
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
|
|
||||||
probability=$(echo $openweatherJSON | jq '.["daily"][0].pop' )
|
|
||||||
|
|
||||||
#if [ $? -ne 0 ]; then
|
|
||||||
if [ "$probability" == "null" ]; then
|
|
||||||
echoerr "Error reading OpenWeather JSON, please check!"
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
echomsg -n "Probability of rain today is "`echo "$probability * 100" | bc`"%"
|
|
||||||
|
|
||||||
curl -s "$sprinklerdProbability`echo \"$probability * 100\" | bc`" > /dev/null
|
|
||||||
|
|
||||||
if (( $(echo "$probability > $probabilityOver" | bc -l) )); then
|
|
||||||
echomsg -n ", enabeling rain delay"
|
|
||||||
curl -s "$sprinklerdEnableDelay" > /dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
echomsg ""
|
|
|
@ -10,6 +10,9 @@
|
||||||
#
|
#
|
||||||
# The below are NOT valid, you MUST change them to your information.
|
# The below are NOT valid, you MUST change them to your information.
|
||||||
|
|
||||||
|
#Can use below to track best api for location
|
||||||
|
#https://www.forecastadvisor.com/
|
||||||
|
|
||||||
# API Keys from the following are supported
|
# API Keys from the following are supported
|
||||||
# openweathermap.org weatherapi.com weatherbit.io climacell.co
|
# openweathermap.org weatherapi.com weatherbit.io climacell.co
|
||||||
|
|
||||||
|
@ -17,9 +20,12 @@ openweatherAPIkey='-----'
|
||||||
weatherbitAPIkey='-----'
|
weatherbitAPIkey='-----'
|
||||||
climacellAPIkey='-----'
|
climacellAPIkey='-----'
|
||||||
weatherAPIkey='-----'
|
weatherAPIkey='-----'
|
||||||
|
accuweatherAPI='-----'
|
||||||
|
|
||||||
lat='42.3601'
|
lat='42.3601'
|
||||||
lon='-71.0589'
|
lon='-71.0589'
|
||||||
|
zip='11111'
|
||||||
|
|
||||||
|
|
||||||
# 101 means don't set rain delay from this script, use the SprinklerD config (webUI) to decide if to set delay
|
# 101 means don't set rain delay from this script, use the SprinklerD config (webUI) to decide if to set delay
|
||||||
probabilityOver=101
|
probabilityOver=101
|
||||||
|
@ -43,13 +49,27 @@ openweatherURL="https://api.openweathermap.org/data/2.5/onecall?lat=$lat&lon=$lo
|
||||||
weatherbitURL="https://api.weatherbit.io/v2.0/forecast/daily?key=$weatherbitAPIkey&lat=$lat&lon=$lon"
|
weatherbitURL="https://api.weatherbit.io/v2.0/forecast/daily?key=$weatherbitAPIkey&lat=$lat&lon=$lon"
|
||||||
climacellURL="https://data.climacell.co/v4/timelines?location=$lat%2C$lon&fields=precipitationProbability×teps=1d&units=metric&apikey=$climacellAPIkey"
|
climacellURL="https://data.climacell.co/v4/timelines?location=$lat%2C$lon&fields=precipitationProbability×teps=1d&units=metric&apikey=$climacellAPIkey"
|
||||||
weatherAPIlURL="http://api.weatherapi.com/v1/forecast.json?key=$weatherAPIkey&q=$lat,$lon&days=1&aqi=no&alerts=no"
|
weatherAPIlURL="http://api.weatherapi.com/v1/forecast.json?key=$weatherAPIkey&q=$lat,$lon&days=1&aqi=no&alerts=no"
|
||||||
|
openmeteoURL="https://api.open-meteo.com/v1/forecast?latitude=$lat&longitude=$lon&daily=precipitation_probability_max&timezone=America%2FChicago&forecast_days=1"
|
||||||
|
accuweatherURL="http://dataservice.accuweather.com/forecasts/v1/daily/1day/$zip?apikey=$accuweatherAPI&details=true"
|
||||||
|
pirateweatherURL="https://api.pirateweather.net/forecast/$pirateweatherAPI/$lat%2C$lon?exclude=minutely%2Chourly%2Calerts"
|
||||||
|
|
||||||
|
|
||||||
true=0
|
true=0
|
||||||
false=1
|
false=1
|
||||||
|
|
||||||
|
OUT_FIRST=1
|
||||||
|
OUT_MAX=2
|
||||||
|
OUT_MIN=3
|
||||||
|
OUT_AVERAGE=4
|
||||||
|
OUT_PRINT_ONLY=5
|
||||||
|
|
||||||
|
output=$OUT_FIRST
|
||||||
|
|
||||||
echoerr() { printf "%s\n" "$*" >&2; }
|
echoerr() { printf "%s\n" "$*" >&2; }
|
||||||
echomsg() { if [ -t 1 ]; then echo "$@" 1>&2; fi; }
|
echomsg() { if [ -t 1 ]; then echo "$@" 1>&2; fi; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function getURL() {
|
function getURL() {
|
||||||
url=$1
|
url=$1
|
||||||
jq=$2
|
jq=$2
|
||||||
|
@ -66,6 +86,11 @@ function getURL() {
|
||||||
probability=$(echo $JSON | jq "$jq" )
|
probability=$(echo $JSON | jq "$jq" )
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if ! [[ $probability =~ ^[0-9]+([.][0-9]+)?$ ]]; then
|
||||||
|
echoerr "Did not get a number from probability API result=$probability"
|
||||||
|
return $false
|
||||||
|
fi
|
||||||
|
|
||||||
probability=$(echo "$probability * $factor / 1" | bc )
|
probability=$(echo "$probability * $factor / 1" | bc )
|
||||||
echo $probability
|
echo $probability
|
||||||
return $true
|
return $true
|
||||||
|
@ -76,63 +101,129 @@ command -v curl >/dev/null 2>&1 || { echoerr "curl is not installed. Aborting!"
|
||||||
command -v jq >/dev/null 2>&1 || { echoerr "jq is not installed. Aborting!"; exit 1; }
|
command -v jq >/dev/null 2>&1 || { echoerr "jq is not installed. Aborting!"; exit 1; }
|
||||||
command -v bc >/dev/null 2>&1 || { echoerr "bc not installed. Aborting!"; exit 1; }
|
command -v bc >/dev/null 2>&1 || { echoerr "bc not installed. Aborting!"; exit 1; }
|
||||||
|
|
||||||
pop=-1
|
probArray=()
|
||||||
|
|
||||||
if [ "$#" -lt 1 ]; then
|
if [ "$#" -lt 1 ]; then
|
||||||
echomsg "Pass at least one command line parameter (openweather, weatherbit, climacell, weatherapi)"
|
echomsg "Pass at least one command line parameter (openweather, weatherbit, climacell, weatherapi, openmeteo, accuweather, pirateweather)"
|
||||||
|
echomsg "if you pass more than 1 of above, can also use one of folowing -max -min -average -first"
|
||||||
|
echomsg "Example:-"
|
||||||
|
echomsg " $0 openweather weatherapi -average"
|
||||||
|
echomsg ""
|
||||||
exit 1;
|
exit 1;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for var in "$@"
|
for var in "$@"
|
||||||
do
|
do
|
||||||
case "$var" in
|
case "$var" in
|
||||||
|
-max)
|
||||||
|
output=$OUT_MAX
|
||||||
|
;;
|
||||||
|
-min)
|
||||||
|
output=$OUT_MIN
|
||||||
|
;;
|
||||||
|
-average)
|
||||||
|
output=$OUT_AVERAGE
|
||||||
|
;;
|
||||||
|
-first)
|
||||||
|
output=$OUT_FIRST
|
||||||
|
;;
|
||||||
|
-print)
|
||||||
|
output=$OUT_PRINT_ONLY
|
||||||
|
;;
|
||||||
openweather)
|
openweather)
|
||||||
if [ "$openweatherAPIkey" == "-----" ]; then echomsg "missing OpenWeather API key" && continue; fi
|
if [ "$openweatherAPIkey" == "-----" ]; then echomsg "missing OpenWeather API key" && continue; fi
|
||||||
if probability=$(getURL "$openweatherURL" '.["daily"][0].pop' "100"); then
|
if probability=$(getURL "$openweatherURL" '.["daily"][0].pop' "100"); then
|
||||||
echomsg "OpenWeather probability of rain today is $probability%"
|
echomsg "OpenWeather probability of rain today is $probability%"
|
||||||
pop=$(echo "if($probability>$pop)print $probability else print $pop" | bc -l)
|
#pop=$(echo "if($probability>$pop)print $probability else print $pop" | bc -l)
|
||||||
|
probArray+=($probability)
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
weatherbit)
|
weatherbit)
|
||||||
if [ "$weatherbitAPIkey" == "-----" ]; then echomsg "missing WeatherBit API key" && continue; fi
|
if [ "$weatherbitAPIkey" == "-----" ]; then echomsg "missing WeatherBit API key" && continue; fi
|
||||||
if probability=$(getURL "$weatherbitURL" '.data[0].pop' "1"); then
|
if probability=$(getURL "$weatherbitURL" '.data[0].pop' "1"); then
|
||||||
echomsg "WeatherBit probability of rain today is $probability%"
|
echomsg "WeatherBit probability of rain today is $probability%"
|
||||||
pop=$(echo "if($probability>$pop)print $probability else print $pop" | bc -l)
|
#pop=$(echo "if($probability>$pop)print $probability else print $pop" | bc -l)
|
||||||
|
probArray+=($probability)
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
climacell)
|
climacell)
|
||||||
if [ "$climacellAPIkey" == "-----" ]; then echomsg "missing ClimaCell API key" && continue; fi
|
if [ "$climacellAPIkey" == "-----" ]; then echomsg "missing ClimaCell API key" && continue; fi
|
||||||
if probability=$(getURL "$climacellURL" '.data.timelines[0].intervals[0].values.precipitationProbability' "1"); then
|
if probability=$(getURL "$climacellURL" '.data.timelines[0].intervals[0].values.precipitationProbability' "1"); then
|
||||||
echomsg "ClimaCell probability of rain today is $probability%"
|
echomsg "ClimaCell probability of rain today is $probability%"
|
||||||
pop=$(echo "if($probability>$pop)print $probability else print $pop" | bc -l)
|
probArray+=($probability)
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
weatherapi)
|
weatherapi)
|
||||||
if [ "$weatherAPIkey" == "-----" ]; then echomsg "missing WeatherAPI API key" && continue; fi
|
if [ "$weatherAPIkey" == "-----" ]; then echomsg "missing WeatherAPI API key" && continue; fi
|
||||||
if probability=$(getURL "$weatherAPIlURL" '.forecast.forecastday[0].day.daily_chance_of_rain' "1"); then
|
if probability=$(getURL "$weatherAPIlURL" '.forecast.forecastday[0].day.daily_chance_of_rain' "1"); then
|
||||||
echomsg "WeatherAPI probability of rain today is $probability%"
|
echomsg "WeatherAPI probability of rain today is $probability%"
|
||||||
pop=$(echo "if($probability>$pop)print $probability else print $pop" | bc -l)
|
probArray+=($probability)
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
openmeteo)
|
||||||
|
if probability=$(getURL "$openmeteoURL" '.daily.precipitation_probability_max[]' "1"); then
|
||||||
|
echomsg "Open Meteo probability of rain today is $probability%"
|
||||||
|
probArray+=($probability)
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
accuweather)
|
||||||
|
if probability=$(getURL "$accuweatherURL" '.DailyForecasts[0].Day.PrecipitationProbability' "1"); then
|
||||||
|
echomsg "AccuWeather probability of rain today is $probability%"
|
||||||
|
probArray+=($probability)
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
pirateweather)
|
||||||
|
if probability=$(getURL "$pirateweatherURL" '.daily.data[0].precipProbability' "100"); then
|
||||||
|
echomsg "PirateWeather probability of rain today is $probability%"
|
||||||
|
probArray+=($probability)
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
# Remove all new line, carriage return, tab characters
|
|
||||||
# from the string, to allow integer comparison
|
|
||||||
pop="${pop//[$'\t\r\n ']}"
|
|
||||||
|
|
||||||
if [ "$pop" -lt 0 ]; then
|
if [ ${#probArray[@]} -le 0 ]; then
|
||||||
echoerr "Error reading Probability, please check!"
|
echoerr "No rain probability values found"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echomsg "Chance of rain $pop%"
|
|
||||||
|
|
||||||
curl -s "$sprinklerdProbability$pop" > /dev/null
|
prop=${probArray[0]}
|
||||||
|
|
||||||
if (( $(echo "$pop > $probabilityOver" | bc -l) )); then
|
case $output in
|
||||||
|
$OUT_PRINT_ONLY)
|
||||||
|
exit 0;
|
||||||
|
;;
|
||||||
|
$OUT_FIRST)
|
||||||
|
prop=${probArray[0]}
|
||||||
|
;;
|
||||||
|
$OUT_MAX)
|
||||||
|
for n in "${probArray[@]}" ; do
|
||||||
|
((n > prop)) && prop=$n
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
$OUT_MIN)
|
||||||
|
for n in "${probArray[@]}" ; do
|
||||||
|
((n < prop)) && prop=$n
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
$OUT_AVERAGE)
|
||||||
|
prop=0
|
||||||
|
for n in "${probArray[@]}" ; do
|
||||||
|
let prop=prop+n
|
||||||
|
done
|
||||||
|
let prop=prop/${#probArray[@]}
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echomsg "Chance of rain $prop%"
|
||||||
|
|
||||||
|
curl -s "$sprinklerdProbability$prop" > /dev/null
|
||||||
|
|
||||||
|
if (( $(echo "$prop > $probabilityOver" | bc -l) )); then
|
||||||
echomsg "Enabeling rain delay"
|
echomsg "Enabeling rain delay"
|
||||||
curl -s "$sprinklerdEnableDelay" > /dev/null
|
curl -s "$sprinklerdEnableDelay" > /dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|
||||||
|
|
49
hassio.c
49
hassio.c
|
@ -10,13 +10,18 @@
|
||||||
#include "net_services.h"
|
#include "net_services.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//#define HASS_EXPIRE ""\"expire_after"\": 300,"
|
||||||
|
#define HASS_EXPIRE ""
|
||||||
|
|
||||||
#define HASS_DEVICE "\"identifiers\": " \
|
#define HASS_DEVICE "\"identifiers\": " \
|
||||||
"[\"SprinklerD\"]," \
|
"[\"SprinklerD\"]," \
|
||||||
" \"sw_version\": \"" SD_VERSION "\"," \
|
" \"sw_version\": \"" SD_VERSION "\"," \
|
||||||
" \"model\": \"Sprinkler Daemon\"," \
|
" \"model\": \"Sprinkler Daemon\"," \
|
||||||
" \"name\": \"SprinklerD\"," \
|
" \"name\": \"SprinklerD\"," \
|
||||||
" \"manufacturer\": \"SprinklerD\"," \
|
" \"manufacturer\": \"SprinklerD\"," \
|
||||||
" \"suggested_area\": \"pool\""
|
" \"suggested_area\": \"garden\""
|
||||||
|
|
||||||
#define HASS_AVAILABILITY "\"payload_available\" : \"1\"," \
|
#define HASS_AVAILABILITY "\"payload_available\" : \"1\"," \
|
||||||
"\"payload_not_available\" : \"0\"," \
|
"\"payload_not_available\" : \"0\"," \
|
||||||
|
@ -32,6 +37,18 @@ const char *HASSIO_TEXT_SENSOR_DISCOVER = "{"
|
||||||
"\"icon\": \"mdi:card-text\""
|
"\"icon\": \"mdi:card-text\""
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
|
const char *HASSIO_SENSOR_DISCOVER = "{"
|
||||||
|
"\"device\": {" HASS_DEVICE "},"
|
||||||
|
"\"availability\": {" HASS_AVAILABILITY "},"
|
||||||
|
"\"type\": \"sensor\","
|
||||||
|
"\"unique_id\": \"%s\","
|
||||||
|
"\"name\": \"%s\","
|
||||||
|
"\"state_topic\": \"%s/%s\","
|
||||||
|
"\"value_template\": \"{{ value_json }}\","
|
||||||
|
"\"unit_of_measurement\": \"%s\","
|
||||||
|
"\"icon\": \"%s\""
|
||||||
|
"}";
|
||||||
|
|
||||||
const char *HASSIO_SWITCH_DISCOVER = "{"
|
const char *HASSIO_SWITCH_DISCOVER = "{"
|
||||||
"\"device\": {" HASS_DEVICE "},"
|
"\"device\": {" HASS_DEVICE "},"
|
||||||
"\"availability\": {" HASS_AVAILABILITY "},"
|
"\"availability\": {" HASS_AVAILABILITY "},"
|
||||||
|
@ -41,9 +58,7 @@ const char *HASSIO_SWITCH_DISCOVER = "{"
|
||||||
"\"state_topic\": \"%s/%s\","
|
"\"state_topic\": \"%s/%s\","
|
||||||
"\"command_topic\": \"%s/%s/set\","
|
"\"command_topic\": \"%s/%s/set\","
|
||||||
"\"payload_on\": \"1\","
|
"\"payload_on\": \"1\","
|
||||||
"\"payload_off\": \"0\","
|
"\"payload_off\": \"0\""
|
||||||
"\"qos\": 1,"
|
|
||||||
"\"retain\": false"
|
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
const char *HASSIO_VALVE_DISCOVER = "{"
|
const char *HASSIO_VALVE_DISCOVER = "{"
|
||||||
|
@ -57,9 +72,7 @@ const char *HASSIO_VALVE_DISCOVER = "{"
|
||||||
"\"command_topic\": \"%s/zone%d/set\"," // 1
|
"\"command_topic\": \"%s/zone%d/set\"," // 1
|
||||||
"\"value_template\": \"{%% set values = { '0':'closed', '1':'open'} %%}{{ values[value] if value in values.keys() else 'closed' }}\","
|
"\"value_template\": \"{%% set values = { '0':'closed', '1':'open'} %%}{{ values[value] if value in values.keys() else 'closed' }}\","
|
||||||
"\"payload_open\": \"1\","
|
"\"payload_open\": \"1\","
|
||||||
"\"payload_close\": \"0\","
|
"\"payload_close\": \"0\""
|
||||||
"\"qos\": 1,"
|
|
||||||
"\"retain\": false"
|
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
void publish_mqtt_hassio_discover(struct mg_connection *nc)
|
void publish_mqtt_hassio_discover(struct mg_connection *nc)
|
||||||
|
@ -121,6 +134,28 @@ void publish_mqtt_hassio_discover(struct mg_connection *nc)
|
||||||
send_mqtt_msg(nc, topic, msg);
|
send_mqtt_msg(nc, topic, msg);
|
||||||
|
|
||||||
|
|
||||||
|
sprintf(id,"sprinklerd_rainprobability");
|
||||||
|
sprintf(topic, "%s/sensor/sprinklerd/%s/config", _sdconfig_.mqtt_ha_dis_topic, id);
|
||||||
|
sprintf(msg, HASSIO_SENSOR_DISCOVER,
|
||||||
|
_sdconfig_.mqtt_topic,
|
||||||
|
id,
|
||||||
|
"Todays Rain Probability",
|
||||||
|
_sdconfig_.mqtt_topic, "chanceofrain",
|
||||||
|
"%",
|
||||||
|
"mdi:water-percent" );
|
||||||
|
send_mqtt_msg(nc, topic, msg);
|
||||||
|
|
||||||
|
sprintf(id,"sprinklerd_raintotal");
|
||||||
|
sprintf(topic, "%s/sensor/sprinklerd/%s/config", _sdconfig_.mqtt_ha_dis_topic, id);
|
||||||
|
sprintf(msg, HASSIO_SENSOR_DISCOVER,
|
||||||
|
_sdconfig_.mqtt_topic,
|
||||||
|
id,
|
||||||
|
"Todays Rain Total",
|
||||||
|
_sdconfig_.mqtt_topic, "raintotal",
|
||||||
|
"\\\"",
|
||||||
|
"mdi:weather-hail" );
|
||||||
|
send_mqtt_msg(nc, topic, msg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//for (i=(_sdconfig_.master_valve?0:1); i <= _sdconfig_.zones ; i++)
|
//for (i=(_sdconfig_.master_valve?0:1); i <= _sdconfig_.zones ; i++)
|
||||||
|
|
3271
mongoose.c
3271
mongoose.c
File diff suppressed because it is too large
Load Diff
551
mongoose.h
551
mongoose.h
File diff suppressed because it is too large
Load Diff
|
@ -191,7 +191,7 @@ void send_mqtt_msg(struct mg_connection *nc, char *toppic, char *message)
|
||||||
//mg_mqtt_publish(nc, toppic, msg_id, MG_MQTT_QOS(0), message, strlen(message));
|
//mg_mqtt_publish(nc, toppic, msg_id, MG_MQTT_QOS(0), message, strlen(message));
|
||||||
mg_mqtt_publish(nc, toppic, msg_id, MG_MQTT_RETAIN | MG_MQTT_QOS(1), message, strlen(message));
|
mg_mqtt_publish(nc, toppic, msg_id, MG_MQTT_RETAIN | MG_MQTT_QOS(1), message, strlen(message));
|
||||||
|
|
||||||
logMessage(LOG_INFO, "MQTT: Published id=%d: %s %s\n", msg_id, toppic, message);
|
logMessage(LOG_DEBUG, "MQTT: Published id=%d: %s %s\n", msg_id, toppic, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void publish_zone_mqtt(struct mg_connection *nc, struct GPIOcfg *gpiopin) {
|
void publish_zone_mqtt(struct mg_connection *nc, struct GPIOcfg *gpiopin) {
|
||||||
|
@ -322,6 +322,16 @@ void broadcast_sprinklerdactivestate(struct mg_connection *nc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearEventZones;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getTodayString(char *buffer, int size) {
|
||||||
|
time_t rawtime;
|
||||||
|
struct tm * timeinfo;
|
||||||
|
time (&rawtime);
|
||||||
|
timeinfo = localtime (&rawtime);
|
||||||
|
return strftime (buffer,size,"%a %h %d.",timeinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void broadcast_sprinklerdstate(struct mg_connection *nc)
|
void broadcast_sprinklerdstate(struct mg_connection *nc)
|
||||||
|
@ -332,6 +342,8 @@ void broadcast_sprinklerdstate(struct mg_connection *nc)
|
||||||
static char mqtt_topic[250];
|
static char mqtt_topic[250];
|
||||||
static char mqtt_msg[50];
|
static char mqtt_msg[50];
|
||||||
static char last_state_msg[50];
|
static char last_state_msg[50];
|
||||||
|
static int publishedTodayRainChance = -1;
|
||||||
|
static float publishedTodayRainTotal = -1;
|
||||||
|
|
||||||
for (c = mg_next(nc->mgr, NULL); c != NULL; c = mg_next(nc->mgr, c)) {
|
for (c = mg_next(nc->mgr, NULL); c != NULL; c = mg_next(nc->mgr, c)) {
|
||||||
// Start from 0 since we publish master valve (just a temp measure)
|
// Start from 0 since we publish master valve (just a temp measure)
|
||||||
|
@ -358,6 +370,30 @@ void broadcast_sprinklerdstate(struct mg_connection *nc)
|
||||||
sprintf(mqtt_topic, "%s/status", _sdconfig_.mqtt_topic);
|
sprintf(mqtt_topic, "%s/status", _sdconfig_.mqtt_topic);
|
||||||
sprinklerdstatus(mqtt_msg, 50);
|
sprinklerdstatus(mqtt_msg, 50);
|
||||||
send_mqtt_msg(c, mqtt_topic, mqtt_msg);
|
send_mqtt_msg(c, mqtt_topic, mqtt_msg);
|
||||||
|
if (publishedTodayRainChance != _sdconfig_.todayRainChance || isEventRainProbability) {
|
||||||
|
sprintf(mqtt_topic, "%s/chanceofrain", _sdconfig_.mqtt_topic);
|
||||||
|
sprintf(mqtt_msg, "%d",_sdconfig_.todayRainChance);
|
||||||
|
send_mqtt_msg(c, mqtt_topic, mqtt_msg);
|
||||||
|
publishedTodayRainChance = _sdconfig_.todayRainChance;
|
||||||
|
|
||||||
|
getTodayString(mqtt_msg, 50);
|
||||||
|
sprintf(mqtt_topic, "%s/chanceofrain/day", _sdconfig_.mqtt_topic);
|
||||||
|
send_mqtt_msg(c, mqtt_topic, mqtt_msg);
|
||||||
|
|
||||||
|
clearEventRainProbability;
|
||||||
|
}
|
||||||
|
if (publishedTodayRainTotal != _sdconfig_.todayRainTotal || isEventRainTotal) {
|
||||||
|
sprintf(mqtt_topic, "%s/raintotal", _sdconfig_.mqtt_topic);
|
||||||
|
sprintf(mqtt_msg, "%.2f",_sdconfig_.todayRainTotal);
|
||||||
|
send_mqtt_msg(c, mqtt_topic, mqtt_msg);
|
||||||
|
publishedTodayRainTotal = _sdconfig_.todayRainTotal;
|
||||||
|
|
||||||
|
getTodayString(mqtt_msg, 50);
|
||||||
|
sprintf(mqtt_topic, "%s/raintotal/day", _sdconfig_.mqtt_topic);
|
||||||
|
send_mqtt_msg(c, mqtt_topic, mqtt_msg);
|
||||||
|
|
||||||
|
clearEventRainTotal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (_sdconfig_.enableMQTTdz == true) {
|
if (_sdconfig_.enableMQTTdz == true) {
|
||||||
if (_sdconfig_.dzidx_calendar > 0 && update_dz_cache(_sdconfig_.dzidx_calendar,(_sdconfig_.calendar==true ? DZ_ON : DZ_OFF) )) {
|
if (_sdconfig_.dzidx_calendar > 0 && update_dz_cache(_sdconfig_.dzidx_calendar,(_sdconfig_.calendar==true ? DZ_ON : DZ_OFF) )) {
|
||||||
|
@ -383,6 +419,9 @@ void broadcast_sprinklerdstate(struct mg_connection *nc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearEventStatus;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,7 +441,8 @@ bool is_value_flip(char *buf) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int serve_web_request(struct mg_connection *nc, struct http_message *http_msg, char *buffer, int size, bool *changedOption) {
|
//int serve_web_request(struct mg_connection *nc, struct http_message *http_msg, char *buffer, int size, bool *changedOption) {
|
||||||
|
int serve_web_request(struct mg_connection *nc, struct http_message *http_msg, char *buffer, int size) {
|
||||||
static int buflen = 50;
|
static int buflen = 50;
|
||||||
char buf[buflen];
|
char buf[buflen];
|
||||||
//int action = -1;
|
//int action = -1;
|
||||||
|
@ -475,7 +515,8 @@ int serve_web_request(struct mg_connection *nc, struct http_message *http_msg, c
|
||||||
logMessage(LOG_WARNING, "Bad request unknown option\n");
|
logMessage(LOG_WARNING, "Bad request unknown option\n");
|
||||||
length = sprintf(buffer, "{ \"error\": \"Bad request unknown option\" }");
|
length = sprintf(buffer, "{ \"error\": \"Bad request unknown option\" }");
|
||||||
}
|
}
|
||||||
*changedOption = true;
|
//*changedOption = true;
|
||||||
|
setEventStatus;
|
||||||
//broadcast_sprinklerdstate(nc);
|
//broadcast_sprinklerdstate(nc);
|
||||||
} else if (strncasecmp(buf, "config", 6) == 0) {
|
} else if (strncasecmp(buf, "config", 6) == 0) {
|
||||||
mg_get_http_var(&http_msg->query_string, "option", buf, buflen);
|
mg_get_http_var(&http_msg->query_string, "option", buf, buflen);
|
||||||
|
@ -499,9 +540,11 @@ int serve_web_request(struct mg_connection *nc, struct http_message *http_msg, c
|
||||||
mg_get_http_var(&http_msg->query_string, "sensor", buf, buflen);
|
mg_get_http_var(&http_msg->query_string, "sensor", buf, buflen);
|
||||||
if (strncasecmp(buf, "chanceofrain", 13) == 0) {
|
if (strncasecmp(buf, "chanceofrain", 13) == 0) {
|
||||||
mg_get_http_var(&http_msg->query_string, "value", buf, buflen);
|
mg_get_http_var(&http_msg->query_string, "value", buf, buflen);
|
||||||
|
logMessage(LOG_NOTICE, "API: Chance of rain %d%%\n",atoi(buf));
|
||||||
setTodayChanceOfRain(atoi(buf));
|
setTodayChanceOfRain(atoi(buf));
|
||||||
} else if (strncasecmp(buf, "raintotal", 9) == 0) {
|
} else if (strncasecmp(buf, "raintotal", 9) == 0) {
|
||||||
mg_get_http_var(&http_msg->query_string, "value", buf, buflen);
|
mg_get_http_var(&http_msg->query_string, "value", buf, buflen);
|
||||||
|
logMessage(LOG_NOTICE, "API: Rain total %.2f\n",atof(buf));
|
||||||
setTodayRainTotal(atof(buf));
|
setTodayRainTotal(atof(buf));
|
||||||
}
|
}
|
||||||
length = build_sprinkler_JSON(buffer, size);
|
length = build_sprinkler_JSON(buffer, size);
|
||||||
|
@ -519,13 +562,16 @@ int serve_web_request(struct mg_connection *nc, struct http_message *http_msg, c
|
||||||
//if ( (strncasecmp(buf, "off", 3) == 0 || strncmp(buf, "0", 1) == 0) && zone <= _sdconfig_.zones) {
|
//if ( (strncasecmp(buf, "off", 3) == 0 || strncmp(buf, "0", 1) == 0) && zone <= _sdconfig_.zones) {
|
||||||
if (is_value_ON(buf) == true && zone <= _sdconfig_.zones)
|
if (is_value_ON(buf) == true && zone <= _sdconfig_.zones)
|
||||||
{
|
{
|
||||||
|
logMessage(LOG_NOTICE, "API: Turn zone %d on for %d mins\n",zone,runtime);
|
||||||
zc_zone(type, zone, zcON, runtime);
|
zc_zone(type, zone, zcON, runtime);
|
||||||
length = build_sprinkler_JSON(buffer, size);
|
length = build_sprinkler_JSON(buffer, size);
|
||||||
//} else if ( (strncasecmp(buf, "on", 2) == 0 || strncmp(buf, "1", 1) == 0) && zone <= _sdconfig_.zones) {
|
//} else if ( (strncasecmp(buf, "on", 2) == 0 || strncmp(buf, "1", 1) == 0) && zone <= _sdconfig_.zones) {
|
||||||
} else if ( is_value_ON(buf) == false && zone <= _sdconfig_.zones) {
|
} else if ( is_value_ON(buf) == false && zone <= _sdconfig_.zones) {
|
||||||
|
logMessage(LOG_NOTICE, "API: Turn zone %d off\n",zone);
|
||||||
zc_zone(type, zone, zcOFF, runtime);
|
zc_zone(type, zone, zcOFF, runtime);
|
||||||
length = build_sprinkler_JSON(buffer, size);
|
length = build_sprinkler_JSON(buffer, size);
|
||||||
} else if ( is_value_flip(buf) == true && zone <= _sdconfig_.zones) {
|
} else if ( is_value_flip(buf) == true && zone <= _sdconfig_.zones) {
|
||||||
|
logMessage(LOG_NOTICE, "API: Turn zone %d %s\n",zone, !zc_state(zone)==zcON?"ON":"OFF");
|
||||||
zc_zone(type, zone, !zc_state(zone), runtime);
|
zc_zone(type, zone, !zc_state(zone), runtime);
|
||||||
} else {
|
} else {
|
||||||
if (zone > _sdconfig_.zones) {
|
if (zone > _sdconfig_.zones) {
|
||||||
|
@ -535,6 +581,8 @@ int serve_web_request(struct mg_connection *nc, struct http_message *http_msg, c
|
||||||
logMessage(LOG_WARNING, "Bad request on zone %d, unknown state %s\n",zone, buf);
|
logMessage(LOG_WARNING, "Bad request on zone %d, unknown state %s\n",zone, buf);
|
||||||
length = sprintf(buffer, "{ \"error\": \"Bad request on zone %d, unknown state %s\"}", zone, buf);
|
length = sprintf(buffer, "{ \"error\": \"Bad request on zone %d, unknown state %s\"}", zone, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setEventZones;
|
||||||
}
|
}
|
||||||
} else if (strcmp(buf, "zrtcfg") == 0) {
|
} else if (strcmp(buf, "zrtcfg") == 0) {
|
||||||
//logMessage(LOG_DEBUG, "WEB REQUEST cfg %s\n",buf);
|
//logMessage(LOG_DEBUG, "WEB REQUEST cfg %s\n",buf);
|
||||||
|
@ -547,7 +595,8 @@ int serve_web_request(struct mg_connection *nc, struct http_message *http_msg, c
|
||||||
logMessage(LOG_DEBUG, "changed default runtime on zone %d, to %d\n",zone, runtime);
|
logMessage(LOG_DEBUG, "changed default runtime on zone %d, to %d\n",zone, runtime);
|
||||||
length = build_sprinkler_JSON(buffer, size);
|
length = build_sprinkler_JSON(buffer, size);
|
||||||
zc_update_runtime(zone);
|
zc_update_runtime(zone);
|
||||||
*changedOption = true;
|
//*changedOption = true;
|
||||||
|
setEventZones;
|
||||||
} else
|
} else
|
||||||
length += sprintf(buffer, "{ \"error\": \"bad request zone %d runtime %d\"}",zone,runtime);
|
length += sprintf(buffer, "{ \"error\": \"bad request zone %d runtime %d\"}",zone,runtime);
|
||||||
} else if (strcmp(buf, "calcfg") == 0) {
|
} else if (strcmp(buf, "calcfg") == 0) {
|
||||||
|
@ -591,13 +640,14 @@ void action_web_request(struct mg_connection *nc, struct http_message *http_msg)
|
||||||
char buf[bufsize];
|
char buf[bufsize];
|
||||||
char *c_type;
|
char *c_type;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
bool changedOption = false;
|
//bool changedOption = false;
|
||||||
|
|
||||||
logMessage(LOG_DEBUG, "action_web_request %.*s %.*s\n",http_msg->uri.len, http_msg->uri.p, http_msg->query_string.len, http_msg->query_string.p);
|
logMessage(LOG_DEBUG, "action_web_request %.*s %.*s\n",http_msg->uri.len, http_msg->uri.p, http_msg->query_string.len, http_msg->query_string.p);
|
||||||
|
|
||||||
if (http_msg->query_string.len > 0) {
|
if (http_msg->query_string.len > 0) {
|
||||||
//size = serve_web_request(nc, http_msg, buf, sizeof(buf));
|
//size = serve_web_request(nc, http_msg, buf, sizeof(buf));
|
||||||
size = serve_web_request(nc, http_msg, buf, bufsize, &changedOption);
|
//size = serve_web_request(nc, http_msg, buf, bufsize, &changedOption);
|
||||||
|
size = serve_web_request(nc, http_msg, buf, bufsize);
|
||||||
c_type = CT_JSON;
|
c_type = CT_JSON;
|
||||||
|
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
|
@ -608,9 +658,8 @@ void action_web_request(struct mg_connection *nc, struct http_message *http_msg)
|
||||||
mg_send(nc, buf, size);
|
mg_send(nc, buf, size);
|
||||||
//logMessage (LOG_DEBUG, "Web Return %d = '%.*s'\n",size, size, buf);
|
//logMessage (LOG_DEBUG, "Web Return %d = '%.*s'\n",size, size, buf);
|
||||||
|
|
||||||
if (changedOption)
|
//if (changedOption)
|
||||||
_sdconfig_.eventToUpdateHappened = true;
|
// _sdconfig_.eventToUpdateHappened = true;
|
||||||
//broadcast_sprinklerdstate(nc);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -730,7 +779,8 @@ void action_mqtt_message(struct mg_connection *nc, struct mg_mqtt_message *msg){
|
||||||
if (zone > 0 && zone <= _sdconfig_.zones) {
|
if (zone > 0 && zone <= _sdconfig_.zones) {
|
||||||
int v = str2int(msg->payload.p, msg->payload.len);
|
int v = str2int(msg->payload.p, msg->payload.len);
|
||||||
_sdconfig_.zonecfg[zone].default_runtime = v / 60;
|
_sdconfig_.zonecfg[zone].default_runtime = v / 60;
|
||||||
_sdconfig_.eventToUpdateHappened = true;
|
//_sdconfig_.eventToUpdateHappened = true;
|
||||||
|
//setEventZones;
|
||||||
zc_update_runtime(zone);
|
zc_update_runtime(zone);
|
||||||
logMessage(LOG_DEBUG, "MQTT: Default runtime zone %d is %d\n",zone,_sdconfig_.zonecfg[zone].default_runtime);
|
logMessage(LOG_DEBUG, "MQTT: Default runtime zone %d is %d\n",zone,_sdconfig_.zonecfg[zone].default_runtime);
|
||||||
} else {
|
} else {
|
||||||
|
@ -738,39 +788,42 @@ void action_mqtt_message(struct mg_connection *nc, struct mg_mqtt_message *msg){
|
||||||
}
|
}
|
||||||
} else if (pt2 != NULL && pt3 != NULL && strncmp(pt2, "24hdelay", 8) == 0 && strncmp(pt3, "set", 3) == 0 ) {
|
} else if (pt2 != NULL && pt3 != NULL && strncmp(pt2, "24hdelay", 8) == 0 && strncmp(pt3, "set", 3) == 0 ) {
|
||||||
enable_delay24h(status==zcON?true:false);
|
enable_delay24h(status==zcON?true:false);
|
||||||
logMessage(LOG_DEBUG, "MQTT: Enable 24 hour delay %s\n",status==zcON?"YES":"NO");
|
logMessage(LOG_NOTICE, "MQTT: Enable 24 hour delay %s\n",status==zcON?"YES":"NO");
|
||||||
} else if (pt2 != NULL && pt3 != NULL && strncmp(pt2, "calendar", 6) == 0 && strncmp(pt3, "set", 3) == 0 ) {
|
} else if (pt2 != NULL && pt3 != NULL && strncmp(pt2, "calendar", 6) == 0 && strncmp(pt3, "set", 3) == 0 ) {
|
||||||
//_sdconfig_.system=status==zcON?true:false;
|
//_sdconfig_.system=status==zcON?true:false;
|
||||||
logMessage(LOG_NOTICE, "MQTT request to turn Calendar %s\n",status==zcON?"On":"Off");
|
logMessage(LOG_DEBUG, "MQTT request to turn Calendar %s\n",status==zcON?"On":"Off");
|
||||||
enable_calendar(status==zcON?true:false);
|
enable_calendar(status==zcON?true:false);
|
||||||
logMessage(LOG_DEBUG, "MQTT: Turning calendar %s\n",status==zcON?"ON":"OFF");
|
logMessage(LOG_NOTICE, "MQTT: Turning calendar %s\n",status==zcON?"ON":"OFF");
|
||||||
} else if (pt2 != NULL && pt3 != NULL && strncmp(pt2, "cycleallzones", 13) == 0 && strncmp(pt3, "set", 3) == 0 ) {
|
} else if (pt2 != NULL && pt3 != NULL && strncmp(pt2, "cycleallzones", 13) == 0 && strncmp(pt3, "set", 3) == 0 ) {
|
||||||
zc_zone(zcALL, 0, status, 0);
|
zc_zone(zcALL, 0, status, 0);
|
||||||
logMessage(LOG_DEBUG, "MQTT: Cycle all zones %s\n",status==zcON?"ON":"OFF");
|
logMessage(LOG_NOTICE, "MQTT: Cycle all zones %s\n",status==zcON?"ON":"OFF");
|
||||||
} else if (pt2 != NULL && pt3 != NULL && strncmp(pt2, "raintotal", 9) == 0 && strncmp(pt3, "set", 3) == 0 ) {
|
} else if (pt2 != NULL && pt3 != NULL && strncmp(pt2, "raintotal", 9) == 0 && strncmp(pt3, "set", 3) == 0 ) {
|
||||||
float v = str2float(msg->payload.p, msg->payload.len);
|
float v = str2float(msg->payload.p, msg->payload.len);
|
||||||
logMessage(LOG_DEBUG, "MQTT: Rain total %.2f\n",v);
|
logMessage(LOG_NOTICE, "MQTT: Rain total %.2f\n",v);
|
||||||
setTodayRainTotal(v);
|
setTodayRainTotal(v);
|
||||||
} else if (pt2 != NULL && pt3 != NULL && strncmp(pt2, "chanceofrain", 12) == 0 && strncmp(pt3, "set", 3) == 0 ) {
|
} else if (pt2 != NULL && pt3 != NULL && strncmp(pt2, "chanceofrain", 12) == 0 && strncmp(pt3, "set", 3) == 0 ) {
|
||||||
int v = str2int(msg->payload.p, msg->payload.len);
|
int v = str2int(msg->payload.p, msg->payload.len);
|
||||||
logMessage(LOG_DEBUG, "MQTT: Chance of rain %d%%\n",v);
|
logMessage(LOG_NOTICE, "MQTT: Chance of rain %d%%\n",v);
|
||||||
setTodayChanceOfRain(v);
|
setTodayChanceOfRain(v);
|
||||||
} else if (pt2 != NULL && pt3 != NULL && strncmp(pt2, "zone", 4) == 0 && strncmp(pt3, "set", 3) == 0 ) {
|
} else if (pt2 != NULL && pt3 != NULL && strncmp(pt2, "zone", 4) == 0 && strncmp(pt3, "set", 3) == 0 ) {
|
||||||
int zone = atoi(&pt2[4]);
|
int zone = atoi(&pt2[4]);
|
||||||
if (zone > 0 && zone <= _sdconfig_.zones) {
|
if (zone > 0 && zone <= _sdconfig_.zones) {
|
||||||
|
logMessage(LOG_NOTICE, "MQTT: Turn zone %d %s\n",zone, status==zcON?"ON":"OFF");
|
||||||
zc_zone(zcSINGLE, zone, status, 0);
|
zc_zone(zcSINGLE, zone, status, 0);
|
||||||
logMessage(LOG_DEBUG, "MQTT: Turn zone %d %s\n",zone, status==zcON?"ON":"OFF");
|
|
||||||
} else if (zone == 0 && status == zcOFF && _sdconfig_.currentZone.type != zcNONE) {
|
} else if (zone == 0 && status == zcOFF && _sdconfig_.currentZone.type != zcNONE) {
|
||||||
// request to turn off master will turn off any running zone
|
// request to turn off master will turn off any running zone
|
||||||
zc_zone(zcSINGLE, _sdconfig_.currentZone.zone , zcOFF, 0);
|
|
||||||
logMessage(LOG_DEBUG, "MQTT: Request master valve off, turned zone %d off\n",_sdconfig_.currentZone.zone);
|
logMessage(LOG_DEBUG, "MQTT: Request master valve off, turned zone %d off\n",_sdconfig_.currentZone.zone);
|
||||||
|
zc_zone(zcSINGLE, _sdconfig_.currentZone.zone , zcOFF, 0);
|
||||||
} else if (zone == 0 && status == zcON) {
|
} else if (zone == 0 && status == zcON) {
|
||||||
// Can't turn on master valve, just re-send current stats.
|
// Can't turn on master valve, just re-send current stats.
|
||||||
_sdconfig_.eventToUpdateHappened = true;
|
//_sdconfig_.eventToUpdateHappened = true;
|
||||||
|
setEventZones;
|
||||||
|
setEventStatus;
|
||||||
} else {
|
} else {
|
||||||
logMessage(LOG_WARNING, "MQTT: unknown zone %d\n",zone);
|
logMessage(LOG_WARNING, "MQTT: unknown zone %d\n",zone);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// No set. nothing for us to do.
|
||||||
logMessage(LOG_DEBUG, "MQTT: Unknown topic %.*s %.*s\n",msg->topic.len, msg->topic.p, msg->payload.len, msg->payload.p);
|
logMessage(LOG_DEBUG, "MQTT: Unknown topic %.*s %.*s\n",msg->topic.len, msg->topic.p, msg->payload.len, msg->payload.p);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -1,164 +0,0 @@
|
||||||
[SPRINKLERD]
|
|
||||||
PORT=80
|
|
||||||
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 = 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
|
|
||||||
|
|
||||||
DZIDX_CALENDAR = 2197
|
|
||||||
DZIDX_24HDELAY = 2198
|
|
||||||
DZIDX_ALL_ZONES = 2199
|
|
||||||
DZIDX_RAINSENSOR = 2248
|
|
||||||
|
|
||||||
# Options for the below ZONE and GPIO configuration
|
|
||||||
#
|
|
||||||
# LOW 0
|
|
||||||
# HIGH 1
|
|
||||||
#
|
|
||||||
# PUD_OFF 0
|
|
||||||
# PUD_DOWN 1
|
|
||||||
# PUD_UP 2
|
|
||||||
|
|
||||||
#NAME = name of zone
|
|
||||||
#GPIO_PIN = GPIO # This is the GPIO# not the pin#, so (17 = GPIO17 = Pin 11) or another example (5 = GPIO5 = Pin 29)
|
|
||||||
#WPI_PIN = use instead of GPIO_PIN if compiled with USE_WIRINGPI flag, This is WiringPi Pin#, not Raspberry Pi board pin#
|
|
||||||
#GPIO_PULL_UPDN = setup pull up pull down resistor PUD_OFF|PUD_DOWN|PUD_UP
|
|
||||||
#GPIO_ON_STATE = State GPIO reads when relay for zone is on. HIGH or LOW 1 or 0
|
|
||||||
#DOMOTICZ_IDX = Domoticz IDX 0 or remove entry if you don;t use Domoticz (only if you use domoticz)
|
|
||||||
|
|
||||||
# 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=2
|
|
||||||
#WPI_PIN=0
|
|
||||||
GPIO_PULL_UPDN=1
|
|
||||||
GPIO_ON_STATE=0
|
|
||||||
|
|
||||||
[ZONE:1]
|
|
||||||
NAME=Island
|
|
||||||
DEFAULT_RUNTIME=10
|
|
||||||
#GPIO_PIN=18
|
|
||||||
GPIO_PIN=3
|
|
||||||
#WPI_PIN=1
|
|
||||||
GPIO_PULL_UPDN=1
|
|
||||||
GPIO_ON_STATE=0
|
|
||||||
DOMOTICZ_IDX=2000
|
|
||||||
|
|
||||||
[ZONE:2]
|
|
||||||
NAME=Driveway
|
|
||||||
DEFAULT_RUNTIME=10
|
|
||||||
GPIO_PIN=27
|
|
||||||
#GPIO_PIN=40
|
|
||||||
#WPI_PIN=2
|
|
||||||
GPIO_PULL_UPDN=1
|
|
||||||
GPIO_ON_STATE=0
|
|
||||||
DOMOTICZ_IDX=2010
|
|
||||||
|
|
||||||
[ZONE:3]
|
|
||||||
NAME=Diningroom Flowerbeds
|
|
||||||
DEFAULT_RUNTIME=10
|
|
||||||
GPIO_PIN=5
|
|
||||||
#WPI_PIN=3
|
|
||||||
GPIO_PULL_UPDN=1
|
|
||||||
GPIO_ON_STATE=0
|
|
||||||
DOMOTICZ_IDX=2020
|
|
||||||
|
|
||||||
#[INPUT]
|
|
||||||
#[INPUT:1]
|
|
||||||
#NAME=Test Switch
|
|
||||||
#GPIO_PIN=6
|
|
||||||
#WPI_PIN=3
|
|
||||||
#GPIO_PULL_UPDN=1
|
|
||||||
#GPIO_ON_STATE=0
|
|
||||||
#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
|
|
||||||
#DEFAULT_RUNTIME=10
|
|
||||||
#GPIO_PIN=23
|
|
||||||
#WPI_PIN=4
|
|
||||||
#GPIO_PULL_UPDN=1
|
|
||||||
#GPIO_ON_STATE=0
|
|
||||||
#DOMOTICZ_IDX=203
|
|
||||||
|
|
||||||
#[ZONE:5]
|
|
||||||
#NAME=Backgarden Left
|
|
||||||
#DEFAULT_RUNTIME=10
|
|
||||||
#GPIO_PIN=24
|
|
||||||
#WPI_PIN=5
|
|
||||||
#GPIO_PULL_UPDN=1
|
|
||||||
#GPIO_ON_STATE=0
|
|
||||||
#DOMOTICZ_IDX=204
|
|
||||||
|
|
||||||
#[ZONE:6]
|
|
||||||
#NAME=Backgarden Right
|
|
||||||
#DEFAULT_RUNTIME=10
|
|
||||||
#GPIO_PIN=25
|
|
||||||
#WPI_PIN=6
|
|
||||||
#GPIO_PULL_UPDN=1
|
|
||||||
#GPIO_ON_STATE=0
|
|
||||||
#DOMOTICZ_IDX=205
|
|
||||||
|
|
||||||
#[ZONE:7]
|
|
||||||
#NAME=Garage Flowerbeds
|
|
||||||
#DEFAULT_RUNTIME=10
|
|
||||||
#GPIO_PIN=5
|
|
||||||
#WPI_PIN=21
|
|
||||||
#GPIO_PULL_UPDN=1
|
|
||||||
#GPIO_ON_STATE=0
|
|
||||||
#DOMOTICZ_IDX=206
|
|
||||||
|
|
||||||
#[ZONE:8]
|
|
||||||
#NAME=Golfcart path
|
|
||||||
#DEFAULT_RUNTIME=10
|
|
||||||
#GPIO_PIN=6
|
|
||||||
#WPI_PIN=22
|
|
||||||
#GPIO_PULL_UPDN=1
|
|
||||||
#GPIO_ON_STATE=0
|
|
||||||
#DOMOTICZ_IDX=207
|
|
||||||
|
|
||||||
#
|
|
||||||
# This is for future support of sensors, not implimented yet
|
|
||||||
#
|
|
||||||
#PIN
|
|
||||||
#NAME name
|
|
||||||
#PIN_MODE Setup as input or output
|
|
||||||
#PULL_UPDN setup pull up pull down resistor NONE|PUD_OFF|PUD_DOWN|PUD_UP
|
|
||||||
#TRIGGER_EVENT_ON trigger_event on NONE|INT_EDGE_SETUP|INT_EDGE_FALLING|INT_EDGE_RISING|INT_EDGE_BOTH
|
|
||||||
#TRIGGER_EVENT_STATE trigger_event_received_state LOW|HIGH|BOTH
|
|
||||||
#COMMAND triggered_event_runcmd = external command to run
|
|
||||||
#DOMOTICZ_IDX Domoticz IDX
|
|
||||||
|
|
||||||
#[GPIO]
|
|
||||||
#[GPIO:1]
|
|
||||||
#NAME=Rain Sensor
|
|
||||||
#GPIO_PIN=4
|
|
||||||
#WPI_PIN=7
|
|
||||||
#PIN_MODE=0
|
|
||||||
#PULL_UPDN=0
|
|
||||||
#TRIGGER_EVENT_ON=3
|
|
||||||
#COMMAND_HIGH=/usr/bin/curl -s -o /dev/null 'http://localhost?type=option&option=24hdelay&state=on'
|
|
||||||
#COMMAND_LOW=/usr/bin/curl -s -o /dev/null 'http://localhost?type=option&option=24hdelay&state=off'
|
|
41
sd_cron.c
41
sd_cron.c
|
@ -15,10 +15,14 @@ bool setTodayChanceOfRain(int percent)
|
||||||
{
|
{
|
||||||
logMessage(LOG_DEBUG, "Set today's chance of rain = %d\n",percent);
|
logMessage(LOG_DEBUG, "Set today's chance of rain = %d\n",percent);
|
||||||
if (percent <= 100 && percent >= 0) {
|
if (percent <= 100 && percent >= 0) {
|
||||||
|
//_sdconfig_.eventToUpdateHappened = true;
|
||||||
|
setEventRainProbability;
|
||||||
_sdconfig_.todayRainChance = percent;
|
_sdconfig_.todayRainChance = percent;
|
||||||
if (_sdconfig_.precipChanceDelay > 0 && _sdconfig_.todayRainChance >= _sdconfig_.precipChanceDelay) {
|
if (_sdconfig_.precipChanceDelay > 0 && _sdconfig_.todayRainChance >= _sdconfig_.precipChanceDelay) {
|
||||||
//enable_delay24h(true);
|
//enable_delay24h(true);
|
||||||
reset_delay24h_time(0); // will add 24hours or reset
|
reset_delay24h_time(0); // will add 24hours or turn on and set delay to 24hours
|
||||||
|
} else {
|
||||||
|
enable_delay24h(false); // Turn off rain delay
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -28,10 +32,12 @@ bool setTodayChanceOfRain(int percent)
|
||||||
|
|
||||||
bool setTodayRainTotal(float rain)
|
bool setTodayRainTotal(float rain)
|
||||||
{
|
{
|
||||||
if (_sdconfig_.todayRainTotal == rain)
|
if (_sdconfig_.todayRainTotal == rain && rain != 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
_sdconfig_.todayRainTotal = rain;
|
_sdconfig_.todayRainTotal = rain;
|
||||||
|
//_sdconfig_.eventToUpdateHappened = true;
|
||||||
|
setEventRainTotal;
|
||||||
|
|
||||||
logMessage(LOG_DEBUG, "Today's rain total = %f\n",_sdconfig_.todayRainTotal);
|
logMessage(LOG_DEBUG, "Today's rain total = %f\n",_sdconfig_.todayRainTotal);
|
||||||
|
|
||||||
|
@ -64,7 +70,8 @@ bool check_delay24h()
|
||||||
void enable_calendar(bool state)
|
void enable_calendar(bool state)
|
||||||
{
|
{
|
||||||
if (_sdconfig_.calendar != state) {
|
if (_sdconfig_.calendar != state) {
|
||||||
_sdconfig_.eventToUpdateHappened = true;
|
//_sdconfig_.eventToUpdateHappened = true;
|
||||||
|
setEventStatus;
|
||||||
_sdconfig_.calendar = state;
|
_sdconfig_.calendar = state;
|
||||||
logMessage(LOG_NOTICE, "Turning %s calendar\n",state==true?"on":"off");
|
logMessage(LOG_NOTICE, "Turning %s calendar\n",state==true?"on":"off");
|
||||||
} else {
|
} else {
|
||||||
|
@ -75,7 +82,8 @@ void enable_calendar(bool state)
|
||||||
void enable_delay24h(bool state)
|
void enable_delay24h(bool state)
|
||||||
{
|
{
|
||||||
if (_sdconfig_.delay24h != state) {
|
if (_sdconfig_.delay24h != state) {
|
||||||
_sdconfig_.eventToUpdateHappened = true;
|
//_sdconfig_.eventToUpdateHappened = true;
|
||||||
|
setEventStatus;
|
||||||
|
|
||||||
_sdconfig_.delay24h = state;
|
_sdconfig_.delay24h = state;
|
||||||
if (state) {
|
if (state) {
|
||||||
|
@ -96,7 +104,8 @@ void enable_delay24h(bool state)
|
||||||
void reset_delay24h_time(unsigned long dtime)
|
void reset_delay24h_time(unsigned long dtime)
|
||||||
{
|
{
|
||||||
if (_sdconfig_.delay24h != true) {
|
if (_sdconfig_.delay24h != true) {
|
||||||
_sdconfig_.eventToUpdateHappened = true;
|
//_sdconfig_.eventToUpdateHappened = true;
|
||||||
|
setEventStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t now;
|
time_t now;
|
||||||
|
@ -136,6 +145,7 @@ void write_cron() {
|
||||||
int hour;
|
int hour;
|
||||||
int day;
|
int day;
|
||||||
int zone;
|
int zone;
|
||||||
|
int rb4i;
|
||||||
|
|
||||||
bool fs = remount_root_ro(false);
|
bool fs = remount_root_ro(false);
|
||||||
|
|
||||||
|
@ -170,7 +180,26 @@ void write_cron() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (rb4i=0; rb4i<_sdconfig_.runBeforeCmds; rb4i++) {
|
||||||
|
if (_sdconfig_.cron[day].minute < _sdconfig_.runBeforeCmd[rb4i].mins) {
|
||||||
|
fprintf(fp, "%d %d * * %d root %s\n",
|
||||||
|
(60 - (_sdconfig_.runBeforeCmd[rb4i].mins - _sdconfig_.cron[day].minute)),
|
||||||
|
(_sdconfig_.cron[day].hour - 1),
|
||||||
|
day,
|
||||||
|
_sdconfig_.runBeforeCmd[rb4i].command);
|
||||||
|
} else {
|
||||||
|
fprintf(fp, "%d %d * * %d root %s\n",
|
||||||
|
(_sdconfig_.cron[day].minute - _sdconfig_.runBeforeCmd[rb4i].mins),
|
||||||
|
_sdconfig_.cron[day].hour,
|
||||||
|
day,
|
||||||
|
_sdconfig_.runBeforeCmd[rb4i].command);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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=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, "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");
|
fprintf(fp, "#***** AUTO GENERATED DO NOT EDIT *****\n");
|
||||||
|
@ -205,7 +234,7 @@ void read_cron() {
|
||||||
for (day=0; day <= 6; day++) {
|
for (day=0; day <= 6; day++) {
|
||||||
_sdconfig_.cron[day].hour = -1;
|
_sdconfig_.cron[day].hour = -1;
|
||||||
_sdconfig_.cron[day].minute = -1;
|
_sdconfig_.cron[day].minute = -1;
|
||||||
for (zone=1; zone < _sdconfig_.zones; zone ++) {
|
for (zone=0; zone < _sdconfig_.zones; zone ++) {
|
||||||
_sdconfig_.cron[day].zruntimes[zone] = 0;
|
_sdconfig_.cron[day].zruntimes[zone] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,7 +148,8 @@ int main (int argc, char *argv[])
|
||||||
_sdconfig_.calendar = true;
|
_sdconfig_.calendar = true;
|
||||||
_sdconfig_.currentZone.type = zcNONE;
|
_sdconfig_.currentZone.type = zcNONE;
|
||||||
_sdconfig_.cron_update = 0;
|
_sdconfig_.cron_update = 0;
|
||||||
_sdconfig_.eventToUpdateHappened = false;
|
//_sdconfig_.eventToUpdateHappened = false;
|
||||||
|
_sdconfig_.updateEventMask = 0;
|
||||||
read_cron();
|
read_cron();
|
||||||
read_cache();
|
read_cache();
|
||||||
|
|
||||||
|
@ -303,10 +304,10 @@ void main_loop ()
|
||||||
{
|
{
|
||||||
//logMessage (LOG_DEBUG, "mg_mgr_poll\n");
|
//logMessage (LOG_DEBUG, "mg_mgr_poll\n");
|
||||||
mg_mgr_poll(&_mgr, 500);
|
mg_mgr_poll(&_mgr, 500);
|
||||||
|
//logMessage (LOG_DEBUG, "updateEventMask=%d\n",_sdconfig_.updateEventMask);
|
||||||
check_cron();
|
check_cron();
|
||||||
if (zc_check() == true || check_delay24h() == true || _sdconfig_.eventToUpdateHappened) {
|
if (zc_check() == true || check_delay24h() == true || _sdconfig_.updateEventMask != 0) {
|
||||||
_sdconfig_.eventToUpdateHappened = false;
|
//_sdconfig_.eventToUpdateHappened = false;
|
||||||
broadcast_sprinklerdstate(_mgr.active_connections);
|
broadcast_sprinklerdstate(_mgr.active_connections);
|
||||||
broadcast_sprinklerdactivestate(_mgr.active_connections);
|
broadcast_sprinklerdactivestate(_mgr.active_connections);
|
||||||
} else if (i > 10 && _sdconfig_.currentZone.type!=zcNONE) {
|
} else if (i > 10 && _sdconfig_.currentZone.type!=zcNONE) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#ifndef SD_VERSION_H
|
#ifndef SD_VERSION_H
|
||||||
#define SD_VERSION_H
|
#define SD_VERSION_H
|
||||||
|
|
||||||
#define SD_VERSION "1.3"
|
#define SD_VERSION "1.4.1"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -42,6 +42,8 @@ int start_next_zone(int startz) {
|
||||||
|
|
||||||
int zone = startz+1;
|
int zone = startz+1;
|
||||||
|
|
||||||
|
setEventZones;
|
||||||
|
|
||||||
while( _sdconfig_.zonecfg[zone].default_runtime <= 0 || !validGPIO( _sdconfig_.zonecfg[zone].pin) ) {
|
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 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#");
|
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#");
|
||||||
|
@ -74,6 +76,7 @@ void zc_update_runtime(int zone) {
|
||||||
if (zone > 0 && zone < _sdconfig_.zones && zone == _sdconfig_.currentZone.zone) {
|
if (zone > 0 && zone < _sdconfig_.zones && zone == _sdconfig_.currentZone.zone) {
|
||||||
_sdconfig_.currentZone.duration=_sdconfig_.zonecfg[zone].default_runtime;
|
_sdconfig_.currentZone.duration=_sdconfig_.zonecfg[zone].default_runtime;
|
||||||
}
|
}
|
||||||
|
setEventZones;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool zc_check() {
|
bool zc_check() {
|
||||||
|
@ -236,7 +239,8 @@ bool zc_start(/*zcRunType type,*/ int zone) {
|
||||||
digitalWrite(_sdconfig_.zonecfg[zone].pin, _sdconfig_.zonecfg[zone].on_state );
|
digitalWrite(_sdconfig_.zonecfg[zone].pin, _sdconfig_.zonecfg[zone].on_state );
|
||||||
int rtn = true;
|
int rtn = true;
|
||||||
#endif
|
#endif
|
||||||
_sdconfig_.eventToUpdateHappened = true;
|
//_sdconfig_.eventToUpdateHappened = true;
|
||||||
|
setEventZones;
|
||||||
|
|
||||||
return rtn;
|
return rtn;
|
||||||
// store what's running
|
// store what's running
|
||||||
|
@ -264,7 +268,8 @@ bool zc_stop(/*zcRunType type,*/ int zone) {
|
||||||
digitalWrite(_sdconfig_.zonecfg[zone].pin, !_sdconfig_.zonecfg[zone].on_state );
|
digitalWrite(_sdconfig_.zonecfg[zone].pin, !_sdconfig_.zonecfg[zone].on_state );
|
||||||
int rtn = true;
|
int rtn = true;
|
||||||
#endif
|
#endif
|
||||||
_sdconfig_.eventToUpdateHappened = true;
|
//_sdconfig_.eventToUpdateHappened = true;
|
||||||
|
setEventZones;
|
||||||
|
|
||||||
return rtn;
|
return rtn;
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue