parent
e93ad44028
commit
cb920a03d3
9
Makefile
9
Makefile
|
@ -49,7 +49,14 @@ GPIO = ./release/gpio
|
|||
# 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)
|
||||
@echo: $(MAIN) have been compiled
|
||||
|
|
29
config.c
29
config.c
|
@ -368,6 +368,7 @@ void readCfg(char *inifile)
|
|||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
_sdconfig_.inputs = 0;
|
||||
// Caculate how many inputs we have
|
||||
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;
|
||||
|
|
31
config.h
31
config.h
|
@ -24,6 +24,11 @@ struct CALENDARday {
|
|||
int minute;
|
||||
int *zruntimes;
|
||||
};
|
||||
|
||||
struct RunB4CalStart {
|
||||
int mins;
|
||||
char command[256];
|
||||
};
|
||||
/*
|
||||
struct GPIOextra {
|
||||
char command_high[COMMAND_SIZE];
|
||||
|
@ -96,8 +101,11 @@ struct sprinklerdcfg {
|
|||
long cron_update;
|
||||
int log_level;
|
||||
struct szRunning currentZone;
|
||||
struct RunB4CalStart *runBeforeCmd;
|
||||
int runBeforeCmds;
|
||||
char cache_file[512];
|
||||
bool eventToUpdateHappened;
|
||||
//bool eventToUpdateHappened;
|
||||
uint8_t updateEventMask;
|
||||
int todayRainChance;
|
||||
float todayRainTotal;
|
||||
};
|
||||
|
@ -127,5 +135,26 @@ void read_cache();
|
|||
#define ON 0
|
||||
#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
|
||||
#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.
|
||||
|
||||
#Can use below to track best api for location
|
||||
#https://www.forecastadvisor.com/
|
||||
|
||||
# API Keys from the following are supported
|
||||
# openweathermap.org weatherapi.com weatherbit.io climacell.co
|
||||
|
||||
|
@ -17,9 +20,12 @@ openweatherAPIkey='-----'
|
|||
weatherbitAPIkey='-----'
|
||||
climacellAPIkey='-----'
|
||||
weatherAPIkey='-----'
|
||||
accuweatherAPI='-----'
|
||||
|
||||
lat='42.3601'
|
||||
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
|
||||
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"
|
||||
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"
|
||||
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
|
||||
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; }
|
||||
echomsg() { if [ -t 1 ]; then echo "$@" 1>&2; fi; }
|
||||
|
||||
|
||||
|
||||
function getURL() {
|
||||
url=$1
|
||||
jq=$2
|
||||
|
@ -66,6 +86,11 @@ function getURL() {
|
|||
probability=$(echo $JSON | jq "$jq" )
|
||||
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 )
|
||||
echo $probability
|
||||
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 bc >/dev/null 2>&1 || { echoerr "bc not installed. Aborting!"; exit 1; }
|
||||
|
||||
pop=-1
|
||||
probArray=()
|
||||
|
||||
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;
|
||||
fi
|
||||
|
||||
for var in "$@"
|
||||
do
|
||||
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)
|
||||
if [ "$openweatherAPIkey" == "-----" ]; then echomsg "missing OpenWeather API key" && continue; fi
|
||||
if probability=$(getURL "$openweatherURL" '.["daily"][0].pop' "100"); then
|
||||
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
|
||||
;;
|
||||
weatherbit)
|
||||
if [ "$weatherbitAPIkey" == "-----" ]; then echomsg "missing WeatherBit API key" && continue; fi
|
||||
if probability=$(getURL "$weatherbitURL" '.data[0].pop' "1"); then
|
||||
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
|
||||
;;
|
||||
climacell)
|
||||
if [ "$climacellAPIkey" == "-----" ]; then echomsg "missing ClimaCell API key" && continue; fi
|
||||
if probability=$(getURL "$climacellURL" '.data.timelines[0].intervals[0].values.precipitationProbability' "1"); then
|
||||
echomsg "ClimaCell probability of rain today is $probability%"
|
||||
pop=$(echo "if($probability>$pop)print $probability else print $pop" | bc -l)
|
||||
probArray+=($probability)
|
||||
fi
|
||||
;;
|
||||
weatherapi)
|
||||
if [ "$weatherAPIkey" == "-----" ]; then echomsg "missing WeatherAPI API key" && continue; fi
|
||||
if probability=$(getURL "$weatherAPIlURL" '.forecast.forecastday[0].day.daily_chance_of_rain' "1"); then
|
||||
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
|
||||
;;
|
||||
esac
|
||||
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
|
||||
echoerr "Error reading Probability, please check!"
|
||||
if [ ${#probArray[@]} -le 0 ]; then
|
||||
echoerr "No rain probability values found"
|
||||
exit 1
|
||||
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"
|
||||
curl -s "$sprinklerdEnableDelay" > /dev/null
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
|
|
49
hassio.c
49
hassio.c
|
@ -10,13 +10,18 @@
|
|||
#include "net_services.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
|
||||
//#define HASS_EXPIRE ""\"expire_after"\": 300,"
|
||||
#define HASS_EXPIRE ""
|
||||
|
||||
#define HASS_DEVICE "\"identifiers\": " \
|
||||
"[\"SprinklerD\"]," \
|
||||
" \"sw_version\": \"" SD_VERSION "\"," \
|
||||
" \"model\": \"Sprinkler Daemon\"," \
|
||||
" \"name\": \"SprinklerD\"," \
|
||||
" \"manufacturer\": \"SprinklerD\"," \
|
||||
" \"suggested_area\": \"pool\""
|
||||
" \"suggested_area\": \"garden\""
|
||||
|
||||
#define HASS_AVAILABILITY "\"payload_available\" : \"1\"," \
|
||||
"\"payload_not_available\" : \"0\"," \
|
||||
|
@ -32,6 +37,18 @@ const char *HASSIO_TEXT_SENSOR_DISCOVER = "{"
|
|||
"\"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 = "{"
|
||||
"\"device\": {" HASS_DEVICE "},"
|
||||
"\"availability\": {" HASS_AVAILABILITY "},"
|
||||
|
@ -41,9 +58,7 @@ const char *HASSIO_SWITCH_DISCOVER = "{"
|
|||
"\"state_topic\": \"%s/%s\","
|
||||
"\"command_topic\": \"%s/%s/set\","
|
||||
"\"payload_on\": \"1\","
|
||||
"\"payload_off\": \"0\","
|
||||
"\"qos\": 1,"
|
||||
"\"retain\": false"
|
||||
"\"payload_off\": \"0\""
|
||||
"}";
|
||||
|
||||
const char *HASSIO_VALVE_DISCOVER = "{"
|
||||
|
@ -57,9 +72,7 @@ const char *HASSIO_VALVE_DISCOVER = "{"
|
|||
"\"command_topic\": \"%s/zone%d/set\"," // 1
|
||||
"\"value_template\": \"{%% set values = { '0':'closed', '1':'open'} %%}{{ values[value] if value in values.keys() else 'closed' }}\","
|
||||
"\"payload_open\": \"1\","
|
||||
"\"payload_close\": \"0\","
|
||||
"\"qos\": 1,"
|
||||
"\"retain\": false"
|
||||
"\"payload_close\": \"0\""
|
||||
"}";
|
||||
|
||||
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);
|
||||
|
||||
|
||||
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++)
|
||||
|
|
3447
mongoose.c
3447
mongoose.c
File diff suppressed because it is too large
Load Diff
553
mongoose.h
553
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_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) {
|
||||
|
@ -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)
|
||||
|
@ -332,6 +342,8 @@ void broadcast_sprinklerdstate(struct mg_connection *nc)
|
|||
static char mqtt_topic[250];
|
||||
static char mqtt_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)) {
|
||||
// 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);
|
||||
sprinklerdstatus(mqtt_msg, 50);
|
||||
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_.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;
|
||||
}
|
||||
|
||||
|
@ -402,7 +441,8 @@ bool is_value_flip(char *buf) {
|
|||
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;
|
||||
char buf[buflen];
|
||||
//int action = -1;
|
||||
|
@ -475,11 +515,12 @@ int serve_web_request(struct mg_connection *nc, struct http_message *http_msg, c
|
|||
logMessage(LOG_WARNING, "Bad request unknown option\n");
|
||||
length = sprintf(buffer, "{ \"error\": \"Bad request unknown option\" }");
|
||||
}
|
||||
*changedOption = true;
|
||||
//*changedOption = true;
|
||||
setEventStatus;
|
||||
//broadcast_sprinklerdstate(nc);
|
||||
} else if (strncasecmp(buf, "config", 6) == 0) {
|
||||
mg_get_http_var(&http_msg->query_string, "option", buf, buflen);
|
||||
if (strncasecmp(buf, "raindelaychance", 15) == 0)
|
||||
if (strncasecmp(buf, "raindelaychance", 15) == 0 )
|
||||
{
|
||||
mg_get_http_var(&http_msg->query_string, "value", buf, buflen);
|
||||
_sdconfig_.precipChanceDelay = atoi(buf);
|
||||
|
@ -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);
|
||||
if (strncasecmp(buf, "chanceofrain", 13) == 0) {
|
||||
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));
|
||||
} else if (strncasecmp(buf, "raintotal", 9) == 0) {
|
||||
mg_get_http_var(&http_msg->query_string, "value", buf, buflen);
|
||||
logMessage(LOG_NOTICE, "API: Rain total %.2f\n",atof(buf));
|
||||
setTodayRainTotal(atof(buf));
|
||||
}
|
||||
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 (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);
|
||||
length = build_sprinkler_JSON(buffer, size);
|
||||
//} 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) {
|
||||
logMessage(LOG_NOTICE, "API: Turn zone %d off\n",zone);
|
||||
zc_zone(type, zone, zcOFF, runtime);
|
||||
length = build_sprinkler_JSON(buffer, size);
|
||||
} 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);
|
||||
} else {
|
||||
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);
|
||||
length = sprintf(buffer, "{ \"error\": \"Bad request on zone %d, unknown state %s\"}", zone, buf);
|
||||
}
|
||||
|
||||
setEventZones;
|
||||
}
|
||||
} else if (strcmp(buf, "zrtcfg") == 0) {
|
||||
//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);
|
||||
length = build_sprinkler_JSON(buffer, size);
|
||||
zc_update_runtime(zone);
|
||||
*changedOption = true;
|
||||
//*changedOption = true;
|
||||
setEventZones;
|
||||
} else
|
||||
length += sprintf(buffer, "{ \"error\": \"bad request zone %d runtime %d\"}",zone,runtime);
|
||||
} 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 *c_type;
|
||||
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);
|
||||
|
||||
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, 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;
|
||||
|
||||
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);
|
||||
//logMessage (LOG_DEBUG, "Web Return %d = '%.*s'\n",size, size, buf);
|
||||
|
||||
if (changedOption)
|
||||
_sdconfig_.eventToUpdateHappened = true;
|
||||
//broadcast_sprinklerdstate(nc);
|
||||
//if (changedOption)
|
||||
// _sdconfig_.eventToUpdateHappened = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -730,7 +779,8 @@ void action_mqtt_message(struct mg_connection *nc, struct mg_mqtt_message *msg){
|
|||
if (zone > 0 && zone <= _sdconfig_.zones) {
|
||||
int v = str2int(msg->payload.p, msg->payload.len);
|
||||
_sdconfig_.zonecfg[zone].default_runtime = v / 60;
|
||||
_sdconfig_.eventToUpdateHappened = true;
|
||||
//_sdconfig_.eventToUpdateHappened = true;
|
||||
//setEventZones;
|
||||
zc_update_runtime(zone);
|
||||
logMessage(LOG_DEBUG, "MQTT: Default runtime zone %d is %d\n",zone,_sdconfig_.zonecfg[zone].default_runtime);
|
||||
} 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 ) {
|
||||
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 ) {
|
||||
//_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);
|
||||
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 ) {
|
||||
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 ) {
|
||||
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);
|
||||
} 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);
|
||||
logMessage(LOG_DEBUG, "MQTT: Chance of rain %d%%\n",v);
|
||||
logMessage(LOG_NOTICE, "MQTT: Chance of rain %d%%\n",v);
|
||||
setTodayChanceOfRain(v);
|
||||
} else if (pt2 != NULL && pt3 != NULL && strncmp(pt2, "zone", 4) == 0 && strncmp(pt3, "set", 3) == 0 ) {
|
||||
int zone = atoi(&pt2[4]);
|
||||
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);
|
||||
logMessage(LOG_DEBUG, "MQTT: Turn zone %d %s\n",zone, status==zcON?"ON":"OFF");
|
||||
} else if (zone == 0 && status == zcOFF && _sdconfig_.currentZone.type != zcNONE) {
|
||||
// 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);
|
||||
zc_zone(zcSINGLE, _sdconfig_.currentZone.zone , zcOFF, 0);
|
||||
} else if (zone == 0 && status == zcON) {
|
||||
// Can't turn on master valve, just re-send current stats.
|
||||
_sdconfig_.eventToUpdateHappened = true;
|
||||
//_sdconfig_.eventToUpdateHappened = true;
|
||||
setEventZones;
|
||||
setEventStatus;
|
||||
} else {
|
||||
logMessage(LOG_WARNING, "MQTT: unknown zone %d\n",zone);
|
||||
}
|
||||
} 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);
|
||||
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'
|
45
sd_cron.c
45
sd_cron.c
|
@ -15,10 +15,14 @@ bool setTodayChanceOfRain(int percent)
|
|||
{
|
||||
logMessage(LOG_DEBUG, "Set today's chance of rain = %d\n",percent);
|
||||
if (percent <= 100 && percent >= 0) {
|
||||
//_sdconfig_.eventToUpdateHappened = true;
|
||||
setEventRainProbability;
|
||||
_sdconfig_.todayRainChance = percent;
|
||||
if (_sdconfig_.precipChanceDelay > 0 && _sdconfig_.todayRainChance >= _sdconfig_.precipChanceDelay) {
|
||||
//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;
|
||||
}
|
||||
|
@ -28,10 +32,12 @@ bool setTodayChanceOfRain(int percent)
|
|||
|
||||
bool setTodayRainTotal(float rain)
|
||||
{
|
||||
if (_sdconfig_.todayRainTotal == rain)
|
||||
if (_sdconfig_.todayRainTotal == rain && rain != 0)
|
||||
return true;
|
||||
|
||||
_sdconfig_.todayRainTotal = rain;
|
||||
|
||||
_sdconfig_.todayRainTotal = rain;
|
||||
//_sdconfig_.eventToUpdateHappened = true;
|
||||
setEventRainTotal;
|
||||
|
||||
logMessage(LOG_DEBUG, "Today's rain total = %f\n",_sdconfig_.todayRainTotal);
|
||||
|
||||
|
@ -64,7 +70,8 @@ bool check_delay24h()
|
|||
void enable_calendar(bool state)
|
||||
{
|
||||
if (_sdconfig_.calendar != state) {
|
||||
_sdconfig_.eventToUpdateHappened = true;
|
||||
//_sdconfig_.eventToUpdateHappened = true;
|
||||
setEventStatus;
|
||||
_sdconfig_.calendar = state;
|
||||
logMessage(LOG_NOTICE, "Turning %s calendar\n",state==true?"on":"off");
|
||||
} else {
|
||||
|
@ -75,7 +82,8 @@ void enable_calendar(bool state)
|
|||
void enable_delay24h(bool state)
|
||||
{
|
||||
if (_sdconfig_.delay24h != state) {
|
||||
_sdconfig_.eventToUpdateHappened = true;
|
||||
//_sdconfig_.eventToUpdateHappened = true;
|
||||
setEventStatus;
|
||||
|
||||
_sdconfig_.delay24h = state;
|
||||
if (state) {
|
||||
|
@ -96,7 +104,8 @@ void enable_delay24h(bool state)
|
|||
void reset_delay24h_time(unsigned long dtime)
|
||||
{
|
||||
if (_sdconfig_.delay24h != true) {
|
||||
_sdconfig_.eventToUpdateHappened = true;
|
||||
//_sdconfig_.eventToUpdateHappened = true;
|
||||
setEventStatus;
|
||||
}
|
||||
|
||||
time_t now;
|
||||
|
@ -136,6 +145,7 @@ void write_cron() {
|
|||
int hour;
|
||||
int day;
|
||||
int zone;
|
||||
int rb4i;
|
||||
|
||||
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=raintotal&value=0'\n",_sdconfig_.socket_port);
|
||||
fprintf(fp, "#***** AUTO GENERATED DO NOT EDIT *****\n");
|
||||
|
@ -205,7 +234,7 @@ void read_cron() {
|
|||
for (day=0; day <= 6; day++) {
|
||||
_sdconfig_.cron[day].hour = -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,7 +148,8 @@ int main (int argc, char *argv[])
|
|||
_sdconfig_.calendar = true;
|
||||
_sdconfig_.currentZone.type = zcNONE;
|
||||
_sdconfig_.cron_update = 0;
|
||||
_sdconfig_.eventToUpdateHappened = false;
|
||||
//_sdconfig_.eventToUpdateHappened = false;
|
||||
_sdconfig_.updateEventMask = 0;
|
||||
read_cron();
|
||||
read_cache();
|
||||
|
||||
|
@ -303,10 +304,10 @@ void main_loop ()
|
|||
{
|
||||
//logMessage (LOG_DEBUG, "mg_mgr_poll\n");
|
||||
mg_mgr_poll(&_mgr, 500);
|
||||
|
||||
//logMessage (LOG_DEBUG, "updateEventMask=%d\n",_sdconfig_.updateEventMask);
|
||||
check_cron();
|
||||
if (zc_check() == true || check_delay24h() == true || _sdconfig_.eventToUpdateHappened) {
|
||||
_sdconfig_.eventToUpdateHappened = false;
|
||||
if (zc_check() == true || check_delay24h() == true || _sdconfig_.updateEventMask != 0) {
|
||||
//_sdconfig_.eventToUpdateHappened = false;
|
||||
broadcast_sprinklerdstate(_mgr.active_connections);
|
||||
broadcast_sprinklerdactivestate(_mgr.active_connections);
|
||||
} else if (i > 10 && _sdconfig_.currentZone.type!=zcNONE) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef SD_VERSION_H
|
||||
#define SD_VERSION_H
|
||||
|
||||
#define SD_VERSION "1.3"
|
||||
#define SD_VERSION "1.4.1"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -42,6 +42,8 @@ int start_next_zone(int startz) {
|
|||
|
||||
int zone = startz+1;
|
||||
|
||||
setEventZones;
|
||||
|
||||
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#");
|
||||
|
@ -74,6 +76,7 @@ void zc_update_runtime(int zone) {
|
|||
if (zone > 0 && zone < _sdconfig_.zones && zone == _sdconfig_.currentZone.zone) {
|
||||
_sdconfig_.currentZone.duration=_sdconfig_.zonecfg[zone].default_runtime;
|
||||
}
|
||||
setEventZones;
|
||||
}
|
||||
|
||||
bool zc_check() {
|
||||
|
@ -236,7 +239,8 @@ bool zc_start(/*zcRunType type,*/ int zone) {
|
|||
digitalWrite(_sdconfig_.zonecfg[zone].pin, _sdconfig_.zonecfg[zone].on_state );
|
||||
int rtn = true;
|
||||
#endif
|
||||
_sdconfig_.eventToUpdateHappened = true;
|
||||
//_sdconfig_.eventToUpdateHappened = true;
|
||||
setEventZones;
|
||||
|
||||
return rtn;
|
||||
// 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 );
|
||||
int rtn = true;
|
||||
#endif
|
||||
_sdconfig_.eventToUpdateHappened = true;
|
||||
//_sdconfig_.eventToUpdateHappened = true;
|
||||
setEventZones;
|
||||
|
||||
return rtn;
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue