mirror of
https://github.com/openshwprojects/OpenBK7231T_App.git
synced 2026-02-10 07:05:36 +00:00
973 lines
32 KiB
C
973 lines
32 KiB
C
#include "../new_common.h"
|
|
#include "http_fns.h"
|
|
#include "../new_pins.h"
|
|
#include "../new_cfg.h"
|
|
#include "../ota/ota.h"
|
|
// Commands register, execution API and cmd tokenizer
|
|
#include "../cmnds/cmd_public.h"
|
|
#include "../driver/drv_tuyaMCU.h"
|
|
#include "../driver/drv_public.h"
|
|
#include "../driver/drv_battery.h"
|
|
#include "../hal/hal_wifi.h"
|
|
#include "../hal/hal_pins.h"
|
|
#include "../hal/hal_flashConfig.h"
|
|
#include "../logging/logging.h"
|
|
#include "../devicegroups/deviceGroups_public.h"
|
|
#include "../mqtt/new_mqtt.h"
|
|
#include "hass.h"
|
|
#include "../cJSON/cJSON.h"
|
|
#include <time.h>
|
|
#include "../driver/drv_ntp.h"
|
|
#include "../driver/drv_local.h"
|
|
|
|
void JSON_PrintKeyValue_String(void* request, jsonCb_t printer, const char *key, const char *value, bool bComma) {
|
|
printer(request, "\"%s\":\"%s\"", key, value);
|
|
if (bComma) {
|
|
printer(request, ",");
|
|
}
|
|
}
|
|
void JSON_PrintKeyValue_Int(void* request, jsonCb_t printer, const char *key, int value, bool bComma) {
|
|
printer(request, "\"%s\":%i", key, value);
|
|
if (bComma) {
|
|
printer(request, ",");
|
|
}
|
|
}
|
|
void JSON_PrintKeyValue_Float(void* request, jsonCb_t printer, const char *key, float value, bool bComma) {
|
|
printer(request, "\"%s\":%f", key, value);
|
|
if (bComma) {
|
|
printer(request, ",");
|
|
}
|
|
}
|
|
|
|
static int http_tasmota_json_Dimmer(void* request, jsonCb_t printer) {
|
|
int dimmer;
|
|
dimmer = LED_GetDimmer();
|
|
JSON_PrintKeyValue_Int(request, printer, "Dimmer", dimmer, false);
|
|
return 0;
|
|
}
|
|
static int http_tasmota_json_CT(void* request, jsonCb_t printer) {
|
|
int temperature;
|
|
// 154 to 500 range
|
|
temperature = LED_GetTemperature();
|
|
// Temperature
|
|
JSON_PrintKeyValue_Int(request, printer, "CT", temperature, false);
|
|
return 0;
|
|
}
|
|
// https://tasmota.github.io/docs/Commands/#with-mqtt
|
|
/*
|
|
http://<ip>/cm?cmnd=Power%20TOGGLE
|
|
http://<ip>/cm?cmnd=Power%20On
|
|
http://<ip>/cm?cmnd=Power%20off
|
|
http://<ip>/cm?user=admin&password=joker&cmnd=Power%20Toggle
|
|
*/
|
|
// https://www.elektroda.com/rtvforum/viewtopic.php?p=19330027#19330027
|
|
// Web browser sends: GET /cm?cmnd=POWER1
|
|
// System responds with state
|
|
static int http_tasmota_json_power(void* request, jsonCb_t printer) {
|
|
int numRelays;
|
|
int numPWMs;
|
|
int i;
|
|
int lastRelayState;
|
|
bool bRelayIndexingStartsWithZero;
|
|
int relayIndexingOffset;
|
|
char buff32[32];
|
|
|
|
bRelayIndexingStartsWithZero = CHANNEL_HasChannelPinWithRoleOrRole(0, IOR_Relay, IOR_Relay_n);
|
|
if (bRelayIndexingStartsWithZero) {
|
|
relayIndexingOffset = 0;
|
|
}
|
|
else {
|
|
relayIndexingOffset = 1;
|
|
}
|
|
|
|
// try to return status
|
|
numPWMs = PIN_CountPinsWithRoleOrRole(IOR_PWM, IOR_PWM_n);
|
|
numRelays = 0;
|
|
|
|
// LED driver (if has PWMs)
|
|
if (LED_IsLEDRunning()) {
|
|
http_tasmota_json_Dimmer(request, printer);
|
|
printer(request, ",");
|
|
// Temperature
|
|
JSON_PrintKeyValue_String(request, printer, "Fade", "OFF", true);
|
|
JSON_PrintKeyValue_Int(request, printer, "Speed", 1, true);
|
|
JSON_PrintKeyValue_String(request, printer, "LedTable", "ON", true);
|
|
if (LED_IsLedDriverChipRunning() || numPWMs >= 3) {
|
|
/*
|
|
{
|
|
POWER: "OFF",
|
|
Dimmer: 100,
|
|
Color: "255,0,157",
|
|
HSBColor: "323,100,100",
|
|
Channel: [
|
|
100,
|
|
0,
|
|
62
|
|
]
|
|
}*/
|
|
// Eg: Color: "255,0,157",
|
|
byte rgbcw[5];
|
|
int hsv[3];
|
|
byte channels[5];
|
|
|
|
LED_GetFinalRGBCW(rgbcw);
|
|
LED_GetFinalHSV(hsv);
|
|
LED_GetFinalChannels100(channels);
|
|
|
|
// it looks like they include C and W in color
|
|
if (LED_IsLedDriverChipRunning() || numPWMs == 5) {
|
|
sprintf(buff32, "%i,%i,%i,%i,%i",(int)rgbcw[0], (int)rgbcw[1], (int)rgbcw[2], (int)rgbcw[3], (int)rgbcw[4]);
|
|
}
|
|
else {
|
|
sprintf(buff32,"%i,%i,%i", (int)rgbcw[0], (int)rgbcw[1], (int)rgbcw[2]);
|
|
}
|
|
JSON_PrintKeyValue_String(request, printer, "Color", buff32, true);
|
|
sprintf(buff32, "%i,%i,%i", (int)hsv[0], (int)hsv[1], (int)hsv[2]);
|
|
JSON_PrintKeyValue_String(request, printer, "HSBColor", buff32, true);
|
|
printer(request, "\"Channel\":[%i,%i,%i],", (int)channels[0], (int)channels[1], (int)channels[2]);
|
|
|
|
}
|
|
if (LED_IsLedDriverChipRunning() || numPWMs == 5 || numPWMs == 2) {
|
|
http_tasmota_json_CT(request, printer);
|
|
printer(request, ",");
|
|
}
|
|
if (LED_GetEnableAll() == 0) {
|
|
JSON_PrintKeyValue_String(request, printer, "POWER", "OFF", false);
|
|
}
|
|
else {
|
|
JSON_PrintKeyValue_String(request, printer, "POWER", "ON", false);
|
|
}
|
|
}
|
|
else {
|
|
// relays driver
|
|
for (i = 0; i < CHANNEL_MAX; i++) {
|
|
if (h_isChannelRelay(i) || CHANNEL_GetType(i) == ChType_Toggle) {
|
|
numRelays++;
|
|
lastRelayState = CHANNEL_Get(i);
|
|
}
|
|
}
|
|
if (numRelays == 0) {
|
|
JSON_PrintKeyValue_String(request, printer, "POWER", "ON", false);
|
|
}
|
|
else if (numRelays == 1) {
|
|
if (lastRelayState) {
|
|
JSON_PrintKeyValue_String(request, printer, "POWER", "ON", false);
|
|
}
|
|
else {
|
|
JSON_PrintKeyValue_String(request, printer, "POWER", "OFF", false);
|
|
}
|
|
}
|
|
else {
|
|
int c_posted = 0;
|
|
for (i = 0; i < CHANNEL_MAX; i++) {
|
|
if (h_isChannelRelay(i) || CHANNEL_GetType(i) == ChType_Toggle) {
|
|
int indexStartingFrom1;
|
|
|
|
if (bRelayIndexingStartsWithZero) {
|
|
indexStartingFrom1 = i + 1;
|
|
}
|
|
else {
|
|
indexStartingFrom1 = i;
|
|
}
|
|
lastRelayState = CHANNEL_Get(i);
|
|
if (c_posted) {
|
|
printer(request, ",");
|
|
}
|
|
sprintf(buff32, "POWER%i", indexStartingFrom1);
|
|
if (lastRelayState) {
|
|
JSON_PrintKeyValue_String(request, printer, buff32, "ON", false);
|
|
}
|
|
else {
|
|
JSON_PrintKeyValue_String(request, printer, buff32, "OFF", false);
|
|
}
|
|
c_posted++;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
/*
|
|
{"StatusSNS":{"Time":"2022-07-30T10:11:26","ENERGY":{"TotalStartTime":"2022-05-12T10:56:31","Total":0.003,"Yesterday":0.003,"Today":0.000,"Power": 0,"ApparentPower": 0,"ReactivePower": 0,"Factor":0.00,"Voltage":236,"Current":0.000}}}
|
|
*/
|
|
|
|
|
|
static int http_tasmota_json_ENERGY(void* request, jsonCb_t printer) {
|
|
float power, factor, voltage, current, batterypercentage = 0;
|
|
float energy, energy_hour;
|
|
|
|
factor = 0; // TODO
|
|
voltage = DRV_GetReading(OBK_VOLTAGE);
|
|
current = DRV_GetReading(OBK_CURRENT);
|
|
power = DRV_GetReading(OBK_POWER);
|
|
energy = DRV_GetReading(OBK_CONSUMPTION_TOTAL);
|
|
energy_hour = DRV_GetReading(OBK_CONSUMPTION_LAST_HOUR);
|
|
|
|
if (DRV_IsMeasuringBattery()) {
|
|
#if defined(PLATFORM_BEKEN)
|
|
voltage = Battery_lastreading(OBK_BATT_VOLTAGE) / 1000.00;
|
|
batterypercentage = Battery_lastreading(OBK_BATT_LEVEL);
|
|
#endif
|
|
printer(request, "{");
|
|
printer(request, "\"Voltage\":%.4f,", voltage);
|
|
printer(request, "\"Batterypercentage\":%.0f", batterypercentage);
|
|
// close ENERGY block
|
|
printer(request, "}");
|
|
}
|
|
else {
|
|
// following check will clear NaN values
|
|
if (OBK_IS_NAN(energy)) {
|
|
energy = 0;
|
|
}
|
|
if (OBK_IS_NAN(energy_hour)) {
|
|
energy_hour = 0;
|
|
}
|
|
printer(request, "{");
|
|
printer(request, "\"Power\": %f,", power);
|
|
printer(request, "\"ApparentPower\": 0,");
|
|
printer(request, "\"ReactivePower\": 0,");
|
|
printer(request, "\"Factor\":%f,", factor);
|
|
printer(request, "\"Voltage\":%f,", voltage);
|
|
printer(request, "\"Current\":%f,", current);
|
|
printer(request, "\"ConsumptionTotal\":%f,", energy);
|
|
printer(request, "\"ConsumptionLastHour\":%f", energy_hour);
|
|
// close ENERGY block
|
|
printer(request, "}");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// Topic: tele/tasmota_48E7F3/SENSOR at 3:06 AM:
|
|
// Sample:
|
|
/*
|
|
{
|
|
"Time": "2022-12-30T03:06:36",
|
|
"ENERGY": {
|
|
"TotalStartTime": "2022-05-12T10:56:31",
|
|
"Total": 0.007,
|
|
"Yesterday": 0,
|
|
"Today": 0,
|
|
"Period": 0,
|
|
"Power": 0,
|
|
"ApparentPower": 0,
|
|
"ReactivePower": 0,
|
|
"Factor": 0,
|
|
"Voltage": 241,
|
|
"Current": 0
|
|
}
|
|
}
|
|
*/
|
|
static int http_tasmota_json_SENSOR(void* request, jsonCb_t printer) {
|
|
float temperature, humidity;
|
|
int channel_1, channel_2, g_pin_1 = 0;
|
|
printer(request, ",");
|
|
if (DRV_IsRunning("SHT3X")) {
|
|
g_pin_1 = PIN_FindPinIndexForRole(IOR_SHT3X_DAT, g_pin_1);
|
|
channel_1 = g_cfg.pins.channels[g_pin_1];
|
|
channel_2 = g_cfg.pins.channels2[g_pin_1];
|
|
|
|
temperature = CHANNEL_GetFloat(channel_1) / 10.0f;
|
|
humidity = CHANNEL_GetFloat(channel_2);
|
|
|
|
// writer header
|
|
printer(request, "\"SHT3X\":");
|
|
// following check will clear NaN values
|
|
printer(request, "{");
|
|
printer(request, "\"Temperature\": %.1f,", temperature);
|
|
printer(request, "\"Humidity\": %.0f", humidity);
|
|
// close ENERGY block
|
|
printer(request, "},");
|
|
}
|
|
if (DRV_IsRunning("CHT8305")) {
|
|
g_pin_1 = PIN_FindPinIndexForRole(IOR_CHT8305_DAT, g_pin_1);
|
|
channel_1 = g_cfg.pins.channels[g_pin_1];
|
|
channel_2 = g_cfg.pins.channels2[g_pin_1];
|
|
|
|
temperature = CHANNEL_GetFloat(channel_1) / 10.0f;
|
|
humidity = CHANNEL_GetFloat(channel_2);
|
|
|
|
// writer header
|
|
printer(request, "\"CHT8305\":");
|
|
// following check will clear NaN values
|
|
printer(request, "{");
|
|
printer(request, "\"Temperature\": %.1f,", temperature);
|
|
printer(request, "\"Humidity\": %.0f", humidity);
|
|
// close ENERGY block
|
|
printer(request, "},");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int http_tasmota_json_status_SNS(void* request, jsonCb_t printer, bool bAppendHeader) {
|
|
char buff[20];
|
|
|
|
if (bAppendHeader) {
|
|
printer(request, "\"StatusSNS\":");
|
|
}
|
|
printer(request, "{");
|
|
|
|
time_t localTime = (time_t)NTP_GetCurrentTime();
|
|
strftime(buff, sizeof(buff), "%Y-%m-%dT%H:%M:%S", localtime(&localTime));
|
|
JSON_PrintKeyValue_String(request, printer, "Time", buff, false);
|
|
|
|
#ifndef OBK_DISABLE_ALL_DRIVERS
|
|
|
|
if (DRV_IsMeasuringPower() || DRV_IsMeasuringBattery()) {
|
|
|
|
// begin ENERGY block
|
|
printer(request, ",");
|
|
printer(request, "\"ENERGY\":");
|
|
http_tasmota_json_ENERGY(request, printer);
|
|
}
|
|
if (DRV_IsSensor()) {
|
|
http_tasmota_json_SENSOR(request, printer);
|
|
JSON_PrintKeyValue_String(request, printer, "TempUnit", "C", false);
|
|
}
|
|
#endif
|
|
|
|
printer(request, "}");
|
|
|
|
return 0;
|
|
}
|
|
|
|
#ifdef PLATFORM_XR809
|
|
//XR809 does not support drivers but its build script compiles many drivers including ntp.
|
|
|
|
#else
|
|
#ifndef ENABLE_BASIC_DRIVERS
|
|
unsigned int NTP_GetCurrentTime() {
|
|
return 0;
|
|
}
|
|
unsigned int NTP_GetCurrentTimeWithoutOffset() {
|
|
return 0;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
// Topic: tele/tasmota_48E7F3/STATE
|
|
// Sample:
|
|
/*
|
|
{
|
|
"Time": "2022-12-30T03:06:36",
|
|
"Uptime": "0T06:16:14",
|
|
"UptimeSec": 22574,
|
|
"Heap": 26,
|
|
"SleepMode": "Dynamic",
|
|
"Sleep": 50,
|
|
"LoadAvg": 19,
|
|
"MqttCount": 1,
|
|
"POWER": "ON",
|
|
"Wifi": {
|
|
"AP": 1,
|
|
"SSId": "ASUS_25G_WIFI",
|
|
"BSSId": "32:21:BA:10:F6:6D",
|
|
"Channel": 3,
|
|
"Mode": "11n",
|
|
"RSSI": 62,
|
|
"Signal": -69,
|
|
"LinkCount": 1,
|
|
"Downtime": "0T00:00:04"
|
|
}
|
|
}
|
|
*/
|
|
|
|
void format_time(int total_seconds, char* output, int outLen) {
|
|
int days = total_seconds / 86400;
|
|
int hours = (total_seconds / 3600) % 24;
|
|
int minutes = (total_seconds / 60) % 60;
|
|
int seconds = total_seconds % 60;
|
|
|
|
snprintf(output, outLen, "%dT%02d:%02d:%02d", days, hours, minutes, seconds);
|
|
}
|
|
|
|
static int http_tasmota_json_status_STS(void* request, jsonCb_t printer, bool bAppendHeader) {
|
|
char buff[20];
|
|
time_t localTime = (time_t)NTP_GetCurrentTime();
|
|
|
|
if (bAppendHeader) {
|
|
printer(request, "\"StatusSTS\":");
|
|
}
|
|
printer(request, "{");
|
|
strftime(buff, sizeof(buff), "%Y-%m-%dT%H:%M:%S", localtime(&localTime));
|
|
JSON_PrintKeyValue_String(request, printer, "Time", buff, true);
|
|
format_time(Time_getUpTimeSeconds(), buff, sizeof(buff));
|
|
JSON_PrintKeyValue_String(request, printer, "Uptime", buff, true);
|
|
//JSON_PrintKeyValue_String(request, printer, "Uptime", "30T02:59:30", true);
|
|
JSON_PrintKeyValue_Int(request, printer, "UptimeSec", Time_getUpTimeSeconds(), true);
|
|
JSON_PrintKeyValue_Int(request, printer, "Heap", 25, true);
|
|
JSON_PrintKeyValue_String(request, printer, "SleepMode", "Dynamic", true);
|
|
JSON_PrintKeyValue_Int(request, printer, "Sleep", 10, true);
|
|
JSON_PrintKeyValue_Int(request, printer, "LoadAvg", 99, true);
|
|
JSON_PrintKeyValue_Int(request, printer, "MqttCount", 23, true);
|
|
#if defined(PLATFORM_BEKEN)
|
|
if (DRV_IsRunning("Battery")) {
|
|
printer(request, "\"Vcc\":%.4f,", Battery_lastreading(OBK_BATT_VOLTAGE) / 1000.00);
|
|
}
|
|
#endif
|
|
http_tasmota_json_power(request, printer);
|
|
printer(request, ",");
|
|
printer(request, "\"Wifi\":{"); // open WiFi
|
|
JSON_PrintKeyValue_Int(request, printer, "AP", 1, true);
|
|
JSON_PrintKeyValue_String(request, printer, "SSId", CFG_GetWiFiSSID(), true);
|
|
JSON_PrintKeyValue_String(request, printer, "BSSId", "30:B5:C2:5D:70:72", true);
|
|
JSON_PrintKeyValue_Int(request, printer, "Channel", 11, true);
|
|
JSON_PrintKeyValue_String(request, printer, "Mode", "11n", true);
|
|
JSON_PrintKeyValue_Int(request, printer, "RSSI", (HAL_GetWifiStrength() + 100) * 2, true);
|
|
JSON_PrintKeyValue_Int(request, printer, "Signal", HAL_GetWifiStrength(), true);
|
|
JSON_PrintKeyValue_Int(request, printer, "LinkCount", 21, true);
|
|
JSON_PrintKeyValue_String(request, printer, "Downtime", "0T06:13:34", false);
|
|
printer(request, "}"); // close WiFi
|
|
printer(request, "}");
|
|
return 0;
|
|
}
|
|
static int http_tasmota_json_status_TIM(void* request, jsonCb_t printer) {
|
|
char buff[20];
|
|
|
|
time_t localTime = (time_t)NTP_GetCurrentTime();
|
|
time_t localUTC = (time_t)NTP_GetCurrentTimeWithoutOffset();
|
|
printer(request, "\"StatusTIM\":{");
|
|
strftime(buff, sizeof(buff), "%Y-%m-%dT%H:%M:%S", localtime(&localUTC));
|
|
JSON_PrintKeyValue_String(request, printer, "UTC", buff, true);
|
|
strftime(buff, sizeof(buff), "%Y-%m-%dT%H:%M:%S", localtime(&localTime));
|
|
JSON_PrintKeyValue_String(request, printer, "Local", buff, true);
|
|
JSON_PrintKeyValue_String(request, printer, "StartDST", "2022-03-27T02:00:00", true);
|
|
JSON_PrintKeyValue_String(request, printer, "EndDST", "2022-10-30T03:00:00", true);
|
|
JSON_PrintKeyValue_String(request, printer, "Timezone", "+01:00", true);
|
|
JSON_PrintKeyValue_String(request, printer, "Sunrise", "07:50", true);
|
|
JSON_PrintKeyValue_String(request, printer, "Sunset", "17:17", false);
|
|
printer(request, "}");
|
|
return 0;
|
|
}
|
|
static int http_tasmota_json_status_FWR(void* request, jsonCb_t printer) {
|
|
|
|
printer(request, "\"StatusFWR\":{");
|
|
JSON_PrintKeyValue_String(request, printer, "Version", DEVICENAME_PREFIX_FULL"_"USER_SW_VER, true);
|
|
JSON_PrintKeyValue_String(request, printer, "BuildDateTime", __DATE__" "__TIME__, true);
|
|
JSON_PrintKeyValue_Int(request, printer, "Boot", 7, true);
|
|
JSON_PrintKeyValue_String(request, printer, "Core", "0.0", true);
|
|
JSON_PrintKeyValue_String(request, printer, "SDK", "obk", true);
|
|
JSON_PrintKeyValue_Int(request, printer, "CpuFrequency", 80, true);
|
|
JSON_PrintKeyValue_String(request, printer, "Hardware", PLATFORM_MCU_NAME, true);
|
|
JSON_PrintKeyValue_String(request, printer, "CR", "465/699", false);
|
|
printer(request, "}");
|
|
return 0;
|
|
}
|
|
static int http_tasmota_json_status_MEM(void* request, jsonCb_t printer) {
|
|
printer(request, "\"StatusMEM\":{");
|
|
JSON_PrintKeyValue_Int(request, printer, "ProgramSize", 616, true);
|
|
JSON_PrintKeyValue_Int(request, printer, "Free", 384, true);
|
|
JSON_PrintKeyValue_Int(request, printer, "Heap", 25, true);
|
|
JSON_PrintKeyValue_Int(request, printer, "ProgramFlashSize", 1024, true);
|
|
JSON_PrintKeyValue_Int(request, printer, "FlashSize", 2048, true);
|
|
JSON_PrintKeyValue_String(request, printer, "FlashChipId", "1540A1", true);
|
|
JSON_PrintKeyValue_Int(request, printer, "FlashFrequency", 40, true);
|
|
JSON_PrintKeyValue_Int(request, printer, "FlashMode", 3, true);
|
|
printer(request, "\"Features\":[");
|
|
printer(request, "\"00000809\",");
|
|
printer(request, "\"8FDAC787\",");
|
|
printer(request, "\"04368001\",");
|
|
printer(request, "\"000000CF\",");
|
|
printer(request, "\"010013C0\",");
|
|
printer(request, "\"C000F981\",");
|
|
printer(request, "\"00004004\",");
|
|
printer(request, "\"00001000\",");
|
|
printer(request, "\"00000020\"");
|
|
printer(request, "],");
|
|
JSON_PrintKeyValue_String(request, printer, "Drivers", "1,2,3,4,5,6,7,8,9,10,12,16,18,19,20,21,22,24,26,27,29,30,35,37,45", true);
|
|
JSON_PrintKeyValue_String(request, printer, "Sensors", "1,2,3,4,5,6", false);
|
|
printer(request, "}");
|
|
return 0;
|
|
}
|
|
static int http_tasmota_json_status_NET(void* request, jsonCb_t printer) {
|
|
|
|
printer(request, "\"StatusNET\":{");
|
|
JSON_PrintKeyValue_String(request, printer, "Hostname", CFG_GetShortDeviceName(), true);
|
|
JSON_PrintKeyValue_String(request, printer, "IPAddress", HAL_GetMyIPString(), true);
|
|
JSON_PrintKeyValue_String(request, printer, "Gateway", "192.168.0.1", true);
|
|
JSON_PrintKeyValue_String(request, printer, "Subnetmask", "255.255.255.0", true);
|
|
JSON_PrintKeyValue_String(request, printer, "DNSServer1", "192.168.0.1", true);
|
|
JSON_PrintKeyValue_String(request, printer, "DNSServer2", "0.0.0.0", true);
|
|
JSON_PrintKeyValue_String(request, printer, "Mac", "10:52:1C:D7:9E:2C", true);
|
|
JSON_PrintKeyValue_Int(request, printer, "Webserver", 2, true);
|
|
JSON_PrintKeyValue_Int(request, printer, "HTTP_API", 1, true);
|
|
JSON_PrintKeyValue_Int(request, printer, "WifiConfig", 4, true);
|
|
printer(request, "\"WifiPower\":17.0");
|
|
printer(request, "}");
|
|
return 0;
|
|
}
|
|
static int http_tasmota_json_status_MQT(void* request, jsonCb_t printer) {
|
|
|
|
printer(request, "\"StatusMQT\":{");
|
|
JSON_PrintKeyValue_String(request, printer, "MqttHost", CFG_GetMQTTHost(), true);
|
|
JSON_PrintKeyValue_Int(request, printer, "MqttPort", CFG_GetMQTTPort(), true);
|
|
JSON_PrintKeyValue_String(request, printer, "MqttClientMask", "core", true);
|
|
JSON_PrintKeyValue_String(request, printer, "MqttClient", CFG_GetMQTTClientId(), true);
|
|
JSON_PrintKeyValue_String(request, printer, "MqttUser", CFG_GetMQTTUserName(), true);
|
|
JSON_PrintKeyValue_Int(request, printer, "MqttCount", 23, true);
|
|
JSON_PrintKeyValue_Int(request, printer, "MAX_PACKET_SIZE", 1200, true);
|
|
JSON_PrintKeyValue_Int(request, printer, "KEEPALIVE", 30, true);
|
|
JSON_PrintKeyValue_Int(request, printer, "SOCKET_TIMEOUT", 4, false);
|
|
printer(request, "}");
|
|
return 0;
|
|
}
|
|
/*
|
|
{"Status":{"Module":0,"DeviceName":"Tasmota","FriendlyName":["Tasmota"],"Topic":"tasmota_48E7F3","ButtonTopic":"0","Power":1,"PowerOnState":3,"LedState":1,"LedMask":"FFFF","SaveData":1,"SaveState":1,"SwitchTopic":"0","SwitchMode":[0,0,0,0,0,0,0,0],"ButtonRetain":0,"SwitchRetain":0,"SensorRetain":0,"PowerRetain":0,"InfoRetain":0,"StateRetain":0}}
|
|
*/
|
|
static int http_tasmota_json_status_generic(void* request, jsonCb_t printer) {
|
|
const char* deviceName;
|
|
const char* friendlyName;
|
|
const char* clientId;
|
|
int powerCode;
|
|
int relayCount, pwmCount, dInputCount, i;
|
|
bool bRelayIndexingStartsWithZero;
|
|
|
|
deviceName = CFG_GetShortDeviceName();
|
|
friendlyName = CFG_GetDeviceName();
|
|
clientId = CFG_GetMQTTClientId();
|
|
|
|
//deviceName = "Tasmota";
|
|
//friendlyName - "Tasmota";
|
|
|
|
bRelayIndexingStartsWithZero = CHANNEL_HasChannelPinWithRoleOrRole(0, IOR_Relay, IOR_Relay_n);
|
|
|
|
get_Relay_PWM_Count(&relayCount, &pwmCount, &dInputCount);
|
|
|
|
if (LED_IsLEDRunning()) {
|
|
powerCode = LED_GetEnableAll();
|
|
}
|
|
else {
|
|
powerCode = 0;
|
|
for (i = 0; i < CHANNEL_MAX; i++) {
|
|
bool bRelay;
|
|
int useIdx;
|
|
int iValue;
|
|
if (bRelayIndexingStartsWithZero) {
|
|
useIdx = i;
|
|
}
|
|
else {
|
|
useIdx = i + 1;
|
|
}
|
|
bRelay = CHANNEL_HasChannelPinWithRoleOrRole(useIdx, IOR_Relay, IOR_Relay_n);
|
|
if (bRelay) {
|
|
iValue = CHANNEL_Get(useIdx);
|
|
if (iValue)
|
|
BIT_SET(powerCode, i);
|
|
else
|
|
BIT_CLEAR(powerCode, i);
|
|
}
|
|
}
|
|
}
|
|
|
|
printer(request, "{");
|
|
// Status section
|
|
printer(request, "\"Status\":{\"Module\":0,");
|
|
JSON_PrintKeyValue_String(request, printer, "DeviceName", deviceName, true);
|
|
printer(request, "\"FriendlyName\":[");
|
|
if (relayCount == 0) {
|
|
printer(request, "\"%s\"", deviceName);
|
|
}
|
|
else {
|
|
int c_printed = 0;
|
|
for (i = 0; i < CHANNEL_MAX; i++) {
|
|
bool bRelay;
|
|
bRelay = CHANNEL_HasChannelPinWithRoleOrRole(i, IOR_Relay, IOR_Relay_n);
|
|
if (bRelay) {
|
|
int useIdx;
|
|
if (bRelayIndexingStartsWithZero) {
|
|
useIdx = i + 1;
|
|
}
|
|
else {
|
|
useIdx = i;
|
|
}
|
|
if (c_printed) {
|
|
printer(request, ",");
|
|
}
|
|
printer(request, "\"%s_%i\"", deviceName, useIdx);
|
|
c_printed++;
|
|
}
|
|
}
|
|
}
|
|
printer(request, "]");
|
|
printer(request, ",\"Topic\":\"%s\",\"ButtonTopic\":\"0\"", clientId);
|
|
printer(request, ",\"Power\":%i,\"PowerOnState\":3,\"LedState\":1", powerCode);
|
|
printer(request, ",\"LedMask\":\"FFFF\",\"SaveData\":1,\"SaveState\":1");
|
|
printer(request, ",\"SwitchTopic\":\"0\",\"SwitchMode\":[0,0,0,0,0,0,0,0]");
|
|
printer(request, ",\"ButtonRetain\":0,\"SwitchRetain\":0,\"SensorRetain\":0");
|
|
printer(request, ",\"PowerRetain\":0,\"InfoRetain\":0,\"StateRetain\":0");
|
|
printer(request, "}");
|
|
|
|
printer(request, ",");
|
|
|
|
printer(request, "\"StatusPRM\":{");
|
|
JSON_PrintKeyValue_Int(request, printer, "Baudrate", 115200, true);
|
|
JSON_PrintKeyValue_String(request, printer, "SerialConfig", "8N1", true);
|
|
JSON_PrintKeyValue_String(request, printer, "GroupTopic", CFG_DeviceGroups_GetName(), true);
|
|
JSON_PrintKeyValue_String(request, printer, "OtaUrl", "https://github.com/openshwprojects/OpenBK7231T_App/releases/latest", true);
|
|
JSON_PrintKeyValue_String(request, printer, "RestartReason", "HardwareWatchdog", true);
|
|
JSON_PrintKeyValue_Int(request, printer, "Uptime", Time_getUpTimeSeconds(), true);
|
|
struct tm* ltm;
|
|
int ntpTime = NTP_GetCurrentTime() - Time_getUpTimeSeconds();
|
|
ltm = localtime((time_t*)&ntpTime);
|
|
|
|
if (ltm != 0) {
|
|
printer(request, "\"StartupUTC\":\"%04d-%02d-%02dT%02d:%02d:%02d\",", ltm->tm_year + 1900, ltm->tm_mon + 1, ltm->tm_mday, ltm->tm_hour, ltm->tm_min, ltm->tm_sec);
|
|
}
|
|
else {
|
|
|
|
}
|
|
JSON_PrintKeyValue_Int(request, printer, "Sleep", 50, true);
|
|
JSON_PrintKeyValue_Int(request, printer, "CfgHolder", 4617, true);
|
|
JSON_PrintKeyValue_Int(request, printer, "BootCount", 22, true);
|
|
JSON_PrintKeyValue_String(request, printer, "BCResetTime", "2022-01-27T16:10:56", true);
|
|
JSON_PrintKeyValue_Int(request, printer, "SaveCount", 1235, true);
|
|
JSON_PrintKeyValue_String(request, printer, "SaveAddress", "F9000", false);
|
|
printer(request, "}");
|
|
|
|
printer(request, ",");
|
|
|
|
http_tasmota_json_status_FWR(request, printer);
|
|
|
|
printer(request, ",");
|
|
|
|
|
|
|
|
printer(request, "\"StatusLOG\":{");
|
|
printer(request, "\"SerialLog\":2,");
|
|
printer(request, "\"WebLog\":2,");
|
|
printer(request, "\"MqttLog\":0,");
|
|
printer(request, "\"SysLog\":0,");
|
|
printer(request, "\"LogHost\":\"\",");
|
|
printer(request, "\"LogPort\":514,");
|
|
printer(request, "\"SSId1\":\"%s\",", CFG_GetWiFiSSID());
|
|
printer(request, "\"SSId2\":\"\",");
|
|
printer(request, "\"TelePeriod\":300,");
|
|
printer(request, "\"Resolution\":\"558180C0\",");
|
|
printer(request, "\"SetOption\":[");
|
|
printer(request, "\"000A8009\",");
|
|
printer(request, "\"2805C80001000600003C5A0A000000000000\",");
|
|
printer(request, "\"00000280\",");
|
|
printer(request, "\"00006008\",");
|
|
printer(request, "\"00004000\"");
|
|
printer(request, "]");
|
|
printer(request, "}");
|
|
|
|
printer(request, ",");
|
|
|
|
|
|
|
|
http_tasmota_json_status_MEM(request, printer);
|
|
|
|
printer(request, ",");
|
|
|
|
http_tasmota_json_status_NET(request, printer);
|
|
|
|
printer(request, ",");
|
|
|
|
|
|
http_tasmota_json_status_MQT(request, printer);
|
|
|
|
|
|
printer(request, ",");
|
|
|
|
http_tasmota_json_status_TIM(request, printer);
|
|
|
|
printer(request, ",");
|
|
|
|
|
|
http_tasmota_json_status_SNS(request, printer, true);
|
|
|
|
printer(request, ",");
|
|
|
|
|
|
http_tasmota_json_status_STS(request, printer, true);
|
|
|
|
// end
|
|
printer(request, "}");
|
|
|
|
|
|
|
|
return 0;
|
|
}
|
|
int JSON_ProcessCommandReply(const char* cmd, const char* arg, void* request, jsonCb_t printer, int flags) {
|
|
|
|
if (!wal_strnicmp(cmd, "POWER", 5)) {
|
|
|
|
printer(request, "{");
|
|
http_tasmota_json_power(request, printer);
|
|
printer(request, "}");
|
|
if (flags == COMMAND_FLAG_SOURCE_MQTT) {
|
|
MQTT_PublishPrinterContentsToStat((struct obk_mqtt_publishReplyPrinter_s*)request, "RESULT");
|
|
}
|
|
}
|
|
else if (!wal_strnicmp(cmd, "SensorRetain", 12)) {
|
|
printer(request, "{");
|
|
if (CFG_HasFlag(OBK_PUBLISH_FLAG_RETAIN))
|
|
{
|
|
JSON_PrintKeyValue_String(request, printer, "SensorRetain", "ON", false);
|
|
}
|
|
else
|
|
{
|
|
JSON_PrintKeyValue_String(request, printer, "SensorRetain", "OFF", false);
|
|
}
|
|
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "Prefix1", 7)) {
|
|
//TODO
|
|
// Prefix1 1 = reset MQTT command subscription prefix to firmware default (SUB_PREFIX) and restart
|
|
// <value> = set MQTT command subscription prefix and restart
|
|
// Prefix2 1 = reset MQTT status prefix to firmware default (PUB_PREFIX) and restart
|
|
// <value> = set MQTT status prefix and restart
|
|
// Prefix3 1 = Reset MQTT telemetry prefix to firmware default (PUB_PREFIX2) and restart
|
|
// <value> = set MQTT telemetry prefix and restart
|
|
printer(request, "{");
|
|
JSON_PrintKeyValue_String(request, printer, "Prefix1", "cmnd", false);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "Prefix2", 7)) {
|
|
printer(request, "{");
|
|
JSON_PrintKeyValue_String(request, printer, "Prefix2", "stat", false);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "Prefix3", 7)) {
|
|
printer(request, "{");
|
|
JSON_PrintKeyValue_String(request, printer, "Prefix3", "tele", false);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "StateText1", 10)) {
|
|
//TODO
|
|
//StateText<x> <value> = set state text (<x> = 1..4)
|
|
// 1 = OFF state text
|
|
// 2 = ON state text
|
|
// 3 = TOGGLE state text
|
|
// 4 = HOLD state text
|
|
printer(request, "{");
|
|
JSON_PrintKeyValue_String(request, printer, "StateText1", "OFF", false);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "StateText2", 10)) {
|
|
printer(request, "{");
|
|
JSON_PrintKeyValue_String(request, printer, "StateText2", "ON", false);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "StateText3", 10)) {
|
|
printer(request, "{");
|
|
JSON_PrintKeyValue_String(request, printer, "StateText3", "TOGGLE", false);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "StateText4", 10)) {
|
|
printer(request, "{");
|
|
JSON_PrintKeyValue_String(request, printer, "StateText4", "HOLD", false);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "FullTopic", 9)) {
|
|
printer(request, "{");
|
|
JSON_PrintKeyValue_String(request, printer, "FullTopic", "%%prefix%%/%%topic%%", false);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "SwitchTopic", 11)) {
|
|
printer(request, "{");
|
|
JSON_PrintKeyValue_String(request, printer, "SwitchTopic", "0", false);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "ButtonTopic", 11)) {
|
|
printer(request, "{");
|
|
JSON_PrintKeyValue_String(request, printer, "ButtonTopic", "0", false);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "MqttRetry", 9)) {
|
|
printer(request, "{");
|
|
JSON_PrintKeyValue_String(request, printer, "MqttRetry", "1", false);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "TelePeriod", 10)) {
|
|
printer(request, "{");
|
|
JSON_PrintKeyValue_String(request, printer, "TelePeriod", "300", false);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "CT", 2)) {
|
|
printer(request, "{");
|
|
if (*arg == 0) {
|
|
http_tasmota_json_CT(request, printer);
|
|
}
|
|
else {
|
|
http_tasmota_json_power(request, printer);
|
|
}
|
|
printer(request, "}");
|
|
if (flags == COMMAND_FLAG_SOURCE_MQTT) {
|
|
MQTT_PublishPrinterContentsToStat((struct obk_mqtt_publishReplyPrinter_s*)request, "RESULT");
|
|
}
|
|
}
|
|
else if (!wal_strnicmp(cmd, "Dimmer", 6)) {
|
|
printer(request, "{");
|
|
if (*arg == 0) {
|
|
http_tasmota_json_Dimmer(request, printer);
|
|
}
|
|
else {
|
|
http_tasmota_json_power(request, printer);
|
|
}
|
|
printer(request, "}");
|
|
if (flags == COMMAND_FLAG_SOURCE_MQTT) {
|
|
MQTT_PublishPrinterContentsToStat((struct obk_mqtt_publishReplyPrinter_s*)request, "RESULT");
|
|
}
|
|
}
|
|
else if (!wal_strnicmp(cmd, "Color", 5)) {
|
|
printer(request, "{");
|
|
//if (*arg == 0) {
|
|
// http_tasmota_json_Colo(request, printer);
|
|
//}
|
|
//else {
|
|
http_tasmota_json_power(request, printer);
|
|
//}
|
|
printer(request, "}");
|
|
if (flags == COMMAND_FLAG_SOURCE_MQTT) {
|
|
MQTT_PublishPrinterContentsToStat((struct obk_mqtt_publishReplyPrinter_s*)request, "RESULT");
|
|
}
|
|
}
|
|
else if (!wal_strnicmp(cmd, "STATE", 5)) {
|
|
http_tasmota_json_status_STS(request, printer, false);
|
|
if (flags == COMMAND_FLAG_SOURCE_MQTT) {
|
|
MQTT_PublishPrinterContentsToStat((struct obk_mqtt_publishReplyPrinter_s*)request, "RESULT");
|
|
}
|
|
if (flags == COMMAND_FLAG_SOURCE_TELESENDER) {
|
|
MQTT_PublishPrinterContentsToTele((struct obk_mqtt_publishReplyPrinter_s*)request, "STATE");
|
|
}
|
|
}
|
|
else if (!wal_strnicmp(cmd, "SENSOR", 5)) {
|
|
// not a Tasmota command, but still required for us
|
|
http_tasmota_json_status_SNS(request, printer, false);
|
|
if (flags == COMMAND_FLAG_SOURCE_TELESENDER) {
|
|
MQTT_PublishPrinterContentsToTele((struct obk_mqtt_publishReplyPrinter_s*)request, "SENSOR");
|
|
}
|
|
}
|
|
else if (!wal_strnicmp(cmd, "STATUS", 6)) {
|
|
if (!stricmp(arg, "8") || !stricmp(arg, "10")) {
|
|
printer(request, "{");
|
|
http_tasmota_json_status_SNS(request, printer, true);
|
|
printer(request, "}");
|
|
if (flags == COMMAND_FLAG_SOURCE_MQTT) {
|
|
if (arg[0] == '8') {
|
|
MQTT_PublishPrinterContentsToStat((struct obk_mqtt_publishReplyPrinter_s*)request, "STATUS8");
|
|
}
|
|
else {
|
|
MQTT_PublishPrinterContentsToStat((struct obk_mqtt_publishReplyPrinter_s*)request, "STATUS10");
|
|
}
|
|
}
|
|
}
|
|
else if (!stricmp(arg, "6")) {
|
|
printer(request, "{");
|
|
http_tasmota_json_status_MQT(request, printer);
|
|
printer(request, "}");
|
|
if (flags == COMMAND_FLAG_SOURCE_MQTT) {
|
|
MQTT_PublishPrinterContentsToStat((struct obk_mqtt_publishReplyPrinter_s*)request, "STATUS6");
|
|
}
|
|
}
|
|
else if (!stricmp(arg, "7")) {
|
|
printer(request, "{");
|
|
http_tasmota_json_status_TIM(request, printer);
|
|
printer(request, "}");
|
|
if (flags == COMMAND_FLAG_SOURCE_MQTT) {
|
|
MQTT_PublishPrinterContentsToStat((struct obk_mqtt_publishReplyPrinter_s*)request, "STATUS7");
|
|
}
|
|
}
|
|
else if (!stricmp(arg, "5")) {
|
|
printer(request, "{");
|
|
http_tasmota_json_status_NET(request, printer);
|
|
printer(request, "}");
|
|
if (flags == COMMAND_FLAG_SOURCE_MQTT) {
|
|
MQTT_PublishPrinterContentsToStat((struct obk_mqtt_publishReplyPrinter_s*)request, "STATUS5");
|
|
}
|
|
}
|
|
else if (!stricmp(arg, "4")) {
|
|
printer(request, "{");
|
|
http_tasmota_json_status_MEM(request, printer);
|
|
printer(request, "}");
|
|
if (flags == COMMAND_FLAG_SOURCE_MQTT) {
|
|
MQTT_PublishPrinterContentsToStat((struct obk_mqtt_publishReplyPrinter_s*)request, "STATUS4");
|
|
}
|
|
}
|
|
else if (!stricmp(arg, "2")) {
|
|
printer(request, "{");
|
|
http_tasmota_json_status_FWR(request, printer);
|
|
printer(request, "}");
|
|
if (flags == COMMAND_FLAG_SOURCE_MQTT) {
|
|
MQTT_PublishPrinterContentsToStat((struct obk_mqtt_publishReplyPrinter_s*)request, "STATUS2");
|
|
}
|
|
}
|
|
else {
|
|
http_tasmota_json_status_generic(request, printer);
|
|
if (flags == COMMAND_FLAG_SOURCE_MQTT) {
|
|
MQTT_PublishPrinterContentsToStat((struct obk_mqtt_publishReplyPrinter_s*)request, "STATUS");
|
|
}
|
|
}
|
|
}
|
|
else if (!wal_strnicmp(cmd, "SetChannelType", 14)) {
|
|
// OBK-specific
|
|
int i = atoi(arg);
|
|
i = CHANNEL_GetType(i);
|
|
|
|
printer(request, "%i", i);
|
|
}
|
|
else if (!wal_strnicmp(cmd, "GetChannel", 10) || !wal_strnicmp(cmd, "SetChannel", 10) || !wal_strnicmp(cmd, "AddChannel", 10)) {
|
|
// OBK-specific
|
|
int i = atoi(arg);
|
|
i = CHANNEL_Get(i);
|
|
|
|
printer(request, "%i", i);
|
|
}
|
|
else if (!wal_strnicmp(cmd, "led_basecolor_rgb", 17)) {
|
|
// OBK-specific
|
|
char tmp[16];
|
|
LED_GetBaseColorString(tmp);
|
|
printer(request, "{");
|
|
JSON_PrintKeyValue_String(request, printer, "led_basecolor_rgb", tmp, false);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "MQTTClient", 8)) {
|
|
printer(request, "{");
|
|
JSON_PrintKeyValue_String(request, printer, "MQTTClient", CFG_GetMQTTClientId(), false);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "MQTTHost", 8)) {
|
|
printer(request, "{");
|
|
JSON_PrintKeyValue_String(request, printer, "MQTTHost", CFG_GetMQTTHost(), false);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "MQTTUser", 8)) {
|
|
printer(request, "{");
|
|
JSON_PrintKeyValue_String(request, printer, "MQTTUser", CFG_GetMQTTUserName(), false);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "MqttPassword", 12)) {
|
|
printer(request, "{");
|
|
JSON_PrintKeyValue_String(request, printer, "MqttPassword", "****", false);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "SSID1", 5)) {
|
|
printer(request, "{");
|
|
JSON_PrintKeyValue_String(request,printer,"SSID1", CFG_GetWiFiSSID(),false);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "LED_Map", 7)) {
|
|
printer(request, "{");
|
|
printer(request, "\"Map\":[%i,%i,%i,%i,%i]",
|
|
(int)g_cfg.ledRemap.r, (int)g_cfg.ledRemap.g, (int)g_cfg.ledRemap.b, (int)g_cfg.ledRemap.c, (int)g_cfg.ledRemap.w);
|
|
printer(request, "}");
|
|
}
|
|
else if (!wal_strnicmp(cmd, "Flags", 5)) {
|
|
printer(request, "{");
|
|
printer(request, "\"Flags\":\"%ld\"", *((long int*)&g_cfg.genericFlags));
|
|
printer(request, "}");
|
|
}
|
|
else {
|
|
printer(request, "{");
|
|
printer(request, "}");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|