diff --git a/src/driver/drv_tclAC.c b/src/driver/drv_tclAC.c index 4044f1737..a5cdbb4df 100644 --- a/src/driver/drv_tclAC.c +++ b/src/driver/drv_tclAC.c @@ -147,6 +147,8 @@ static const struct { {"turbo", FAN_TURBO}, {"auto", FAN_AUTOMATIC}, }; +//const char *fanOptions[] = { "auto", "low", "medium", "high" }; +const char *fanOptions[] = { "off", "1", "2", "3", "4", "5", "mute", "turbo", "auto" }; fanMode_e parseFanMode(const char *s) { for (int i = 0; i < sizeof(fanModeMap) / sizeof(fanModeMap[0]); ++i) { @@ -165,7 +167,6 @@ const char *fanModeToStr(fanMode_e mode) { } return NULL; } -const char *fanOptions[] = { "auto", "low", "medium", "high" }; typedef enum { VS_NONE, VS_MoveFull, @@ -343,7 +344,7 @@ static const struct { {"off", CLIMATE_MODE_OFF}, {"cool", CLIMATE_MODE_COOL}, {"dry", CLIMATE_MODE_DRY}, - {"fan", CLIMATE_MODE_FAN_ONLY}, + {"fan_only", CLIMATE_MODE_FAN_ONLY}, {"heat", CLIMATE_MODE_HEAT}, {"heatcool", CLIMATE_MODE_HEAT_COOL}, {"auto", CLIMATE_MODE_AUTO} @@ -615,13 +616,67 @@ static commandResult_t CMD_FANMode(const void* context, const char* cmd, const c return CMD_RES_OK; } +void HTTP_CreateSelect(http_request_t *request, const char **options, int numOptions, const char *active, const char *command) { + // on select, send option string to /cm?cmnd=Command [Option] + char tmpA[64]; + if (http_getArg(request->url, command, tmpA, sizeof(tmpA))) { + CMD_ExecuteCommandArgs(command, tmpA, 0); + // hack for display? + active = tmpA; + } + hprintf255(request, + "
" + "
"); +} +void HTTP_CreateDIV(http_request_t *request, const char *label) { + + hprintf255(request, "
%s
", label); +} +void HTTP_CreateRadio(http_request_t *request, const char **options, int numOptions, const char *active, const char *command) { + char tmpA[64]; + if (http_getArg(request->url, command, tmpA, sizeof(tmpA))) { + CMD_ExecuteCommandArgs(command, tmpA, 0); + // hack for display? + active = tmpA; + } + hprintf255(request, "
"); + hprintf255(request, "%s ", command); + for (int i = 0; i < numOptions; i++) { + const char *checked = (strcmp(options[i], active) == 0) ? " checked" : ""; + hprintf255(request, + " ", + command, options[i], checked, options[i]); + } + + hprintf255(request, "
"); +} + void TCL_AppendInformationToHTTPIndexPage(http_request_t *request, int bPreState) { if (bPreState) { - + hprintf255(request, "
"); + HTTP_CreateDIV(request, "ACMode"); + HTTP_CreateDIV(request, "SwingV"); + HTTP_CreateDIV(request, "SwingH"); + hprintf255(request, "
"); + hprintf255(request, "
"); + HTTP_CreateSelect(request, fanOptions, sizeof(fanOptions) / sizeof(fanOptions[0]), climateModeToStr(g_mode), "ACMode"); + HTTP_CreateSelect(request, vertical_swing_options, sizeof(vertical_swing_options) / sizeof(vertical_swing_options[0]), getSwingVLabel(g_swingV), "SwingV"); + HTTP_CreateSelect(request, horizontal_swing_options, sizeof(horizontal_swing_options) / sizeof(horizontal_swing_options[0]), getSwingHLabel(g_swingH),"SwingH"); + hprintf255(request, "
"); } else { - hprintf255(request, "

SwingH: %s

", climateModeToStr(g_mode)); - hprintf255(request, "

SwingV: %s

", climateModeToStr(g_mode)); + HTTP_CreateRadio(request, fanOptions, sizeof(fanOptions) / sizeof(fanOptions[0]), climateModeToStr(g_mode), "ACMode"); + HTTP_CreateRadio(request, vertical_swing_options, sizeof(vertical_swing_options) / sizeof(vertical_swing_options[0]), getSwingVLabel(g_swingV), "SwingV"); + HTTP_CreateRadio(request, horizontal_swing_options, sizeof(horizontal_swing_options) / sizeof(horizontal_swing_options[0]), getSwingHLabel(g_swingH), "SwingH"); + hprintf255(request, "

SwingH: %s

", getSwingHLabel(g_swingH)); + hprintf255(request, "

SwingV: %s

", getSwingVLabel(g_swingV)); hprintf255(request, "

Mode: %s

", climateModeToStr(g_mode)); hprintf255(request, "

Current temperature: %f

", current_temperature); hprintf255(request, "

Target temperature: %f

", target_temperature); @@ -743,7 +798,10 @@ void TCL_DoDiscovery(const char *topic) { HassDeviceInfo* dev_info = NULL; - dev_info = hass_createHVAC(15,30,0.5f, fanOptions, 4); + dev_info = hass_createHVAC(15,30,0.5f, fanOptions, sizeof(fanOptions)/sizeof(fanOptions[0]), + vertical_swing_options,sizeof(vertical_swing_options) / sizeof(vertical_swing_options[0]), + horizontal_swing_options, sizeof(horizontal_swing_options) / sizeof(horizontal_swing_options[0]) + ); MQTT_QueuePublish(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN); hass_free_device_info(dev_info); @@ -760,31 +818,31 @@ void TCL_DoDiscovery(const char *topic) { hass_free_device_info(dev_info); - char command_topic[64]; + //char command_topic[64]; - // Vertical Swing Entity - sprintf(command_topic, "cmnd/%s/SwingV", CFG_GetMQTTClientId()); - dev_info = hass_createSelectEntity( - "~/SwingV/get", // state_topic - command_topic, // command_topic - 9, // numoptions (VerticalSwingMode has 9 values) - vertical_swing_options, // fanOptions array - "Vertical Swing Mode" // title - ); - MQTT_QueuePublish(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN); - hass_free_device_info(dev_info); + //// Vertical Swing Entity + //sprintf(command_topic, "cmnd/%s/SwingV", CFG_GetMQTTClientId()); + //dev_info = hass_createSelectEntity( + // "~/SwingV/get", // state_topic + // command_topic, // command_topic + // 9, // numoptions (VerticalSwingMode has 9 values) + // vertical_swing_options, // fanOptions array + // "Vertical Swing Mode" // title + //); + //MQTT_QueuePublish(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN); + //hass_free_device_info(dev_info); - // Horizontal Swing Entity - sprintf(command_topic, "cmnd/%s/SwingH", CFG_GetMQTTClientId()); - dev_info = hass_createSelectEntity( - "~/SwingH/get", // state_topic - command_topic, // command_topic - 10, // numoptions (HorizontalSwing has 10 values) - horizontal_swing_options, // fanOptions array - "Horizontal Swing Mode" // title - ); - MQTT_QueuePublish(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN); - hass_free_device_info(dev_info); + //// Horizontal Swing Entity + //sprintf(command_topic, "cmnd/%s/SwingH", CFG_GetMQTTClientId()); + //dev_info = hass_createSelectEntity( + // "~/SwingH/get", // state_topic + // command_topic, // command_topic + // 10, // numoptions (HorizontalSwing has 10 values) + // horizontal_swing_options, // fanOptions array + // "Horizontal Swing Mode" // title + //); + // MQTT_QueuePublish(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN); + //hass_free_device_info(dev_info); } diff --git a/src/httpserver/hass.c b/src/httpserver/hass.c index 3e32f5e11..2effcbf39 100644 --- a/src/httpserver/hass.c +++ b/src/httpserver/hass.c @@ -347,7 +347,8 @@ HassDeviceInfo* hass_createSelectEntityIndexed(const char* state_topic, const ch return info; } -HassDeviceInfo* hass_createHVAC(float min, float max, float step, const char **fanOptions, int numFanOptions) { +HassDeviceInfo* hass_createHVAC(float min, float max, float step, const char **fanOptions, int numFanOptions, + const char **swingOptions, int numSwingOptions, const char **swingHOptions, int numSwingHOptions) { HassDeviceInfo* info = hass_init_device_info(HASS_HVAC, 0, NULL, NULL, 0, 0); // Set the name for the HVAC device @@ -377,6 +378,8 @@ HassDeviceInfo* hass_createHVAC(float min, float max, float step, const char **f cJSON_AddItemToArray(modes, cJSON_CreateString("off")); cJSON_AddItemToArray(modes, cJSON_CreateString("heat")); cJSON_AddItemToArray(modes, cJSON_CreateString("cool")); + // fan does not work, it has to be fan_only + cJSON_AddItemToArray(modes, cJSON_CreateString("fan_only")); cJSON_AddItemToObject(info->root, "modes", modes); if (fanOptions && numFanOptions) { @@ -391,10 +394,35 @@ HassDeviceInfo* hass_createHVAC(float min, float max, float step, const char **f const char *mode = fanOptions[i]; cJSON_AddItemToArray(fan_modes, cJSON_CreateString(mode)); } - cJSON_AddItemToArray(fan_modes, cJSON_CreateString("high")); cJSON_AddItemToObject(info->root, "fan_modes", fan_modes); } + if (numSwingHOptions) { + // Add Swing Horizontal + cJSON_AddStringToObject(info->root, "swing_horizontal_mode_state_topic", "~/SwingH/get"); + sprintf(g_hassBuffer, "cmnd/%s/SwingH", CFG_GetMQTTClientId()); + cJSON_AddStringToObject(info->root, "swing_horizontal_mode_command_topic", g_hassBuffer); + cJSON* swingH_modes = cJSON_CreateArray(); + for (int i = 0; i < numSwingHOptions; i++) { + const char *mode = swingHOptions[i]; + cJSON_AddItemToArray(swingH_modes, cJSON_CreateString(mode)); + } + cJSON_AddItemToObject(info->root, "swing_horizontal_modes", swingH_modes); + } + if (numSwingOptions) { + // Add Swing Vertical + cJSON_AddStringToObject(info->root, "swing_mode_state_topic", "~/SwingV/get"); + sprintf(g_hassBuffer, "cmnd/%s/SwingV", CFG_GetMQTTClientId()); + cJSON_AddStringToObject(info->root, "swing_mode_command_topic", g_hassBuffer); + + cJSON* swing_modes = cJSON_CreateArray(); + for (int i = 0; i < numSwingOptions; i++) { + const char *mode = swingOptions[i]; + cJSON_AddItemToArray(swing_modes, cJSON_CreateString(mode)); + } + cJSON_AddItemToObject(info->root, "swing_modes", swing_modes); + + } // Set availability topic cJSON_AddStringToObject(info->root, "availability_topic", "~/status"); cJSON_AddStringToObject(info->root, "payload_available", "online"); @@ -1017,7 +1045,11 @@ const char* hass_build_discovery_json(HassDeviceInfo* info) { addLogAdv(LOG_ERROR, LOG_FEATURE_HASS, "ERROR: someone passed NULL pointer to hass_build_discovery_json\r\n"); return ""; } - cJSON_PrintPreallocated(info->root, info->json, HASS_JSON_SIZE, 0); + int bOk = cJSON_PrintPreallocated(info->root, info->json, HASS_JSON_SIZE, 0); + if (bOk == false) { + addLogAdv(LOG_ERROR, LOG_FEATURE_HASS, "ERROR: too long JSON in hass_build_discovery_json\r\n"); + return ""; + } return info->json; } diff --git a/src/httpserver/hass.h b/src/httpserver/hass.h index d4ac62e59..a0f298259 100644 --- a/src/httpserver/hass.h +++ b/src/httpserver/hass.h @@ -131,7 +131,8 @@ HassDeviceInfo* hass_init_energy_sensor_device_info(int index, int asensdataseti HassDeviceInfo* hass_init_light_singleColor_onChannels(int toggle, int dimmer, int brightness_scale); HassDeviceInfo* hass_init_binary_sensor_device_info(int index, bool bInverse); HassDeviceInfo* hass_init_sensor_device_info(ENTITY_TYPE type, int channel, int decPlaces, int decOffset, int divider); -HassDeviceInfo* hass_createHVAC(float min, float max, float step, const char **fanOptions, int numFanOptions); +HassDeviceInfo* hass_createHVAC(float min, float max, float step, const char **fanOptions, int numFanOptions, + const char **swingOptions, int numSwingOptions, const char **swingHOptions, int numSwingHOptions); HassDeviceInfo* hass_createFanWithModes(const char *label, const char *stateTopic, const char *command, const char **options, int numOptions); HassDeviceInfo* hass_createSelectEntity(const char* state_topic, const char* command_topic, int numoptions, diff --git a/src/mqtt/new_mqtt.h b/src/mqtt/new_mqtt.h index 4f224a59a..34215c1ea 100644 --- a/src/mqtt/new_mqtt.h +++ b/src/mqtt/new_mqtt.h @@ -86,7 +86,7 @@ typedef struct obk_mqtt_request_tag { #define MQTT_PUBLISH_ITEM_TOPIC_LENGTH 64 #define MQTT_PUBLISH_ITEM_CHANNEL_LENGTH 128 -#define MQTT_PUBLISH_ITEM_VALUE_LENGTH 1023 +#define MQTT_PUBLISH_ITEM_VALUE_LENGTH 1512 typedef enum PostPublishCommands_e { None, diff --git a/src/obk_config.h b/src/obk_config.h index 8aed66e14..254a5795d 100644 --- a/src/obk_config.h +++ b/src/obk_config.h @@ -417,7 +417,7 @@ #ifndef PLATFORM_RTL8710B #define ENABLE_OBK_BERRY 1 #endif -//#define ENABLE_DRIVER_TCL 1 +#define ENABLE_DRIVER_TCL 1 #elif PLATFORM_ECR6600