Update
parent
53f6e6874c
commit
e93ad44028
2
Makefile
2
Makefile
|
@ -26,7 +26,7 @@ CFLAGS = $(GCCFLAGS) -I. -I./minIni $(DBG) $(LIBS) -D MG_DISABLE_MD5 -D MG_DISAB
|
|||
|
||||
|
||||
# define the C source files
|
||||
SRCS = sprinkler.c utils.c config.c net_services.c json_messages.c zone_ctrl.c sd_cron.c mongoose.c minIni/minIni.c $(sd_GPIO_C)
|
||||
SRCS = sprinkler.c utils.c config.c net_services.c json_messages.c zone_ctrl.c sd_cron.c hassio.c mongoose.c minIni/minIni.c $(sd_GPIO_C)
|
||||
|
||||
# define the C object files
|
||||
#
|
||||
|
|
12
README.md
12
README.md
|
@ -93,6 +93,16 @@ Specifically, make sure you configure your MQTT, Pool Equiptment Labels & Domoti
|
|||
|
||||
## Included scripts in extras directory.
|
||||
|
||||
[sprinklerRainProbability.sh](https://github.com/sfeakes/sprinklerd/blob/master/extras/sprinklerRainProbability.sh)
|
||||
|
||||
Script to check the chance of rain from forecast OpenWeather, WeaterBit, Climacell, WeatherAPI, if it's greater than a configured percentage then enable the 24h rainDelay on SprinklerD.
|
||||
Simply edit the scrips with your values, and use cron to run it 30mins before your sprinkelrs are due to turn on each day. If the chance of rain is over your configured % it will enable SprinklerD's 24h rain delay, which will stop the sprinklers running that day, and the 24h delay will timeout before the sprinklers are due to run the next day. (or be enabeled again if the chance of rain is high).
|
||||
You will need to edit this script for your API keys.
|
||||
|
||||
Example cron entry
|
||||
`0 5 * * * ~/bin/sprinklerRainProbability.sh weatherapi`
|
||||
|
||||
<!--
|
||||
[sprinklerDarkskys.sh](https://github.com/sfeakes/sprinklerd/blob/master/extras/sprinklerDarkskys.sh)
|
||||
Script to check the chance of rain from darkskys forecast API, if it's greater than a configured percentage then enable the 24h rainDelay on SprinklerD.
|
||||
Simply edit the scrips with your values, and use cron to run it 30mins before your sprinkelrs are due to turn on each day. If the chance of rain is over your configured % it will enable SprinklerD's 24h rain delay, which will stop the sprinklers running that day, and the 24h delay will timeout before the sprinklers are due to run the next day. (or be enabeled again if the chance of rain is high)
|
||||
|
@ -106,7 +116,7 @@ Script to pull daily rain total from Meteohub and send it to SprinklerD. Sprink
|
|||
|
||||
[sprinklerRainDelay.sh](https://github.com/sfeakes/sprinklerd/blob/master/extras/sprinklerRainDelay.sh)
|
||||
Script to enable extended rain delays. i.e. I have my weatherstation triger this script when it detects rain. The script will cancel any running zones and enable a rain delay. You can use a number on command line parameter to enable long delays, (number represents number of days). So if my rainsensor logs over 5mm rain in any 24h period it will call this script with a 2 day delay, or 3 day delay if over 15mm of rain.
|
||||
|
||||
-->
|
||||
|
||||
# Configuration with home automation hubs
|
||||
|
||||
|
|
20
config.c
20
config.c
|
@ -232,22 +232,34 @@ void readCfg(char *inifile)
|
|||
ini_gets("SPRINKLERD", "MQTT_ADDRESS", NULL, _sdconfig_.mqtt_address, sizearray(_sdconfig_.mqtt_address), inifile);
|
||||
ini_gets("SPRINKLERD", "MQTT_USER", NULL, _sdconfig_.mqtt_user, sizearray(_sdconfig_.mqtt_user), inifile);
|
||||
ini_gets("SPRINKLERD", "MQTT_PASSWD", NULL, _sdconfig_.mqtt_passwd, sizearray(_sdconfig_.mqtt_passwd), inifile);
|
||||
|
||||
|
||||
if ( ini_gets("SPRINKLERD", "MQT_TOPIC", NULL, _sdconfig_.mqtt_topic, sizearray(_sdconfig_.mqtt_topic), inifile) > 0 )
|
||||
_sdconfig_.enableMQTTaq = true;
|
||||
else
|
||||
_sdconfig_.enableMQTTaq = false;
|
||||
|
||||
//if ( ini_gets("SPRINKLERD", "MQTT_HA_DIS_TOPIC", NULL, _sdconfig_.mqtt_ha_dis_topic, sizearray(_sdconfig_.mqtt_ha_dis_topic), inifile) > 0 )
|
||||
if ( ini_gets("SPRINKLERD", "MQTT_DZ_PUB_TOPIC", NULL, _sdconfig_.mqtt_dz_pub_topic, sizearray(_sdconfig_.mqtt_dz_pub_topic), inifile) > 0 &&
|
||||
ini_gets("SPRINKLERD", "MQTT_DZ_SUB_TOPIC", NULL, _sdconfig_.mqtt_dz_sub_topic, sizearray(_sdconfig_.mqtt_dz_sub_topic), inifile) > 0)
|
||||
_sdconfig_.enableMQTTdz = true;
|
||||
else
|
||||
_sdconfig_.enableMQTTdz = false;
|
||||
|
||||
if (_sdconfig_.enableMQTTdz == true || _sdconfig_.enableMQTTaq == true) {
|
||||
if ( ini_gets("SPRINKLERD", "MQTT_HA_DIS_TOPIC", NULL, _sdconfig_.mqtt_ha_dis_topic, sizearray(_sdconfig_.mqtt_ha_dis_topic), inifile) > 0 )
|
||||
_sdconfig_.enableMQTTha = true;
|
||||
else
|
||||
_sdconfig_.enableMQTTha = false;
|
||||
|
||||
|
||||
if (_sdconfig_.enableMQTTaq == true ) {
|
||||
logMessage (LOG_DEBUG,"Config mqtt_topic '%s'\n",_sdconfig_.mqtt_topic);
|
||||
logMessage (LOG_DEBUG,"Config mqtt_dz_pub_topic '%s'\n",_sdconfig_.mqtt_dz_pub_topic);
|
||||
logMessage (LOG_DEBUG,"Config mqtt_dz_sub_topic '%s'\n",_sdconfig_.mqtt_dz_sub_topic);
|
||||
if (_sdconfig_.enableMQTTdz == true) {
|
||||
logMessage (LOG_DEBUG,"Config mqtt_dz_pub_topic '%s'\n",_sdconfig_.mqtt_dz_pub_topic);
|
||||
logMessage (LOG_DEBUG,"Config mqtt_dz_sub_topic '%s'\n",_sdconfig_.mqtt_dz_sub_topic);
|
||||
}
|
||||
if (_sdconfig_.enableMQTTha == true) {
|
||||
logMessage (LOG_DEBUG,"Config mqtt_ha_dis_topic '%s'\n",_sdconfig_.mqtt_ha_dis_topic);
|
||||
}
|
||||
} else {
|
||||
logMessage (LOG_DEBUG,"Config mqtt 'disabeled'\n");
|
||||
}
|
||||
|
|
8
config.h
8
config.h
|
@ -61,12 +61,13 @@ struct sprinklerdcfg {
|
|||
char socket_port[6];
|
||||
char name[20];
|
||||
char docroot[512];
|
||||
char mqtt_address[20];
|
||||
char mqtt_address[128];
|
||||
char mqtt_user[50];
|
||||
char mqtt_passwd[50];
|
||||
char mqtt_topic[50];
|
||||
char mqtt_dz_sub_topic[50];
|
||||
char mqtt_dz_pub_topic[50];
|
||||
char mqtt_dz_sub_topic[128];
|
||||
char mqtt_dz_pub_topic[128];
|
||||
char mqtt_ha_dis_topic[128];
|
||||
char mqtt_ID[MQTT_ID_LEN];
|
||||
int dzidx_calendar;
|
||||
int dzidx_24hdelay;
|
||||
|
@ -75,6 +76,7 @@ struct sprinklerdcfg {
|
|||
int dzidx_rainsensor;
|
||||
bool enableMQTTdz;
|
||||
bool enableMQTTaq;
|
||||
bool enableMQTTha;
|
||||
int zones;
|
||||
int inputs;
|
||||
//int pincfgs;
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# you MUST change at least one of the following API keys, and the lat lng variables.
|
||||
# openweatherAPI, weatherAPIkey, weatherbitAPIkey, climacellAPIkey
|
||||
# lat = your latitude
|
||||
# lon = your longitude
|
||||
# probabilityOver = Enable rain delay if probability of rain today is grater than this number.
|
||||
# Range is 0 to 100, so 50 is 50%
|
||||
# sprinklerdEnableDelay = the URL to SprinklerD
|
||||
#
|
||||
# The below are NOT valid, you MUST change them to your information.
|
||||
|
||||
# API Keys from the following are supported
|
||||
# openweathermap.org weatherapi.com weatherbit.io climacell.co
|
||||
|
||||
openweatherAPIkey='-----'
|
||||
weatherbitAPIkey='-----'
|
||||
climacellAPIkey='-----'
|
||||
weatherAPIkey='-----'
|
||||
|
||||
lat='42.3601'
|
||||
lon='-71.0589'
|
||||
|
||||
# 101 means don't set rain delay from this script, use the SprinklerD config (webUI) to decide if to set delay
|
||||
probabilityOver=101
|
||||
|
||||
# If you are not running this from the same host as SprinklerD, then change localhost in the below.
|
||||
sprinklerdHost="http://localhost:80"
|
||||
|
||||
|
||||
|
||||
########################################################################################################################
|
||||
#
|
||||
# Should not need to edit below this line.
|
||||
#
|
||||
########################################################################################################################
|
||||
|
||||
|
||||
sprinklerdEnableDelay="$sprinklerdHost/?type=option&option=24hdelay&state=reset"
|
||||
sprinklerdProbability="$sprinklerdHost/?type=sensor&sensor=chanceofrain&value="
|
||||
|
||||
openweatherURL="https://api.openweathermap.org/data/2.5/onecall?lat=$lat&lon=$lon&appid=$openweatherAPIkey&exclude=current,minutely,hourly,alerts"
|
||||
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"
|
||||
|
||||
true=0
|
||||
false=1
|
||||
|
||||
echoerr() { printf "%s\n" "$*" >&2; }
|
||||
echomsg() { if [ -t 1 ]; then echo "$@" 1>&2; fi; }
|
||||
|
||||
function getURL() {
|
||||
url=$1
|
||||
jq=$2
|
||||
factor=$3
|
||||
|
||||
JSON=$(curl -s "$url")
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echoerr "Error reading URL, '$1' please check!"
|
||||
echoerr "Maybe you didn't configure your API and location?"
|
||||
echo 0;
|
||||
return $false
|
||||
else
|
||||
probability=$(echo $JSON | jq "$jq" )
|
||||
fi
|
||||
|
||||
probability=$(echo "$probability * $factor / 1" | bc )
|
||||
echo $probability
|
||||
return $true
|
||||
}
|
||||
|
||||
# Test we have everything installed
|
||||
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; }
|
||||
|
||||
pop=-1
|
||||
|
||||
if [ "$#" -lt 1 ]; then
|
||||
echomsg "Pass at least one command line parameter (openweather, weatherbit, climacell, weatherapi)"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
for var in "$@"
|
||||
do
|
||||
case "$var" in
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echomsg "Chance of rain $pop%"
|
||||
|
||||
curl -s "$sprinklerdProbability$pop" > /dev/null
|
||||
|
||||
if (( $(echo "$pop > $probabilityOver" | bc -l) )); then
|
||||
echomsg "Enabeling rain delay"
|
||||
curl -s "$sprinklerdEnableDelay" > /dev/null
|
||||
fi
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,152 @@
|
|||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
|
||||
|
||||
#include "mongoose.h"
|
||||
#include "config.h"
|
||||
#include "net_services.h"
|
||||
#include "version.h"
|
||||
|
||||
#define HASS_DEVICE "\"identifiers\": " \
|
||||
"[\"SprinklerD\"]," \
|
||||
" \"sw_version\": \"" SD_VERSION "\"," \
|
||||
" \"model\": \"Sprinkler Daemon\"," \
|
||||
" \"name\": \"SprinklerD\"," \
|
||||
" \"manufacturer\": \"SprinklerD\"," \
|
||||
" \"suggested_area\": \"pool\""
|
||||
|
||||
#define HASS_AVAILABILITY "\"payload_available\" : \"1\"," \
|
||||
"\"payload_not_available\" : \"0\"," \
|
||||
"\"topic\": \"%s/" MQTT_LWM_TOPIC "\""
|
||||
|
||||
const char *HASSIO_TEXT_SENSOR_DISCOVER = "{"
|
||||
"\"device\": {" HASS_DEVICE "},"
|
||||
"\"availability\": {" HASS_AVAILABILITY "},"
|
||||
"\"type\": \"sensor\","
|
||||
"\"unique_id\": \"%s\","
|
||||
"\"name\": \"%s\","
|
||||
"\"state_topic\": \"%s/%s\","
|
||||
"\"icon\": \"mdi:card-text\""
|
||||
"}";
|
||||
|
||||
const char *HASSIO_SWITCH_DISCOVER = "{"
|
||||
"\"device\": {" HASS_DEVICE "},"
|
||||
"\"availability\": {" HASS_AVAILABILITY "},"
|
||||
"\"type\": \"switch\","
|
||||
"\"unique_id\": \"%s\","
|
||||
"\"name\": \"%s\","
|
||||
"\"state_topic\": \"%s/%s\","
|
||||
"\"command_topic\": \"%s/%s/set\","
|
||||
"\"payload_on\": \"1\","
|
||||
"\"payload_off\": \"0\","
|
||||
"\"qos\": 1,"
|
||||
"\"retain\": false"
|
||||
"}";
|
||||
|
||||
const char *HASSIO_VALVE_DISCOVER = "{"
|
||||
"\"device\": {" HASS_DEVICE "},"
|
||||
"\"availability\": {" HASS_AVAILABILITY "},"
|
||||
"\"type\": \"valve\","
|
||||
"\"device_class\": \"water\","
|
||||
"\"unique_id\": \"%s\"," // sprinklerd_zone_1
|
||||
"\"name\": \"Zone %d (%s)\"," // 1 island
|
||||
"\"state_topic\": \"%s/zone%d\"," // 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' }}\","
|
||||
"\"payload_open\": \"1\","
|
||||
"\"payload_close\": \"0\","
|
||||
"\"qos\": 1,"
|
||||
"\"retain\": false"
|
||||
"}";
|
||||
|
||||
void publish_mqtt_hassio_discover(struct mg_connection *nc)
|
||||
{
|
||||
char msg[2048];
|
||||
char topic[256];
|
||||
char id[128];
|
||||
int i;
|
||||
|
||||
|
||||
sprintf(id,"sprinklerd_status");
|
||||
sprintf(topic, "%s/sensor/sprinklerd/%s/config", _sdconfig_.mqtt_ha_dis_topic, id);
|
||||
sprintf(msg, HASSIO_TEXT_SENSOR_DISCOVER,
|
||||
_sdconfig_.mqtt_topic,
|
||||
id,
|
||||
"Status",
|
||||
_sdconfig_.mqtt_topic, "status" );
|
||||
send_mqtt_msg(nc, topic, msg);
|
||||
|
||||
sprintf(id,"sprinklerd_active_zone");
|
||||
sprintf(topic, "%s/sensor/sprinklerd/%s/config", _sdconfig_.mqtt_ha_dis_topic, id);
|
||||
sprintf(msg, HASSIO_TEXT_SENSOR_DISCOVER,
|
||||
_sdconfig_.mqtt_topic,
|
||||
id,
|
||||
"Active Zone",
|
||||
_sdconfig_.mqtt_topic, "active" );
|
||||
send_mqtt_msg(nc, topic, msg);
|
||||
|
||||
|
||||
|
||||
sprintf(id,"sprinklerd_calendar");
|
||||
sprintf(topic, "%s/switch/sprinklerd/%s/config", _sdconfig_.mqtt_ha_dis_topic, id);
|
||||
sprintf(msg, HASSIO_SWITCH_DISCOVER,
|
||||
_sdconfig_.mqtt_topic,
|
||||
id,
|
||||
"Calendar Schedule",
|
||||
_sdconfig_.mqtt_topic, "calendar",
|
||||
_sdconfig_.mqtt_topic, "calendar" );
|
||||
send_mqtt_msg(nc, topic, msg);
|
||||
|
||||
sprintf(id,"sprinklerd_24hdelay");
|
||||
sprintf(topic, "%s/switch/sprinklerd/%s/config", _sdconfig_.mqtt_ha_dis_topic, id);
|
||||
sprintf(msg, HASSIO_SWITCH_DISCOVER,
|
||||
_sdconfig_.mqtt_topic,
|
||||
id,
|
||||
"24 Hour rain delay",
|
||||
_sdconfig_.mqtt_topic, "24hdelay",
|
||||
_sdconfig_.mqtt_topic, "24hdelay" );
|
||||
send_mqtt_msg(nc, topic, msg);
|
||||
|
||||
sprintf(id,"sprinklerd_cycleallzones");
|
||||
sprintf(topic, "%s/switch/sprinklerd/%s/config", _sdconfig_.mqtt_ha_dis_topic, id);
|
||||
sprintf(msg, HASSIO_SWITCH_DISCOVER,
|
||||
_sdconfig_.mqtt_topic,
|
||||
id,
|
||||
"Cycle All Zones",
|
||||
_sdconfig_.mqtt_topic, "cycleallzones",
|
||||
_sdconfig_.mqtt_topic, "cycleallzones" );
|
||||
send_mqtt_msg(nc, topic, msg);
|
||||
|
||||
|
||||
|
||||
|
||||
//for (i=(_sdconfig_.master_valve?0:1); i <= _sdconfig_.zones ; i++)
|
||||
// Don't publish zome0/master valve to ha
|
||||
for (i=1; i <= _sdconfig_.zones ; i++)
|
||||
{
|
||||
sprintf(id,"sprinklerd_zone_%d", _sdconfig_.zonecfg[i].zone);
|
||||
sprintf(topic, "%s/valve/sprinklerd/%s/config", _sdconfig_.mqtt_ha_dis_topic, id);
|
||||
sprintf(msg, HASSIO_VALVE_DISCOVER,
|
||||
_sdconfig_.mqtt_topic,
|
||||
id,
|
||||
_sdconfig_.zonecfg[i].zone,
|
||||
_sdconfig_.zonecfg[i].name,
|
||||
_sdconfig_.mqtt_topic,_sdconfig_.zonecfg[i].zone,
|
||||
_sdconfig_.mqtt_topic,_sdconfig_.zonecfg[i].zone
|
||||
);
|
||||
|
||||
send_mqtt_msg(nc, topic, msg);
|
||||
/*
|
||||
length += sprintf(buffer+length, "{\"type\" : \"zone\", \"zone\": %d, \"name\": \"%s\", \"state\": \"%s\", \"duration\": %d, \"id\" : \"zone%d\" },",
|
||||
_sdconfig_.zonecfg[i].zone,
|
||||
_sdconfig_.zonecfg[i].name,
|
||||
(digitalRead(_sdconfig_.zonecfg[i].pin)==_sdconfig_.zonecfg[i].on_state?"on":"off"),
|
||||
_sdconfig_.zonecfg[i].default_runtime * 60,
|
||||
_sdconfig_.zonecfg[i].zone);
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef HASSIO_H_
|
||||
#define HASSIO_H_
|
||||
|
||||
void publish_mqtt_hassio_discover(struct mg_connection *nc);
|
||||
|
||||
#endif
|
|
@ -19,6 +19,7 @@
|
|||
#include "json_messages.h"
|
||||
#include "zone_ctrl.h"
|
||||
#include "sd_cron.h"
|
||||
#include "hassio.h"
|
||||
|
||||
|
||||
#define EVENT_SIZE ( sizeof (struct inotify_event) )
|
||||
|
@ -207,7 +208,7 @@ void publish_zone_mqtt(struct mg_connection *nc, struct GPIOcfg *gpiopin) {
|
|||
send_mqtt_msg(nc, mqtt_topic, mqtt_msg);
|
||||
|
||||
sprintf(mqtt_topic, "%s/zone%d/remainingduration", _sdconfig_.mqtt_topic, gpiopin->zone);
|
||||
if (_sdconfig_.currentZone.zone == gpiopin->zone) {
|
||||
if (_sdconfig_.currentZone.zone == gpiopin->zone && _sdconfig_.currentZone.type != zcNONE) {
|
||||
sprintf(mqtt_msg, "%d", _sdconfig_.currentZone.timeleft * 60);
|
||||
} else {
|
||||
sprintf(mqtt_msg, "%d", 0);
|
||||
|
@ -277,9 +278,16 @@ void broadcast_sprinklerdactivestate(struct mg_connection *nc)
|
|||
|
||||
for (c = mg_next(nc->mgr, NULL); c != NULL; c = mg_next(nc->mgr, c)) {
|
||||
if (is_mqtt(c)) {
|
||||
sprintf(mqtt_topic, "%s/active", _sdconfig_.mqtt_topic);
|
||||
sprintf(mqtt_msg, "Zone %d", _sdconfig_.currentZone.zone );
|
||||
send_mqtt_msg(c, mqtt_topic, mqtt_msg);
|
||||
if (_sdconfig_.currentZone.type==zcNONE) {
|
||||
sprintf(mqtt_topic, "%s/active", _sdconfig_.mqtt_topic);
|
||||
send_mqtt_msg(c, mqtt_topic, " ");
|
||||
sprintf(mqtt_topic, "%s/cycleallzones/remainingduration", _sdconfig_.mqtt_topic);
|
||||
send_mqtt_msg(c, mqtt_topic, "0");
|
||||
} else {
|
||||
sprintf(mqtt_topic, "%s/active", _sdconfig_.mqtt_topic);
|
||||
sprintf(mqtt_msg, "Zone %d", _sdconfig_.currentZone.zone );
|
||||
send_mqtt_msg(c, mqtt_topic, mqtt_msg);
|
||||
//}
|
||||
//sprintf(mqtt_topic, "%s/remainingduration", _sdconfig_.mqtt_topic);
|
||||
//sprintf(mqtt_msg, "%d", _sdconfig_.currentZone.timeleft );
|
||||
//send_mqtt_msg(c, mqtt_topic, mqtt_msg);
|
||||
|
@ -290,6 +298,7 @@ void broadcast_sprinklerdactivestate(struct mg_connection *nc)
|
|||
sprintf(mqtt_topic, "%s/zone%d/remainingduration", _sdconfig_.mqtt_topic, _sdconfig_.currentZone.zone);
|
||||
sprintf(mqtt_msg, "%d", _sdconfig_.currentZone.timeleft );
|
||||
send_mqtt_msg(c, mqtt_topic, mqtt_msg);
|
||||
}
|
||||
if (_sdconfig_.currentZone.type == zcALL) {
|
||||
int i, total=_sdconfig_.currentZone.timeleft;
|
||||
for (i=_sdconfig_.currentZone.zone+1; i <= _sdconfig_.zones; i++) {
|
||||
|
@ -299,6 +308,8 @@ void broadcast_sprinklerdactivestate(struct mg_connection *nc)
|
|||
sprintf(mqtt_msg, "%d", total );
|
||||
send_mqtt_msg(c, mqtt_topic, mqtt_msg);
|
||||
sprintf(mqtt_topic, "%s/zone0/remainingduration", _sdconfig_.mqtt_topic);
|
||||
//sprintf(mqtt_msg, "%d", _sdconfig_.currentZone.timeleft );
|
||||
sprintf(mqtt_msg, "%d", total );
|
||||
send_mqtt_msg(c, mqtt_topic, mqtt_msg);
|
||||
} else if (_sdconfig_.currentZone.type != zcNONE) {
|
||||
sprintf(mqtt_topic, "%s/zone0/remainingduration", _sdconfig_.mqtt_topic);
|
||||
|
@ -306,7 +317,10 @@ void broadcast_sprinklerdactivestate(struct mg_connection *nc)
|
|||
send_mqtt_msg(c, mqtt_topic, mqtt_msg);
|
||||
}
|
||||
|
||||
}
|
||||
if (_sdconfig_.currentZone.type != zcALL) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -765,6 +779,8 @@ void action_mqtt_message(struct mg_connection *nc, struct mg_mqtt_message *msg){
|
|||
static void ev_handler(struct mg_connection *nc, int ev, void *p) {
|
||||
struct mg_mqtt_message *mqtt_msg;
|
||||
struct http_message *http_msg;
|
||||
static bool hapublished = false;
|
||||
char aq_topic[30];
|
||||
//struct websocket_message *ws_msg;
|
||||
//static double last_control_time;
|
||||
|
||||
|
@ -775,7 +791,7 @@ static void ev_handler(struct mg_connection *nc, int ev, void *p) {
|
|||
switch (ev) {
|
||||
case MG_EV_CONNECT: {
|
||||
set_mqtt(nc);
|
||||
if (_sdconfig_.mqtt_topic != NULL || _sdconfig_.mqtt_dz_sub_topic != NULL) {
|
||||
//if (_sdconfig_.mqtt_topic != NULL || _sdconfig_.mqtt_dz_sub_topic != NULL) {
|
||||
struct mg_send_mqtt_handshake_opts opts;
|
||||
memset(&opts, 0, sizeof(opts));
|
||||
opts.user_name = _sdconfig_.mqtt_user;
|
||||
|
@ -784,12 +800,17 @@ static void ev_handler(struct mg_connection *nc, int ev, void *p) {
|
|||
// opts.flags = 0x00;
|
||||
// opts.flags |= MG_MQTT_WILL_RETAIN;
|
||||
opts.flags |= MG_MQTT_CLEAN_SESSION; // NFS Need to readup on this
|
||||
|
||||
sprintf(aq_topic, "%s/%s", _sdconfig_.mqtt_topic,MQTT_LWM_TOPIC);
|
||||
opts.will_topic = aq_topic;
|
||||
opts.will_message = MQTT_OFF;
|
||||
|
||||
mg_set_protocol_mqtt(nc);
|
||||
mg_send_mqtt_handshake_opt(nc, _sdconfig_.mqtt_ID, opts);
|
||||
logMessage(LOG_INFO, "Connected to mqtt %s with id of: %s\n", _sdconfig_.mqtt_address, _sdconfig_.mqtt_ID);
|
||||
_mqtt_status = mqttrunning;
|
||||
_mqtt_connection = nc;
|
||||
}
|
||||
//}
|
||||
//last_control_time = mg_time();
|
||||
} break;
|
||||
|
||||
|
@ -825,12 +846,25 @@ static void ev_handler(struct mg_connection *nc, int ev, void *p) {
|
|||
mg_mqtt_subscribe(nc, topics, 1, 42);
|
||||
logMessage(LOG_INFO, "MQTT: Subscribing to '%s'\n", _sdconfig_.mqtt_dz_sub_topic);
|
||||
}
|
||||
|
||||
if (_sdconfig_.enableMQTTha && hapublished == false) {
|
||||
logMessage (LOG_DEBUG, "MQTT: Publishing to Home Assistant\n");
|
||||
publish_mqtt_hassio_discover(nc);
|
||||
hapublished = true;
|
||||
}
|
||||
|
||||
broadcast_sprinklerdstate(nc);
|
||||
break;
|
||||
|
||||
case MG_EV_MQTT_PUBACK:
|
||||
mqtt_msg = (struct mg_mqtt_message *)p;
|
||||
logMessage(LOG_DEBUG, "Message publishing acknowledged (msg_id: %d)\n", mqtt_msg->message_id);
|
||||
logMessage(LOG_DEBUG, "MQTT: Message publishing acknowledged (msg_id: %d)\n", mqtt_msg->message_id);
|
||||
break;
|
||||
|
||||
case MG_EV_MQTT_SUBACK:
|
||||
logMessage(LOG_DEBUG, "MQTT: Subscription(s) acknowledged\n");
|
||||
sprintf(aq_topic, "%s/%s", _sdconfig_.mqtt_topic,MQTT_LWM_TOPIC);
|
||||
send_mqtt_msg(nc, aq_topic ,MQTT_ON);
|
||||
break;
|
||||
|
||||
case MG_EV_WEBSOCKET_HANDSHAKE_DONE:
|
||||
|
@ -903,8 +937,8 @@ bool check_net_services(struct mg_mgr *mgr) {
|
|||
|
||||
void start_mqtt(struct mg_mgr *mgr) {
|
||||
|
||||
//if (_sdconfig_.enableMQTT == false) {
|
||||
if( _sdconfig_.enableMQTTaq == false && _sdconfig_.enableMQTTdz == false ) {
|
||||
if (_sdconfig_.enableMQTTaq == false) {
|
||||
//if( _sdconfig_.enableMQTTaq == false && _sdconfig_.enableMQTTdz == false ) {
|
||||
logMessage (LOG_NOTICE, "MQTT client is disabled, not stating\n");
|
||||
_mqtt_status = mqttdisabled;
|
||||
return;
|
||||
|
@ -912,9 +946,9 @@ void start_mqtt(struct mg_mgr *mgr) {
|
|||
|
||||
//generate_mqtt_id(_sdconfig_.mqtt_ID, sizeof(_sdconfig_.mqtt_ID)-1);
|
||||
if (strlen(_sdconfig_.mqtt_ID) < 1) {
|
||||
logMessage (LOG_DEBUG, "MQTTaq %d | MQTTdz %d\n", _sdconfig_.enableMQTTaq, _sdconfig_.enableMQTTdz);
|
||||
//logMessage (LOG_DEBUG, "MQTTaq %d | MQTTdz %d\n", _sdconfig_.enableMQTTaq, _sdconfig_.enableMQTTdz);
|
||||
generate_mqtt_id(_sdconfig_.mqtt_ID, MQTT_ID_LEN-1);
|
||||
logMessage (LOG_DEBUG, "MQTTaq %d | MQTTdz %d\n", _sdconfig_.enableMQTTaq, _sdconfig_.enableMQTTdz);
|
||||
logMessage (LOG_DEBUG, "MQTTaq %d | MQTTdz %d | MQTTha %d\n", _sdconfig_.enableMQTTaq, _sdconfig_.enableMQTTdz, _sdconfig_.enableMQTTha);
|
||||
}
|
||||
|
||||
logMessage (LOG_NOTICE, "Starting MQTT client to %s\n", _sdconfig_.mqtt_address);
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
|
||||
#define MQTT_ON "1"
|
||||
#define MQTT_OFF "0"
|
||||
|
||||
#define MQTT_LWM_TOPIC "Alive"
|
||||
|
||||
//enum nsAction{nsNONE = 0, nsGPIO = 1, nsLED = 2, nsLCD = 3};
|
||||
|
||||
bool start_net_services(struct mg_mgr *mgr);
|
||||
|
@ -21,6 +24,9 @@ void broadcast_sprinklerdactivestate(struct mg_connection *nc);
|
|||
//void broadcast_state(struct mg_connection *nc);
|
||||
//void broadcast_state_error(struct mg_connection *nc, char *msg);
|
||||
bool check_net_services(struct mg_mgr *mgr);
|
||||
|
||||
void send_mqtt_msg(struct mg_connection *nc, char *toppic, char *message);
|
||||
|
||||
//void broadcast_polled_devices(struct mg_connection *nc);
|
||||
//void broadcast_polled_devices(struct mg_mgr *mgr);
|
||||
|
||||
|
|
Binary file not shown.
|
@ -13,6 +13,9 @@ LOG_LEVEL = NOTICE
|
|||
#MQTT_PASSWD = somepassword
|
||||
#MQT_TOPIC = sprinklerd
|
||||
|
||||
# If you want to publish to home assistant doscover topics.
|
||||
#MQTT_HA_DIS_TOPIC = homeassistant
|
||||
|
||||
# if you are using domoticz and MQTT uncomment
|
||||
#MQTT_DZ_PUB_TOPIC = domoticz/in
|
||||
#MQTT_DZ_SUB_TOPIC = domoticz/out
|
||||
|
|
14
sprinkler.c
14
sprinkler.c
|
@ -296,6 +296,8 @@ void main_loop ()
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
i=0;
|
||||
while (true)
|
||||
{
|
||||
|
@ -306,12 +308,16 @@ void main_loop ()
|
|||
if (zc_check() == true || check_delay24h() == true || _sdconfig_.eventToUpdateHappened) {
|
||||
_sdconfig_.eventToUpdateHappened = false;
|
||||
broadcast_sprinklerdstate(_mgr.active_connections);
|
||||
}
|
||||
|
||||
if (i >= 20) {
|
||||
broadcast_sprinklerdactivestate(_mgr.active_connections);
|
||||
} else if (i > 10 && _sdconfig_.currentZone.type!=zcNONE) {
|
||||
i=0;
|
||||
if (_sdconfig_.currentZone.type != zcNONE)
|
||||
broadcast_sprinklerdactivestate(_mgr.active_connections);
|
||||
} else {
|
||||
if (i >= 600) {
|
||||
i=0;
|
||||
broadcast_sprinklerdstate(_mgr.active_connections);
|
||||
broadcast_sprinklerdactivestate(_mgr.active_connections);
|
||||
}
|
||||
}
|
||||
|
||||
//logMessage (LOG_DEBUG, "check_net_services\n");
|
||||
|
|
Loading…
Reference in New Issue