diff --git a/src/httpserver/hass.c b/src/httpserver/hass.c index 273e87dd4..3e32f5e11 100644 --- a/src/httpserver/hass.c +++ b/src/httpserver/hass.c @@ -128,6 +128,9 @@ void hass_populate_unique_id(ENTITY_TYPE type, int index, char* uniq_id, int ase case HASS_IP: sprintf(uniq_id, "%s_ip", longDeviceName); break; + case HASS_PERCENT: + sprintf(uniq_id, "%s_%s_%d", longDeviceName, "number", index); + break; default: // TODO: USE type here as well? // If type is not set, and we use "sensor" naming, we can easily make collision @@ -181,6 +184,9 @@ void hass_populate_device_config_channel(ENTITY_TYPE type, char* uniq_id, HassDe case HASS_FAN: sprintf(info->channel, "fan/%s/config", uniq_id); break; + case HASS_PERCENT: + sprintf(info->channel, "number/%s/config", uniq_id); + break; case SMOKE_SENSOR: case CO2_SENSOR: case TVOC_SENSOR: @@ -806,6 +812,29 @@ HassDeviceInfo* hass_init_sensor_device_info(ENTITY_TYPE type, int channel, int //https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes switch (type) { + case HASS_PERCENT: + // backlog setChannelType 5 Percent; scheduleHADiscovery + cJSON_AddStringToObject(info->root, "unit_of_meas", "%"); + cJSON_AddStringToObject(info->root, "stat_cla", "measurement"); + + // State topic for reading the percentage value + sprintf(g_hassBuffer, "~/%d/get", channel); + cJSON_AddStringToObject(info->root, "stat_t", g_hassBuffer); + + // Command topic for writing the percentage value + sprintf(g_hassBuffer, "~/%d/set", channel); + cJSON_AddStringToObject(info->root, "cmd_t", g_hassBuffer); + + // Value template to ensure the value is between 0 and 100 + //cJSON_AddStringToObject(info->root, "val_tpl", "{{ value | float | round(0) | max(0) | min(100) }}"); + + + // Add number-specific properties for the slider + cJSON_AddStringToObject(info->root, "mode", "slider"); // Use slider mode in HA + cJSON_AddNumberToObject(info->root, "min", 0); // Minimum value + cJSON_AddNumberToObject(info->root, "max", 100); // Maximum value + cJSON_AddNumberToObject(info->root, "step", 1); // Step value for slider + break; case TEMPERATURE_SENSOR: cJSON_AddStringToObject(info->root, "dev_cla", "temperature"); cJSON_AddStringToObject(info->root, "unit_of_meas", "°C"); @@ -972,7 +1001,7 @@ HassDeviceInfo* hass_init_sensor_device_info(ENTITY_TYPE type, int channel, int } - if (decPlaces != -1 && decOffset != -1 && divider != -1) { + if (decPlaces != -1 && decOffset != -1 && divider != -1 && type != HASS_PERCENT) { //https://www.home-assistant.io/integrations/sensor.mqtt/ refers to value_template (val_tpl) cJSON_AddStringToObject(info->root, "val_tpl", hass_generate_multiplyAndRound_template(decPlaces, decOffset, divider)); } diff --git a/src/httpserver/hass.h b/src/httpserver/hass.h index b12109b54..d4ac62e59 100644 --- a/src/httpserver/hass.h +++ b/src/httpserver/hass.h @@ -97,7 +97,8 @@ typedef enum { BATTERY_CHANNEL_SENSOR, HASS_HVAC, HASS_FAN, - HASS_SELECT + HASS_SELECT, + HASS_PERCENT, } ENTITY_TYPE; //unique_id is defined in hass_populate_unique_id and is based on CFG_GetDeviceName() whose size is CGF_DEVICE_NAME_SIZE. diff --git a/src/httpserver/http_fns.c b/src/httpserver/http_fns.c index d0e1f0c6e..3e25807aa 100644 --- a/src/httpserver/http_fns.c +++ b/src/httpserver/http_fns.c @@ -579,7 +579,9 @@ int http_fn_index(http_request_t* request) { else if (h_isChannelRelay(i) || channelType == ChType_Toggle || channelType == ChType_Toggle_Inv) { // HANDLED ABOVE in previous loop } - else if ((bRawPWMs && h_isChannelPWM(i)) || (channelType == ChType_Dimmer) || (channelType == ChType_Dimmer256) || (channelType == ChType_Dimmer1000)) { + else if ((bRawPWMs && h_isChannelPWM(i)) || + (channelType == ChType_Dimmer) || (channelType == ChType_Dimmer256) || (channelType == ChType_Dimmer1000) + || channelType == ChType_Percent) { int maxValue; // PWM and dimmer both use a slider control inputName = h_isChannelPWM(i) ? "pwm" : "dim"; @@ -2143,6 +2145,11 @@ void doHomeAssistantDiscovery(const char* topic, http_request_t* request) { dev_info = hass_init_sensor_device_info(FREQUENCY_SENSOR, i, 3, 2, 1); } break; + case ChType_Percent: + { + dev_info = hass_init_sensor_device_info(HASS_PERCENT, i, 3, 2, 1); + } + break; case ChType_Frequency_div1000: { dev_info = hass_init_sensor_device_info(FREQUENCY_SENSOR, i, 4, 3, 1); diff --git a/src/new_pins.c b/src/new_pins.c index a647923f8..8401854c5 100644 --- a/src/new_pins.c +++ b/src/new_pins.c @@ -2221,7 +2221,7 @@ const char* g_channelTypeNames[] = { "Motion_n", "Frequency_div1000", "OpenStopClose", - "error", + "Percent", "error", "error", "error", diff --git a/src/new_pins.h b/src/new_pins.h index 86cbd9978..489becc75 100644 --- a/src/new_pins.h +++ b/src/new_pins.h @@ -1003,6 +1003,7 @@ typedef enum channelType_e { ChType_Frequency_div1000, ChType_OpenStopClose, + ChType_Percent, //chandetail:{"name":"Max", //chandetail:"title":"TODO", //chandetail:"descr":"This is the current total number of available channel types.",