Browse Source

Pass safe buffer to api callbacks

fastled
Xose Pérez 7 years ago
parent
commit
bbac070c09
8 changed files with 84 additions and 62 deletions
  1. +1
    -1
      code/espurna/config/general.h
  2. +1
    -1
      code/espurna/config/prototypes.h
  3. +26
    -17
      code/espurna/dht.ino
  4. +13
    -9
      code/espurna/ds18b20.ino
  5. +27
    -20
      code/espurna/emon.ino
  6. +6
    -9
      code/espurna/pow.ino
  7. +2
    -2
      code/espurna/relay.ino
  8. +8
    -3
      code/espurna/web.ino

+ 1
- 1
code/espurna/config/general.h View File

@ -81,7 +81,7 @@
#define MQTT_MESSAGE_EVENT 2
// Custom get and set postfixes
// Use something like "/status" or "/set", with trailing slash
// Use something like "/status" or "/set", with leading slash
#define MQTT_USE_GETTER ""
#define MQTT_USE_SETTER ""


+ 1
- 1
code/espurna/config/prototypes.h View File

@ -5,7 +5,7 @@
#include <AsyncMqttClient.h>
#include <functional>
typedef std::function<char *(void)> apiGetCallbackFunction;
typedef std::function<void(char *, size_t)> apiGetCallbackFunction;
typedef std::function<void(const char *)> apiPutCallbackFunction;
void apiRegister(const char * url, const char * key, apiGetCallbackFunction getFn, apiPutCallbackFunction putFn = NULL);
void mqttRegister(void (*callback)(unsigned int, const char *, const char *));


+ 26
- 17
code/espurna/dht.ino View File

