285 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			285 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
#include <stdio.h>
 | 
						|
#include <stdarg.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
#ifdef USE_WIRINGPI
 | 
						|
  #include <wiringPi.h>
 | 
						|
#else
 | 
						|
  #include "GPIO_Pi.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#include "json_messages.h"
 | 
						|
#include "config.h"
 | 
						|
//#include "aq_programmer.h"
 | 
						|
#include "utils.h"
 | 
						|
//#include "web_server.h"
 | 
						|
 | 
						|
int build_sprinkler_cal_JSON(char* buffer, int size)
 | 
						|
{
 | 
						|
  int day;
 | 
						|
  int zone;
 | 
						|
  int length = build_sprinkler_JSON(buffer, size);
 | 
						|
 | 
						|
  length = length-1;
 | 
						|
 | 
						|
  for (zone=1; zone <= _sdconfig_.zones ; zone++)
 | 
						|
  {
 | 
						|
        length += sprintf(buffer+length,  ", \"z%d-runtime\" : %d, \"z%d-name\" : \"%s\" ", 
 | 
						|
                   //_sdconfig_.zonecfg[zone].zone, 
 | 
						|
                  //(digitalRead(_sdconfig_.zonecfg[zone].pin)==_sdconfig_.zonecfg[zone].on_state?"on":"off"),
 | 
						|
                   _sdconfig_.zonecfg[zone].zone,
 | 
						|
                   _sdconfig_.zonecfg[zone].default_runtime,
 | 
						|
                   _sdconfig_.zonecfg[zone].zone,
 | 
						|
                   _sdconfig_.zonecfg[zone].name);
 | 
						|
        //logMessage(LOG_DEBUG, "Zone %d, length %d limit %d\n",i,length,size);
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  for (day=0; day <= 6; day++) {
 | 
						|
    if (_sdconfig_.cron[day].hour >= 0 && _sdconfig_.cron[day].minute >= 0) {
 | 
						|
      length += sprintf(buffer+length, ", \"d%d-starttime\" : \"%.2d:%.2d\" ",day,_sdconfig_.cron[day].hour,_sdconfig_.cron[day].minute);
 | 
						|
      for (zone=0; zone < _sdconfig_.zones; zone ++) {
 | 
						|
        if (_sdconfig_.cron[day].zruntimes[zone] >= 0) {
 | 
						|
          length += sprintf(buffer+length, ", \"d%dz%d-runtime\" : %d",day,zone+1,_sdconfig_.cron[day].zruntimes[zone]);
 | 
						|
          //logMessage(LOG_DEBUG, "Zone %d, length %d limit %d\n",zone,length,size);
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  length += sprintf(buffer+length, "}");
 | 
						|
 | 
						|
  buffer[length] = '\0';
 | 
						|
  return strlen(buffer);
 | 
						|
}
 | 
						|
 | 
						|
int build_sprinkler_JSON(char* buffer, int size)
 | 
						|
{
 | 
						|
  int i;
 | 
						|
  memset(&buffer[0], 0, size);
 | 
						|
  int length = 0;
 | 
						|
  char status[50];
 | 
						|
 | 
						|
  if(_sdconfig_.currentZone.type!=zcNONE)
 | 
						|
    sprintf(status,"Active: Zone %d : time left %02d:%02d",_sdconfig_.currentZone.zone, _sdconfig_.currentZone.timeleft / 60, _sdconfig_.currentZone.timeleft % 60 );
 | 
						|
  else if (_sdconfig_.todayRainChance > 0 || _sdconfig_.todayRainTotal > 0)
 | 
						|
    sprintf(status, "Today:- Chance of rain: %d%%,  Rain total: %.2f\\\"", _sdconfig_.todayRainChance, _sdconfig_.todayRainTotal);
 | 
						|
  else
 | 
						|
    status[0] = '\0';
 | 
						|
 | 
						|
  length += sprintf(buffer+length,  "{ \"title\" : \"%s\",\"calendar\" : \"%s\", \"24hdelay\" : \"%s\", \"allz\" : \"%s\", \"zones\" : \"%d\", \"24hdelay-offtime\" : %li, \"status\" : \"%s\", \"raindelaychance\" : \"%d\", \"raindelaytotal1\" : \"%.1f\", \"raindelaytotal2\" : \"%.1f\", \"todaychanceofrain\" : \"%d\", \"todayraintotal\" : \"%.2f\"", 
 | 
						|
                                    _sdconfig_.name, 
 | 
						|
                                    _sdconfig_.calendar?"on":"off",  
 | 
						|
                                    _sdconfig_.delay24h?"on":"off", 
 | 
						|
                                    _sdconfig_.currentZone.type==zcALL?"on":"off", 
 | 
						|
                                    _sdconfig_.zones,
 | 
						|
                                    _sdconfig_.delay24h_time,
 | 
						|
                                    status,
 | 
						|
                                    _sdconfig_.precipChanceDelay,
 | 
						|
                                    _sdconfig_.precipInchDelay1day,
 | 
						|
                                    _sdconfig_.precipInchDelay2day,
 | 
						|
                                    _sdconfig_.todayRainChance,
 | 
						|
                                    _sdconfig_.todayRainTotal);
 | 
						|
      
 | 
						|
      for (i=1; i <= _sdconfig_.zones ; i++)
 | 
						|
      {
 | 
						|
        length += sprintf(buffer+length,  ", \"z%d\" : \"%s\" ", 
 | 
						|
                   _sdconfig_.zonecfg[i].zone, 
 | 
						|
                  (digitalRead(_sdconfig_.zonecfg[i].pin)==_sdconfig_.zonecfg[i].on_state?"on":"off"));
 | 
						|
                   //_sdconfig_.zonecfg[i].zone,
 | 
						|
                   //_sdconfig_.zonecfg[i].default_runtime,
 | 
						|
                   //_sdconfig_.zonecfg[i].zone,
 | 
						|
                   //_sdconfig_.zonecfg[i].name);
 | 
						|
        //logMessage(LOG_DEBUG, "Zone %d, length %d limit %d\n",i,length,size);
 | 
						|
      }
 | 
						|
      
 | 
						|
      length += sprintf(buffer+length, "}");
 | 
						|
 | 
						|
  buffer[length] = '\0';
 | 
						|
  return strlen(buffer);
 | 
						|
}
 | 
						|
 | 
						|
int build_advanced_sprinkler_JSON(char* buffer, int size)
 | 
						|
{
 | 
						|
  int i, day;
 | 
						|
  memset(&buffer[0], 0, size);
 | 
						|
  int length = 0;
 | 
						|
  bool cal = false;
 | 
						|
/*
 | 
						|
  length += sprintf(buffer+length,  "{ \"title\" : \"%s\",\"calendar\" : \"%s\", \"24hdelay\" : \"%s\", \"allz\" : \"%s\", \"#zones\" : %d, \"24hdelay-offtime\" : %li", 
 | 
						|
                                    _sdconfig_.name, 
 | 
						|
                                    _sdconfig_.calendar?"on":"off",  
 | 
						|
                                    _sdconfig_.delay24h?"on":"off", 
 | 
						|
                                    _sdconfig_.currentZone.type==zcALL?"on":"off", 
 | 
						|
                                    _sdconfig_.zones,
 | 
						|
                                    _sdconfig_.delay24h_time);
 | 
						|
*/
 | 
						|
  length += sprintf(buffer+length,  "{ \"title\" : \"%s\",\"calendar\" : \"%s\", \"24hdelay\" : \"%s\", \"allz\" : \"%s\", \"zones\" : \"%d\", \"24hdelay-offtime\" : %li, \"raindelaychance\" : \"%d\", \"raindelaytotal1\" : \"%.1f\", \"raindelaytotal2\" : \"%.1f\", \"todaychanceofrain\" : \"%d\", \"todayraintotal\" : \"%.2f\"", 
 | 
						|
                                    _sdconfig_.name, 
 | 
						|
                                    _sdconfig_.calendar?"on":"off",  
 | 
						|
                                    _sdconfig_.delay24h?"on":"off", 
 | 
						|
                                    _sdconfig_.currentZone.type==zcALL?"on":"off", 
 | 
						|
                                    _sdconfig_.zones,
 | 
						|
                                    _sdconfig_.delay24h_time,
 | 
						|
                                    _sdconfig_.precipChanceDelay,
 | 
						|
                                    _sdconfig_.precipInchDelay1day,
 | 
						|
                                    _sdconfig_.precipInchDelay2day,
 | 
						|
                                    _sdconfig_.todayRainChance,
 | 
						|
                                    _sdconfig_.todayRainTotal);
 | 
						|
  
 | 
						|
  length += sprintf(buffer+length,  ", \"zones\": {");
 | 
						|
  for (i=1; i <= _sdconfig_.zones ; i++)
 | 
						|
  {
 | 
						|
    length += sprintf(buffer+length,  "\"zone %d\": {\"number\": %d, \"name\": \"%s\", \"state\": \"%s\", \"runtime\": %d },",
 | 
						|
                                      _sdconfig_.zonecfg[i].zone,
 | 
						|
                                      _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
 | 
						|
                                      );
 | 
						|
  }
 | 
						|
  if (_sdconfig_.currentZone.type != zcNONE)
 | 
						|
    length += sprintf(buffer+length,  "\"active\": {\"zone\": %d, \"name\": \"%s\"},",_sdconfig_.currentZone.zone, _sdconfig_.zonecfg[_sdconfig_.currentZone.zone].name);
 | 
						|
 | 
						|
  length -= 1;
 | 
						|
  length += sprintf( buffer+length ,  "}, \"calendar\": {" );
 | 
						|
 | 
						|
  for (day=0; day <= 6; day++) {
 | 
						|
    if (_sdconfig_.cron[day].hour >= 0 && _sdconfig_.cron[day].minute >= 0) {
 | 
						|
      cal = true;
 | 
						|
      length += sprintf(buffer+length, "\"day %d\" : { \"start time\" : \"%.2d:%.2d\", ",day,_sdconfig_.cron[day].hour,_sdconfig_.cron[day].minute);
 | 
						|
      for (i=1; i < _sdconfig_.zones; i ++) {
 | 
						|
        if (_sdconfig_.cron[day].zruntimes[i] >= 0) {
 | 
						|
          length += sprintf(buffer+length, "\"Zone %d\" : %d,",i+1,_sdconfig_.cron[day].zruntimes[i]);
 | 
						|
          //logMessage(LOG_DEBUG, "Zone %d, length %d limit %d\n",i+1,length,size);
 | 
						|
        }
 | 
						|
      }
 | 
						|
      length -= 1;
 | 
						|
      length += sprintf(buffer+length,  "},");
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (cal) {
 | 
						|
    length -= 1;
 | 
						|
  }
 | 
						|
  length += sprintf(buffer+length, "}}");
 | 
						|
  
 | 
						|
 | 
						|
  buffer[length] = '\0';
 | 
						|
  return strlen(buffer);
 | 
						|
}
 | 
						|
 | 
						|
int build_homebridge_sprinkler_JSON(char* buffer, int size)
 | 
						|
{
 | 
						|
  int i;
 | 
						|
  memset(&buffer[0], 0, size);
 | 
						|
  int length = 0;
 | 
						|
 | 
						|
  length += sprintf(buffer+length,  "{ \"title\" : \"%s\", ", _sdconfig_.name);
 | 
						|
 | 
						|
  length += sprintf(buffer+length,  " \"devices\": [");
 | 
						|
  for (i=(_sdconfig_.master_valve?0:1); i <= _sdconfig_.zones ; i++)
 | 
						|
  {
 | 
						|
    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);
 | 
						|
  }
 | 
						|
  
 | 
						|
  length += sprintf(buffer+length,  "{\"type\" : \"zone\", \"zone\": %d, \"name\": \"Cycle all zones\", \"state\": \"%s\", \"duration\": 0, \"id\" : \"cycleallzones\" },",
 | 
						|
                                    _sdconfig_.zones+1,
 | 
						|
                                    _sdconfig_.currentZone.type==zcALL?"on":"off");
 | 
						|
  length += sprintf(buffer+length,  "{\"type\" : \"switch\", \"zone\": -1, \"name\": \"24h Rain Delay\", \"state\": \"%s\", \"duration\": 0, \"id\" : \"24hdelay\" },",
 | 
						|
                                    _sdconfig_.delay24h?"on":"off");
 | 
						|
  length += sprintf(buffer+length,  "{\"type\" : \"switch\", \"zone\": -1, \"name\": \"Run on calendar schedule\", \"state\": \"%s\", \"duration\": 0, \"id\" : \"calendar\" }",
 | 
						|
                                    _sdconfig_.calendar?"on":"off");
 | 
						|
 | 
						|
 | 
						|
  length += sprintf(buffer+length, "]}");
 | 
						|
 | 
						|
  buffer[length] = '\0';
 | 
						|
  return strlen(buffer);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
int build_dz_mqtt_status_JSON(char* buffer, int size, int idx, int nvalue, float tvalue)
 | 
						|
{
 | 
						|
  memset(&buffer[0], 0, size);
 | 
						|
  int length = 0;
 | 
						|
 | 
						|
  if (tvalue == TEMP_UNKNOWN) {
 | 
						|
    length = sprintf(buffer, "{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"\"}", idx, nvalue);
 | 
						|
  } else {
 | 
						|
    length = sprintf(buffer, "{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"%.2f\"}", idx, nvalue, tvalue);
 | 
						|
  }
 | 
						|
 | 
						|
  buffer[length] = '\0';
 | 
						|
  return strlen(buffer);
 | 
						|
}
 | 
						|
 | 
						|
int build_dz_status_message_JSON(char* buffer, int size, int idx, int nvalue, char *svalue)
 | 
						|
{
 | 
						|
  memset(&buffer[0], 0, size);
 | 
						|
  int length = 0;
 | 
						|
  //json.htm?type=command¶m=udevice&idx=IDX&nvalue=LEVEL&svalue=TEXT
 | 
						|
 | 
						|
  length = sprintf(buffer, "{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"%s\"}", idx, nvalue, svalue);
 | 
						|
 | 
						|
  buffer[length] = '\0';
 | 
						|
  return strlen(buffer);
 | 
						|
}
 | 
						|
 | 
						|
bool parseJSONmqttrequest(const char *str, size_t len, int *idx, int *nvalue, char *svalue, const char *svalue_str) {
 | 
						|
  int i = 0;
 | 
						|
  int found = 0;
 | 
						|
  
 | 
						|
  svalue[0] = '\0';
 | 
						|
 | 
						|
  for (i = 0; i < len && str[i] != '\0'; i++) {
 | 
						|
    if (str[i] == '"') {
 | 
						|
      if (strncmp("\"idx\"", (char *)&str[i], 5) == 0) {
 | 
						|
        i = i + 5;
 | 
						|
        for (; str[i] != ',' && str[i] != '\0'; i++) {
 | 
						|
          if (str[i] == ':') {
 | 
						|
            *idx = atoi(&str[i + 1]);
 | 
						|
            found++;
 | 
						|
          }
 | 
						|
        }
 | 
						|
        //if (*idx == 45) 
 | 
						|
        //  printf("%s\n",str);
 | 
						|
      } else if (strncmp("\"nvalue\"", (char *)&str[i], 8) == 0) {
 | 
						|
        i = i + 8;
 | 
						|
        for (; str[i] != ',' && str[i] != '\0'; i++) {
 | 
						|
          if (str[i] == ':') {
 | 
						|
            *nvalue = atoi(&str[i + 1]);
 | 
						|
            found++;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      //} else if (strncmp("\"svalue1\"", (char *)&str[i], 9) == 0) {
 | 
						|
      } else if (strncmp(svalue_str, (char *)&str[i], 9) == 0) {
 | 
						|
        i = i + 9;
 | 
						|
        for (; str[i] != ',' && str[i] != '\0'; i++) {
 | 
						|
          if (str[i] == ':') {
 | 
						|
            while(str[i] == ':' || str[i] == ' ' || str[i] == '"' || str[i] == '\'') i++;
 | 
						|
            int j=i+1;
 | 
						|
            while(str[j] != '"' && str[j] != '\'' && str[j] != ',' && str[j] != '}') j++;
 | 
						|
            strncpy(svalue, &str[i], ((j-i)>DZ_SVALUE_LEN?DZ_SVALUE_LEN:(j-i)));
 | 
						|
            svalue[((j-i)>DZ_SVALUE_LEN?DZ_SVALUE_LEN:(j-i))] = '\0'; // Simply force the last termination
 | 
						|
            found++;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      } 
 | 
						|
      if (found >= 4) {
 | 
						|
        return true;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  // Just incase svalue is not found, we really don;t care for most devices.
 | 
						|
  if (found >= 2) {
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
  return false;
 | 
						|
}
 |