DHT discovery (#590)

* Renamed enums,hass_init_sensor_device_info

* Added discovery for DHT sensors

* Fixed/simplified publish in discovery

* Handle 2nd channel for DHT

* Renamed feature DHT to SENSOR to be reusable

* Added missing :

* Minor optimization

* Fixed missing }
This commit is contained in:
Indu Prakash
2023-01-09 03:06:58 -06:00
committed by GitHub
parent d7aebd5642
commit 174ab8dd1d
9 changed files with 191 additions and 120 deletions

View File

@ -29,27 +29,34 @@ void hass_populate_unique_id(ENTITY_TYPE type, int index, char* uniq_id) {
const char* longDeviceName = CFG_GetDeviceName();
switch (type) {
case ENTITY_LIGHT_PWM:
case LIGHT_PWM:
sprintf(uniq_id, "%s_%s_%d", longDeviceName, "light", index);
break;
case ENTITY_LIGHT_PWMCW:
case ENTITY_LIGHT_RGB:
case ENTITY_LIGHT_RGBCW:
case LIGHT_PWMCW:
case LIGHT_RGB:
case LIGHT_RGBCW:
sprintf(uniq_id, "%s_%s", longDeviceName, "light");
break;
case ENTITY_RELAY:
case RELAY:
sprintf(uniq_id, "%s_%s_%d", longDeviceName, "relay", index);
break;
case ENTITY_SENSOR:
case POWER_SENSOR:
sprintf(uniq_id, "%s_%s_%d", longDeviceName, "sensor", index);
break;
case ENTITY_BINARY_SENSOR:
case BINARY_SENSOR:
sprintf(uniq_id, "%s_%s_%d", longDeviceName, "binary_sensor", index);
break;
case TEMPERATURE_SENSOR:
sprintf(uniq_id, "%s_%s_%d", longDeviceName, "temperature", index);
break;
case HUMIDITY_SENSOR:
sprintf(uniq_id, "%s_%s_%d", longDeviceName, "humidity", index);
break;
}
}
@ -70,22 +77,24 @@ void hass_print_unique_id(http_request_t* request, const char* fmt, ENTITY_TYPE
/// @param info Device info
void hass_populate_device_config_channel(ENTITY_TYPE type, char* uniq_id, HassDeviceInfo* info) {
switch (type) {
case ENTITY_LIGHT_PWM:
case ENTITY_LIGHT_PWMCW:
case ENTITY_LIGHT_RGB:
case ENTITY_LIGHT_RGBCW:
case LIGHT_PWM:
case LIGHT_PWMCW:
case LIGHT_RGB:
case LIGHT_RGBCW:
sprintf(info->channel, "light/%s/config", uniq_id);
break;
case ENTITY_RELAY:
case RELAY:
sprintf(info->channel, "switch/%s/config", uniq_id);
break;
case ENTITY_SENSOR:
case POWER_SENSOR:
case TEMPERATURE_SENSOR:
case HUMIDITY_SENSOR:
sprintf(info->channel, "sensor/%s/config", uniq_id);
break;
case ENTITY_BINARY_SENSOR:
case BINARY_SENSOR:
sprintf(info->channel, "binary_sensor/%s/config", uniq_id);
}
}
@ -112,9 +121,10 @@ cJSON* hass_build_device_node(cJSON* ids) {
/// @brief Initializes HomeAssistant device discovery storage with common values.
/// @param type
/// @param index This is used to generate generate unique_id and name. It is ignored for RGB. For sensor this corresponds to sensor_mqttNames.
/// @param payload_on The payload that represents enabled state. This is not added for ENTITY_SENSOR.
/// @param payload_off The payload that represents disabled state. This is not added for ENTITY_SENSOR.
/// @param index This is used to generate generate unique_id and name.
/// It is ignored for RGB. For power sensors, index corresponds to sensor_mqttNames. For regular sensor, index can be be the channel.
/// @param payload_on The payload that represents enabled state. This is not added for POWER_SENSOR.
/// @param payload_off The payload that represents disabled state. This is not added for POWER_SENSOR.
/// @return
HassDeviceInfo* hass_init_device_info(ENTITY_TYPE type, int index, char* payload_on, char* payload_off) {
HassDeviceInfo* info = os_malloc(sizeof(HassDeviceInfo));
@ -131,21 +141,24 @@ HassDeviceInfo* hass_init_device_info(ENTITY_TYPE type, int index, char* payload
info->root = cJSON_CreateObject();
cJSON_AddItemToObject(info->root, "dev", info->device); //device
bool isSensor = false; //This does not count binary_sensor
//Build the `name`
switch (type) {
case ENTITY_LIGHT_PWM:
case ENTITY_RELAY:
case ENTITY_BINARY_SENSOR:
case LIGHT_PWM:
case RELAY:
case BINARY_SENSOR:
sprintf(g_hassBuffer, "%s %i", CFG_GetShortDeviceName(), index);
break;
case ENTITY_LIGHT_PWMCW:
case ENTITY_LIGHT_RGB:
case ENTITY_LIGHT_RGBCW:
case LIGHT_PWMCW:
case LIGHT_RGB:
case LIGHT_RGBCW:
//There can only be one RGB so we can skip including index in the name. Do the same
//for 2 PWM case.
sprintf(g_hassBuffer, "%s", CFG_GetShortDeviceName());
break;
case ENTITY_SENSOR:
case POWER_SENSOR:
isSensor = true;
#ifndef OBK_DISABLE_ALL_DRIVERS
if ((index >= OBK_VOLTAGE) && (index <= OBK_POWER))
sprintf(g_hassBuffer, "%s %s", CFG_GetShortDeviceName(), sensor_mqttNames[index]);
@ -153,12 +166,21 @@ HassDeviceInfo* hass_init_device_info(ENTITY_TYPE type, int index, char* payload
sprintf(g_hassBuffer, "%s %s", CFG_GetShortDeviceName(), counter_mqttNames[index - OBK_CONSUMPTION_TOTAL]);
#endif
break;
case TEMPERATURE_SENSOR:
isSensor = true;
sprintf(g_hassBuffer, "%s Temperature", CFG_GetShortDeviceName());
break;
case HUMIDITY_SENSOR:
isSensor = true;
sprintf(g_hassBuffer, "%s Humidity", CFG_GetShortDeviceName());
break;
}
cJSON_AddStringToObject(info->root, "name", g_hassBuffer);
cJSON_AddStringToObject(info->root, "~", CFG_GetMQTTClientId()); //base topic
cJSON_AddStringToObject(info->root, "avty_t", "~/connected"); //availability_topic, `online` value is broadcasted
if (type != ENTITY_SENSOR) {
if (!isSensor) { //Sensors (except binary_sensor) don't use payload
cJSON_AddStringToObject(info->root, "pl_on", payload_on); //payload_on
cJSON_AddStringToObject(info->root, "pl_off", payload_off); //payload_off
}
@ -174,7 +196,7 @@ HassDeviceInfo* hass_init_device_info(ENTITY_TYPE type, int index, char* payload
/// @param index
/// @return
HassDeviceInfo* hass_init_relay_device_info(int index) {
HassDeviceInfo* info = hass_init_device_info(ENTITY_RELAY, index, "1", "0");
HassDeviceInfo* info = hass_init_device_info(RELAY, index, "1", "0");
sprintf(g_hassBuffer, "~/%i/get", index);
cJSON_AddStringToObject(info->root, STATE_TOPIC_KEY, g_hassBuffer); //state_topic
@ -197,8 +219,8 @@ HassDeviceInfo* hass_init_light_device_info(ENTITY_TYPE type) {
info = hass_init_device_info(type, 1, "1", "0");
switch (type) {
case ENTITY_LIGHT_RGBCW:
case ENTITY_LIGHT_RGB:
case LIGHT_RGBCW:
case LIGHT_RGB:
cJSON_AddStringToObject(info->root, "rgb_cmd_tpl", "{{'#%02x%02x%02x0000'|format(red,green,blue)}}"); //rgb_command_template
cJSON_AddStringToObject(info->root, "rgb_val_tpl", "{{ value[0:2]|int(base=16) }},{{ value[2:4]|int(base=16) }},{{ value[4:6]|int(base=16) }}"); //rgb_value_template
@ -207,11 +229,11 @@ HassDeviceInfo* hass_init_light_device_info(ENTITY_TYPE type) {
cJSON_AddStringToObject(info->root, "rgb_cmd_t", g_hassBuffer); //rgb_command_topic
break;
case ENTITY_LIGHT_PWM:
case LIGHT_PWM:
brightness_scale = 100;
break;
case ENTITY_LIGHT_PWMCW:
case LIGHT_PWMCW:
brightness_scale = 100;
//Using `last` (the default) will send any style (brightness, color, etc) topics first and then a payload_on to the command_topic.
@ -224,7 +246,7 @@ HassDeviceInfo* hass_init_light_device_info(ENTITY_TYPE type) {
addLogAdv(LOG_ERROR, LOG_FEATURE_HASS, "Unsupported light type %s", type);
}
if ((type == ENTITY_LIGHT_PWMCW) || (type == ENTITY_LIGHT_RGBCW)) {
if ((type == LIGHT_PWMCW) || (type == LIGHT_RGBCW)) {
sprintf(g_hassBuffer, "cmnd/%s/led_temperature", clientId);
cJSON_AddStringToObject(info->root, "clr_temp_cmd_t", g_hassBuffer); //color_temp_command_topic
@ -248,7 +270,7 @@ HassDeviceInfo* hass_init_light_device_info(ENTITY_TYPE type) {
/// @param index
/// @return
HassDeviceInfo* hass_init_binary_sensor_device_info(int index) {
HassDeviceInfo* info = hass_init_device_info(ENTITY_BINARY_SENSOR, index, "1", "0");
HassDeviceInfo* info = hass_init_device_info(BINARY_SENSOR, index, "1", "0");
sprintf(g_hassBuffer, "~/%i/get", index);
cJSON_AddStringToObject(info->root, STATE_TOPIC_KEY, g_hassBuffer); //state_topic
@ -258,11 +280,11 @@ HassDeviceInfo* hass_init_binary_sensor_device_info(int index) {
#ifndef OBK_DISABLE_ALL_DRIVERS
/// @brief Initializes HomeAssistant sensor device discovery storage.
/// @brief Initializes HomeAssistant power sensor device discovery storage.
/// @param index Index corresponding to sensor_mqttNames.
/// @return
HassDeviceInfo* hass_init_sensor_device_info(int index) {
HassDeviceInfo* info = hass_init_device_info(ENTITY_SENSOR, index, NULL, NULL);
HassDeviceInfo* hass_init_power_sensor_device_info(int index) {
HassDeviceInfo* info = hass_init_device_info(POWER_SENSOR, index, NULL, NULL);
//https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes
//device_class automatically assigns unit,icon
@ -296,6 +318,40 @@ HassDeviceInfo* hass_init_sensor_device_info(int index) {
#endif
/// @brief Initializes HomeAssistant sensor device discovery storage.
/// @param type
/// @param channel
/// @return
HassDeviceInfo* hass_init_sensor_device_info(ENTITY_TYPE type, int channel) {
//Assuming that there is only one DHT setup per device which keeps uniqueid/names simpler
HassDeviceInfo* info = hass_init_device_info(type, channel, NULL, NULL); //using channel as index to generate uniqueId
//https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes
switch (type) {
case TEMPERATURE_SENSOR:
cJSON_AddStringToObject(info->root, "dev_cla", "temperature");
cJSON_AddStringToObject(info->root, "unit_of_meas", "°C");
//https://www.home-assistant.io/integrations/sensor.mqtt/ refers to value_template (val_tpl)
//{{ float(value)*0.1 }} for value=12 give 1.2000000000000002, using round() to limit the decimal places
cJSON_AddStringToObject(info->root, "val_tpl", "{{ float(value)*0.1|round(2) }}");
break;
case HUMIDITY_SENSOR:
cJSON_AddStringToObject(info->root, "dev_cla", "humidity");
cJSON_AddStringToObject(info->root, "unit_of_meas", "%");
break;
default:
return NULL;
}
sprintf(g_hassBuffer, "~/%d/get", channel);
cJSON_AddStringToObject(info->root, STATE_TOPIC_KEY, g_hassBuffer);
cJSON_AddStringToObject(info->root, "stat_cla", "measurement");
return info;
}
/// @brief Returns the discovery JSON.
/// @param info
/// @return

View File

@ -6,25 +6,30 @@
typedef enum {
/// @brief Switch
ENTITY_RELAY = 0,
RELAY = 0,
/// @brief Single PWM
ENTITY_LIGHT_PWM,
LIGHT_PWM,
/// @brief 2 PWM setup (brightness and temperature)
ENTITY_LIGHT_PWMCW,
LIGHT_PWMCW,
/// @brief RGB (3 PWM)
ENTITY_LIGHT_RGB,
LIGHT_RGB,
/// @brief RGB + temperature (5 PWM or LED driver)
ENTITY_LIGHT_RGBCW,
LIGHT_RGBCW,
/// @brief Sensor (voltage, current, power)
ENTITY_SENSOR,
/// @brief Power sensors (voltage, current, power)
POWER_SENSOR,
/// @Brief Binary Sensor
ENTITY_BINARY_SENSOR
BINARY_SENSOR,
/// @brief Temperature sensor
TEMPERATURE_SENSOR,
/// @brief Humidity sensor
HUMIDITY_SENSOR
} ENTITY_TYPE;
//unique_id is defined in hass_populate_unique_id and is based on CFG_GetDeviceName() whose size is CGF_DEVICE_NAME_SIZE.
@ -52,7 +57,8 @@ typedef struct HassDeviceInfo_s {
void hass_print_unique_id(http_request_t* request, const char* fmt, ENTITY_TYPE type, int index);
HassDeviceInfo* hass_init_relay_device_info(int index);
HassDeviceInfo* hass_init_light_device_info(ENTITY_TYPE type);
HassDeviceInfo* hass_init_sensor_device_info(int index);
HassDeviceInfo* hass_init_power_sensor_device_info(int index);
HassDeviceInfo* hass_init_binary_sensor_device_info(int index);
HassDeviceInfo* hass_init_sensor_device_info(ENTITY_TYPE type, int channel);
char* hass_build_discovery_json(HassDeviceInfo* info);
void hass_free_device_info(HassDeviceInfo* info);

View File

@ -1584,31 +1584,19 @@ void doHomeAssistantDiscovery(const char *topic, http_request_t *request) {
HassDeviceInfo* dev_info = NULL;
bool measuringPower = false;
struct cJSON_Hooks hooks;
bool discoveryQueued = false;
if (topic == 0 || *topic == 0) {
topic = "homeassistant";
}
#ifndef OBK_DISABLE_ALL_DRIVERS
measuringPower = DRV_IsMeasuringPower();
#endif
get_Relay_PWM_Count(&relayCount, &pwmCount, &dInputCount);
//Note: PublishChannels should be done for the last MQTT publish except for power measurement which always
//sends out MQTT updates.
ledDriverChipRunning = LED_IsLedDriverChipRunning();
if ((relayCount == 0) && (pwmCount == 0) && (dInputCount == 0) && !measuringPower && !ledDriverChipRunning) {
const char *msg = "No relay, PWM, binary sensor or power driver running.";
if (request) {
poststr(request, msg);
poststr(request, NULL);
}
else {
addLogAdv(LOG_ERROR, LOG_FEATURE_HTTP, "HA discovery: %s\r\n", msg);
}
return;
}
ledDriverChipRunning = LED_IsLedDriverChipRunning();
hooks.malloc_fn = os_malloc;
hooks.free_fn = os_free;
@ -1617,56 +1605,30 @@ void doHomeAssistantDiscovery(const char *topic, http_request_t *request) {
if (relayCount > 0) {
for (i = 0; i < CHANNEL_MAX; i++) {
if (h_isChannelRelay(i)) {
if (dev_info != NULL) {
MQTT_QueuePublish(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN);
hass_free_device_info(dev_info);
}
dev_info = hass_init_relay_device_info(i);
MQTT_QueuePublish(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN);
hass_free_device_info(dev_info);
discoveryQueued = true;
}
}
//Invoke publishChannles after the last topic
if (dev_info != NULL) {
PostPublishCommands ppCommand = PublishChannels;
if (ledDriverChipRunning || (pwmCount > 0)) {
ppCommand = None;
}
MQTT_QueuePublishWithCommand(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN, ppCommand);
hass_free_device_info(dev_info);
}
}
if (dInputCount > 0) {
for (i = 0; i < CHANNEL_MAX; i++) {
if (h_isChannelDigitalInput(i)) {
if (dev_info != NULL) {
MQTT_QueuePublish(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN);
hass_free_device_info(dev_info);
}
dev_info = hass_init_binary_sensor_device_info(i);
MQTT_QueuePublish(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN);
hass_free_device_info(dev_info);
discoveryQueued = true;
}
}
//Invoke publishChannels after the last topic
if (dev_info != NULL) {
PostPublishCommands ppCommand = PublishChannels;
if (ledDriverChipRunning || (pwmCount > 0)) {
ppCommand = None;
}
MQTT_QueuePublishWithCommand(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN, ppCommand);
hass_free_device_info(dev_info);
}
}
if (pwmCount == 5 || ledDriverChipRunning) {
// Enable + RGB control + CW control
dev_info = hass_init_light_device_info(ENTITY_LIGHT_RGBCW);
MQTT_QueuePublishWithCommand(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN, PublishChannels);
MQTT_QueuePublish(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN);
hass_free_device_info(dev_info);
discoveryQueued = true;
}
else if (pwmCount > 0) {
if (pwmCount == 4) {
@ -1674,19 +1636,20 @@ void doHomeAssistantDiscovery(const char *topic, http_request_t *request) {
}
else if (pwmCount == 3) {
// Enable + RGB control
dev_info = hass_init_light_device_info(ENTITY_LIGHT_RGB);
dev_info = hass_init_light_device_info(LIGHT_RGB);
}
else if (pwmCount == 2) {
// PWM + Temperature (https://github.com/openshwprojects/OpenBK7231T_App/issues/279)
dev_info = hass_init_light_device_info(ENTITY_LIGHT_PWMCW);
dev_info = hass_init_light_device_info(LIGHT_PWMCW);
}
else {
dev_info = hass_init_light_device_info(ENTITY_LIGHT_PWM);
dev_info = hass_init_light_device_info(LIGHT_PWM);
}
if (dev_info != NULL) {
MQTT_QueuePublishWithCommand(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN, PublishChannels);
MQTT_QueuePublish(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN);
hass_free_device_info(dev_info);
discoveryQueued = true;
}
}
@ -1694,12 +1657,41 @@ void doHomeAssistantDiscovery(const char *topic, http_request_t *request) {
if (measuringPower == true) {
for (i = 0; i < OBK_NUM_SENSOR_COUNT; i++)
{
dev_info = hass_init_sensor_device_info(i);
dev_info = hass_init_power_sensor_device_info(i);
MQTT_QueuePublish(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN);
hass_free_device_info(dev_info);
discoveryQueued = true;
}
}
#endif
for (i = 0; i < PLATFORM_GPIO_MAX; i++) {
if (IS_PIN_DHT_ROLE(g_cfg.pins.roles[i])) {
dev_info = hass_init_sensor_device_info(TEMPERATURE_SENSOR, PIN_GetPinChannelForPinIndex(i));
MQTT_QueuePublish(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN);
hass_free_device_info(dev_info);
dev_info = hass_init_sensor_device_info(HUMIDITY_SENSOR, PIN_GetPinChannel2ForPinIndex(i));
MQTT_QueuePublish(topic, dev_info->channel, hass_build_discovery_json(dev_info), OBK_PUBLISH_FLAG_RETAIN);
hass_free_device_info(dev_info);
discoveryQueued = true;
}
}
if (discoveryQueued) {
MQTT_InvokeCommandAtEnd(PublishChannels);
}
else {
const char *msg = "No relay, PWM, sensor or power driver running.";
if (request) {
poststr(request, msg);
poststr(request, NULL);
}
else {
addLogAdv(LOG_ERROR, LOG_FEATURE_HTTP, "HA discovery: %s\r\n", msg);
}
}
}
/// @brief Sends HomeAssistant discovery MQTT messages.
@ -1803,7 +1795,7 @@ int http_fn_ha_cfg(http_request_t* request) {
switchAdded = 1;
}
hass_print_unique_id(request, " - unique_id: \"%s\"\n", ENTITY_RELAY, i);
hass_print_unique_id(request, " - unique_id: \"%s\"\n", RELAY, i);
hprintf255(request, " name: \"%s %i\"\n", shortDeviceName, i);
hprintf255(request, " state_topic: \"%s/%i/get\"\n", clientId, i);
hprintf255(request, " command_topic: \"%s/%i/set\"\n", clientId, i);
@ -1828,7 +1820,7 @@ int http_fn_ha_cfg(http_request_t* request) {
switchAdded = 1;
}
hass_print_unique_id(request, " - unique_id: \"%s\"\n", ENTITY_BINARY_SENSOR, i);
hass_print_unique_id(request, " - unique_id: \"%s\"\n", BINARY_SENSOR, i);
hprintf255(request, " name: \"%s %i\"\n", shortDeviceName, i);
hprintf255(request, " state_topic: \"%s/%i/get\"\n", clientId, i);
poststr(request, " qos: 1\n");
@ -1851,7 +1843,7 @@ int http_fn_ha_cfg(http_request_t* request) {
switchAdded = 1;
}
hass_print_unique_id(request, " - unique_id: \"%s\"\n", ENTITY_LIGHT_RGBCW, i);
hass_print_unique_id(request, " - unique_id: \"%s\"\n", LIGHT_RGBCW, i);
hprintf255(request, " name: \"%s %i\"\n", shortDeviceName, i);
http_generate_rgb_cfg(request, clientId);
hprintf255(request, " #brightness_value_template: \"{{ value }}\"\n");
@ -1871,7 +1863,7 @@ int http_fn_ha_cfg(http_request_t* request) {
switchAdded = 1;
}
hass_print_unique_id(request, " - unique_id: \"%s\"\n", ENTITY_LIGHT_RGB, i);
hass_print_unique_id(request, " - unique_id: \"%s\"\n", LIGHT_RGB, i);
hprintf255(request, " name: \"%s\"\n", shortDeviceName);
http_generate_rgb_cfg(request, clientId);
}
@ -1886,7 +1878,7 @@ int http_fn_ha_cfg(http_request_t* request) {
switchAdded = 1;
}
hass_print_unique_id(request, " - unique_id: \"%s\"\n", ENTITY_LIGHT_PWM, i);
hass_print_unique_id(request, " - unique_id: \"%s\"\n", LIGHT_PWM, i);
hprintf255(request, " name: \"%s\"\n", shortDeviceName);
http_generate_singleColor_cfg(request, clientId);
}
@ -1901,7 +1893,7 @@ int http_fn_ha_cfg(http_request_t* request) {
switchAdded = 1;
}
hass_print_unique_id(request, " - unique_id: \"%s\"\n", ENTITY_LIGHT_PWMCW, i);
hass_print_unique_id(request, " - unique_id: \"%s\"\n", LIGHT_PWMCW, i);
hprintf255(request, " name: \"%s\"\n", shortDeviceName);
http_generate_cw_cfg(request, clientId);
}
@ -1918,7 +1910,7 @@ int http_fn_ha_cfg(http_request_t* request) {
lightAdded = 1;
}
hass_print_unique_id(request, " - unique_id: \"%s\"\n", ENTITY_LIGHT_PWM, i);
hass_print_unique_id(request, " - unique_id: \"%s\"\n", LIGHT_PWM, i);
hprintf255(request, " name: \"%s %i\"\n", shortDeviceName, i);
hprintf255(request, " state_topic: \"%s/%i/get\"\n", clientId, i);
hprintf255(request, " command_topic: \"%s/%i/set\"\n", clientId, i);
@ -2686,10 +2678,7 @@ int http_fn_cfg_pins(http_request_t* request) {
poststr(request, "</select>");
hprintf255(request, "<input class=\"hele\" name=\"r%i\" type=\"text\" value=\"%i\"/>", i, ch);
if (si == IOR_Button || si == IOR_Button_n
|| si == IOR_DHT11 || si == IOR_DHT22
|| si == IOR_DHT12 || si == IOR_DHT21
)
if (si == IOR_Button || si == IOR_Button_n || IS_PIN_DHT_ROLE(si))
{
// extra param. For button, is relay index to toggle on double click
hprintf255(request, "<input class=\"hele\" name=\"e%i\" type=\"text\" value=\"%i\"/>", i, ch2);