@ -13,25 +13,29 @@ Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
DHT dht(DHT_PIN, DHT_TYPE, DHT_TIMING);
char dhtTemperature[6];
char dhtHumidity[6];
double _dhtTemperature = 0;
unsigned int _dhtHumidity = 0;
// -----------------------------------------------------------------------------
// Values
// -----------------------------------------------------------------------------
char * getDHTTemperature() {
return dhtTemperature;
double getDHTTemperature() {
return _dhtTemperature;
}
char * getDHTHumidity() {
return dhtHumidity;
unsigned int getDHTHumidity() {
return _dhtHumidity;
}
void dhtSetup() {
dht.begin();
apiRegister("/api/temperature", "temperature", getDHTTemperature);
apiRegister("/api/humidity", "humidity", getDHTHumidity);
apiRegister("/api/temperature", "temperature", [](char * buffer, size_t len) {
dtostrf(_dhtTemperature, len-1, 1, buffer);
});
apiRegister("/api/humidity", "humidity", [](char * buffer, size_t len) {
snprintf(buffer, len, "%d", _dhtHumidity);
});
}
void dhtLoop() {
@ -52,25 +56,30 @@ void dhtLoop() {
} else {
dtostrf(t, 4, 1, dhtTemperature);
itoa((int) h, dhtHumidity, 10);
_dhtTemperature = t;
_dhtHumidity = h;
DEBUG_MSG("[DHT] Temperature: %s\n", dhtTemperature);
DEBUG_MSG("[DHT] Humidity: %s\n", dhtHumidity);
char temperature[6];
char humidity[6];
dtostrf(t, 4, 1, temperature);
itoa((unsigned int) h, humidity, 10);
DEBUG_MSG("[DHT] Temperature: %s\n", temperature);
DEBUG_MSG("[DHT] Humidity: %s\n", humidity);
// Send MQTT messages
mqttSend(getSetting("dhtTmpTopic", DHT_TEMPERATURE_TOPIC).c_str(), dhtTemperature);
mqttSend(getSetting("dhtHumTopic", DHT_HUMIDITY_TOPIC).c_str(), dhtHumidity);
mqttSend(getSetting("dhtTmpTopic", DHT_TEMPERATURE_TOPIC).c_str(), temperature);
mqttSend(getSetting("dhtHumTopic", DHT_HUMIDITY_TOPIC).c_str(), humidity);
// Send to Domoticz
#if ENABLE_DOMOTICZ
domoticzSend("dczTmpIdx", dhtTemperature);
domoticzSend("dczHumIdx", dhtHumidity);
domoticzSend("dczTmpIdx", temperature);
domoticzSend("dczHumIdx", humidity);
#endif
// Update websocket clients
char buffer[100];
sprintf_P(buffer, PSTR("{\"dhtVisible\": 1, \"dhtTmp\": %s, \"dhtHum\": %s}"), dhtTemperature, dhtHumidity);
sprintf_P(buffer, PSTR("{\"dhtVisible\": 1, \"dhtTmp\": %s, \"dhtHum\": %s}"), temperature, humidity);
wsSend(buffer);
}


+ 13
- 9
code/espurna/ds18b20.ino View File

@ -14,19 +14,21 @@ Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
OneWire oneWire(DS_PIN);
DallasTemperature ds18b20(&oneWire);
char dsTemperature[6];
double _dsTemperature = 0;
// -----------------------------------------------------------------------------
// DS18B20
// -----------------------------------------------------------------------------
char * getDSTemperature() {
return dsTemperature;
double getDSTemperature() {
return _dsTemperature;
}
void dsSetup() {
ds18b20.begin();
apiRegister("/api/temperature", "temperature", getDSTemperature);
apiRegister("/api/temperature", "temperature", [](char * buffer, size_t len) {
dtostrf(_dsTemperature, len-1, 1, buffer);
});
}
void dsLoop() {
@ -49,21 +51,23 @@ void dsLoop() {
} else {
dtostrf(t, 4, 1, dsTemperature);
_dsTemperature = t;
DEBUG_MSG("[DS18B20] Temperature: %s\n", dsTemperature);
char temperature[6];
dtostrf(t, 5, 1, temperature);
DEBUG_MSG("[DS18B20] Temperature: %s\n", temperature);
// Send MQTT messages
mqttSend(getSetting("dsTmpTopic", DS_TEMPERATURE_TOPIC).c_str(), dsTemperature);
mqttSend(getSetting("dsTmpTopic", DS_TEMPERATURE_TOPIC).c_str(), temperature);
// Send to Domoticz
#if ENABLE_DOMOTICZ
domoticzSend("dczTmpIdx", dsTemperature);
domoticzSend("dczTmpIdx", temperature);
#endif
// Update websocket clients
char buffer[100];
sprintf_P(buffer, PSTR("{\"dsVisible\": 1, \"dsTmp\": %s}"), dsTemperature);
sprintf_P(buffer, PSTR("{\"dsVisible\": 1, \"dsTmp\": %s}"), temperature);
wsSend(buffer);
}


+ 27
- 20
code/espurna/emon.ino View File

@ -11,8 +11,8 @@ Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
#include <EmonLiteESP.h>
EmonLiteESP emon;
double current;
char power[8];
double _current = 0;
unsigned int _power = 0;
// -----------------------------------------------------------------------------
// EMON
@ -22,12 +22,12 @@ void setCurrentRatio(float value) {
emon.setCurrentRatio(value);
}
char * getPower() {
return power;
unsigned int getPower() {
return _power;
}
double getCurrent() {
return current;
return _current;
}
unsigned int currentCallback() {
@ -53,7 +53,9 @@ void powerMonitorSetup() {
);
emon.setPrecision(EMON_CURRENT_PRECISION);
apiRegister("/api/power", "power", getPower);
apiRegister("/api/power", "power", [](char * buffer, size_t len) {
snprintf(buffer, len, "%d", _power);
});
}
@ -77,41 +79,46 @@ void powerMonitorLoop() {
// Safety check: do not read current if relay is OFF
if (!relayStatus(0)) {
current = 0;
_current = 0;
} else {
current = emon.getCurrent(EMON_SAMPLES);
current -= EMON_CURRENT_OFFSET;
if (current < 0) current = 0;
_current = emon.getCurrent(EMON_SAMPLES);
_current -= EMON_CURRENT_OFFSET;
if (_current < 0) _current = 0;
}
if (measurements == 0) {
max = min = current;
max = min = _current;
} else {
if (current > max) max = current;
if (current < min) min = current;
if (_current > max) max = _current;
if (_current < min) min = _current;
}
sum += current;
sum += _current;
++measurements;
float mainsVoltage = getSetting("emonMains", EMON_MAINS_VOLTAGE).toFloat();
//DEBUG_MSG("[ENERGY] Power now: %dW\n", int(current * mainsVoltage));
//DEBUG_MSG("[ENERGY] Power now: %dW\n", int(_current * mainsVoltage));
// Update websocket clients
char text[20];
sprintf_P(text, PSTR("{\"emonPower\": %d}"), int(current * mainsVoltage));
sprintf_P(text, PSTR("{\"emonPower\": %d}"), int(_current * mainsVoltage));
wsSend(text);
// Send MQTT messages averaged every EMON_MEASUREMENTS
if (measurements == EMON_MEASUREMENTS) {
double p = (sum - max - min) * mainsVoltage / (measurements - 2);
sprintf(power, "%d", int(p));
_power = (int) ((sum - max - min) * mainsVoltage / (measurements - 2));
sum = 0;
measurements = 0;
char power[6];
snprintf(power, "%d", 6, _power);
mqttSend(getSetting("emonPowerTopic", EMON_POWER_TOPIC).c_str(), power);
#if ENABLE_DOMOTICZ
domoticzSend("dczPowIdx", power);
#endif
sum = 0;
measurements = 0;
}
next_measurement += EMON_INTERVAL;


+ 6
- 9
code/espurna/pow.ino View File

@ -144,17 +144,14 @@ void powSetup() {
powAttachInterrupts();
#endif
apiRegister("/api/power", "power", []() {
sprintf(apibuffer, "%d", getActivePower());
return apibuffer;
apiRegister("/api/power", "power", [](char * buffer, size_t len) {
snprintf(buffer, len, "%d", getActivePower());
});
apiRegister("/api/current", "current", []() {
dtostrf(getCurrent(), 5, 2, apibuffer);
return apibuffer;
apiRegister("/api/current", "current", [](char * buffer, size_t len) {
dtostrf(getCurrent(), len-1, 2, buffer);
});
apiRegister("/api/voltage", "voltage", []() {
sprintf(apibuffer, "%d", getVoltage());
return apibuffer;
apiRegister("/api/voltage", "voltage", [](char * buffer, size_t len) {
snprintf(buffer, len, "%d", getVoltage());
});
}


+ 2
- 2
code/espurna/relay.ino View File

@ -181,8 +181,8 @@ void relaySetupAPI() {
sprintf(key, "relay%d", relayID);
apiRegister(url, key,
[relayID]() {
return (char *) (relayStatus(relayID) ? "1" : "0");
[relayID](char * buffer, size_t len) {
snprintf(buffer, "%d", len, relayStatus(relayID) ? 1 : 0);
},
[relayID](const char * payload) {
unsigned int value = payload[0] - '0';


+ 8
- 3
code/espurna/web.ino View File

@ -535,14 +535,19 @@ ArRequestHandlerFunction _bindAPI(unsigned int apiID) {
}
}
char * value = strdup((api.getFn)());
char value[10];
(api.getFn)(value, 10);
// jump over leading spaces
char *p = value;
while ((unsigned char) *p == ' ') ++p;
if (asJson) {
char buffer[64];
sprintf_P(buffer, PSTR("{ \"%s\": %s }"), api.key, value);
sprintf_P(buffer, PSTR("{ \"%s\": %s }"), api.key, p);
request->send(200, "application/json", buffer);
} else {
request->send(200, "text/plain", value);
request->send(200, "text/plain", p);
}
};


Loading…
Cancel
Save