master
sfeakes 2024-06-21 17:59:09 -05:00
parent 53f6e6874c
commit e93ad44028
13 changed files with 395 additions and 26 deletions

View File

@ -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
#

View File

@ -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

View File

@ -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");
}

View File

@ -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;

View File

@ -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&timesteps=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

152
hassio.c Normal file
View File

@ -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);
*/
}
}

6
hassio.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef HASSIO_H_
#define HASSIO_H_
void publish_mqtt_hassio_discover(struct mg_connection *nc);
#endif

View File

@ -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);

View File

@ -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.

View File

@ -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

View File

@ -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");

View File

@ -1,6 +1,6 @@
#ifndef SD_VERSION_H
#define SD_VERSION_H
#define SD_VERSION "1.2"
#define SD_VERSION "1.3"
#endif