diff --git a/wled00/wled17_mqtt.ino b/wled00/wled17_mqtt.ino index 191e70ff6..0deca78c6 100644 --- a/wled00/wled17_mqtt.ino +++ b/wled00/wled17_mqtt.ino @@ -44,6 +44,8 @@ void onMqttConnect(bool sessionPresent) strcat(subuf, "/api"); mqtt->subscribe(subuf, 0); } + + sendHADiscoveryMQTT(); publishMqtt(); } @@ -95,6 +97,245 @@ void publishMqtt() mqtt->publish(subuf, 0, true, apires); } +void sendHADiscoveryMQTT(){ +/* + +YYYY is discovery tipic +XXXX is device name + +Send out HA MQTT Discovery message on MQTT connect (~2.4kB): +{ +"name": "XXXX", +"stat_t":"YYYY/c", +"cmd_t":"YYYY", +"rgb_stat_t":"YYYY/c", +"rgb_cmd_t":"YYYY/col", +"bri_cmd_t":"YYYY", +"bri_stat_t":"YYYY/g", +"bri_val_tpl":"{{value}}", +"rgb_cmd_tpl":"{{'#%02x%02x%02x' | format(red, green, blue)}}", +"rgb_val_tpl":"{{value[1:3]|int(base=16)}},{{value[3:5]|int(base=16)}},{{value[5:7]|int(base=16)}}", +"qos": 0, +"opt":true, +"pl_on": "ON", +"pl_off": "OFF", +"fx_cmd_t":"YYYY/api", +"fx_stat_t":"YYYY/api", +"fx_val_tpl":"{{value}}", +"fx_list":[ +"[FX=00] STATIC", +"[FX=01] BLINK", +"[FX=02] BREATH", +"[FX=03] COLOR_WIPE", +"[FX=04] COLOR_WIPE_RANDOM", +"[FX=05] RANDOM_COLOR", +"[FX=06] COLOR_SWEEP", +"[FX=07] DYNAMIC", +"[FX=08] RAINBOW", +"[FX=09] RAINBOW_CYCLE", +"[FX=10] SCAN", +"[FX=11] DUAL_SCAN", +"[FX=12] FADE", +"[FX=13] THEATER_CHASE", +"[FX=14] THEATER_C_RAINBOW", +"[FX=15] RUNNING_LIGHTS", +"[FX=16] SAW", +"[FX=17] TWINKLE", +"[FX=18] DISSOLVE", +"[FX=19] DISSOLVE_RANDOM", +"[FX=20] SPARKLE", +"[FX=21] FLASH_SPARKLE", +"[FX=22] HYPER_SPARKLE", +"[FX=23] STROBE", +"[FX=24] STROBE_RAINBOW", +"[FX=25] MULTI_STROBE", +"[FX=26] BLINK_RAINBOW", +"[FX=27] ANDROID", +"[FX=28] CHASE_COLOR", +"[FX=29] CHASE_RANDOM", +"[FX=30] CHASE_RAINBOW", +"[FX=31] CHASE_FLASH", +"[FX=32] CHASE_FLASH_RANDOM", +"[FX=33] CHASE_RAINBOW_WHITE", +"[FX=34] COLORFUL", +"[FX=35] TRAFFIC_LIGHT", +"[FX=36] COLOR_SWEEP_RANDOM", +"[FX=37] RUNNING_COLOR", +"[FX=38] RUNNING_RED_BLUE", +"[FX=39] RUNNING_RANDOM", +"[FX=40] LARSON_SCANNER", +"[FX=41] COMET", +"[FX=42] FIREWORKS", +"[FX=43] RAIN", +"[FX=44] MERRY_CHRISTMAS", +"[FX=45] FIRE_FLICKER", +"[FX=46] GRADIENT", +"[FX=47] LOADING", +"[FX=48] DUAL_COLOR_WIPE_IN_OUT", +"[FX=49] DUAL_COLOR_WIPE_IN_IN", +"[FX=50] DUAL_COLOR_WIPE_OUT_OUT", +"[FX=51] DUAL_COLOR_WIPE_OUT_IN", +"[FX=52] CIRCUS_COMBUSTUS", +"[FX=53] HALLOWEEN", +"[FX=54] TRICOLOR_CHASE", +"[FX=55] TRICOLOR_WIPE", +"[FX=56] TRICOLOR_FADE", +"[FX=57] LIGHTNING", +"[FX=58] ICU", +"[FX=59] MULTI_COMET", +"[FX=60] DUAL_LARSON_SCANNER", +"[FX=61] RANDOM_CHASE", +"[FX=62] OSCILLATE", +"[FX=63] PRIDE_2015", +"[FX=64] JUGGLE", +"[FX=65] PALETTE", +"[FX=66] FIRE_2012", +"[FX=67] COLORWAVES", +"[FX=68] BPM", +"[FX=69] FILLNOISE8", +"[FX=70] NOISE16_1", +"[FX=71] NOISE16_2", +"[FX=72] NOISE16_3", +"[FX=73] NOISE16_4", +"[FX=74] COLORTWINKLE", +"[FX=75] LAKE", +"[FX=76] METEOR", +"[FX=77] METEOR_SMOOTH", +"[FX=78] RAILWAY", +"[FX=79] RIPPLE" +] + +} + + */ + char bufc[38], bufcol[38], bufg[38], bufapi[38]; + + strcpy(bufc, mqttDeviceTopic); + strcpy(bufcol, mqttDeviceTopic); + strcpy(bufg, mqttDeviceTopic); + strcpy(bufapi, mqttDeviceTopic); + + strcat(bufc, "/c"); + strcat(bufcol, "/col"); + strcat(bufg, "/g"); + strcat(bufapi, "/api"); + + + DynamicJsonBuffer jsonBuffer(JSON_ARRAY_SIZE(80) + JSON_OBJECT_SIZE(18) + 3000); + JsonObject& root = jsonBuffer.createObject(); + root["name"] = serverDescription; + root["stat_t"] = bufc; + root["cmd_t"] = mqttDeviceTopic; + root["rgb_stat_t"] = bufc; + root["rgb_cmd_t"] = bufcol; + root["bri_cmd_t"] = mqttDeviceTopic; + root["bri_stat_t"] = bufg; + root["bri_val_tpl"] = "{{value}}"; + root["rgb_cmd_tpl"] = "{{'#%02x%02x%02x' | format(red, green, blue)}}"; + root["rgb_val_tpl"] = "{{value[1:3]|int(base=16)}},{{value[3:5]|int(base=16)}},{{value[5:7]|int(base=16)}}"; + root["qos"] = 0; + root["opt"] = true; + root["pl_on"] = "ON"; + root["pl_off"] = "OFF"; + root["fx_cmd_t"] = bufapi; + root["fx_stat_t"] = bufapi; + root["fx_val_tpl"] = "{{value}}"; + + JsonArray& fx_list = root.createNestedArray("fx_list"); + // There should be a better way to do this like a for loop but there is no WS2812FX::getModeCount() or WS2812FX::getModeName(), instead there is "JSON_mode_names" + fx_list.add("[FX=00] STATIC"); + fx_list.add("[FX=01] BLINK"); + fx_list.add("[FX=02] BREATH"); + fx_list.add("[FX=03] COLOR_WIPE"); + fx_list.add("[FX=04] COLOR_WIPE_RANDOM"); + fx_list.add("[FX=05] RANDOM_COLOR"); + fx_list.add("[FX=06] COLOR_SWEEP"); + fx_list.add("[FX=07] DYNAMIC"); + fx_list.add("[FX=08] RAINBOW"); + fx_list.add("[FX=09] RAINBOW_CYCLE"); + fx_list.add("[FX=10] SCAN"); + fx_list.add("[FX=11] DUAL_SCAN"); + fx_list.add("[FX=12] FADE"); + fx_list.add("[FX=13] THEATER_CHASE"); + fx_list.add("[FX=14] THEATER_C_RAINBOW"); + fx_list.add("[FX=15] RUNNING_LIGHTS"); + fx_list.add("[FX=16] SAW"); + fx_list.add("[FX=17] TWINKLE"); + fx_list.add("[FX=18] DISSOLVE"); + fx_list.add("[FX=19] DISSOLVE_RANDOM"); + fx_list.add("[FX=20] SPARKLE"); + fx_list.add("[FX=21] FLASH_SPARKLE"); + fx_list.add("[FX=22] HYPER_SPARKLE"); + fx_list.add("[FX=23] STROBE"); + fx_list.add("[FX=24] STROBE_RAINBOW"); + fx_list.add("[FX=25] MULTI_STROBE"); + fx_list.add("[FX=26] BLINK_RAINBOW"); + fx_list.add("[FX=27] ANDROID"); + fx_list.add("[FX=28] CHASE_COLOR"); + fx_list.add("[FX=29] CHASE_RANDOM"); + fx_list.add("[FX=30] CHASE_RAINBOW"); + fx_list.add("[FX=31] CHASE_FLASH"); + fx_list.add("[FX=32] CHASE_FLASH_RANDOM"); + fx_list.add("[FX=33] CHASE_RAINBOW_WHITE"); + fx_list.add("[FX=34] COLORFUL"); + fx_list.add("[FX=35] TRAFFIC_LIGHT"); + fx_list.add("[FX=36] COLOR_SWEEP_RANDOM"); + fx_list.add("[FX=37] RUNNING_COLOR"); + fx_list.add("[FX=38] RUNNING_RED_BLUE"); + fx_list.add("[FX=39] RUNNING_RANDOM"); + fx_list.add("[FX=40] LARSON_SCANNER"); + fx_list.add("[FX=41] COMET"); + fx_list.add("[FX=42] FIREWORKS"); + fx_list.add("[FX=43] RAIN"); + fx_list.add("[FX=44] MERRY_CHRISTMAS"); + fx_list.add("[FX=45] FIRE_FLICKER"); + fx_list.add("[FX=46] GRADIENT"); + fx_list.add("[FX=47] LOADING"); + fx_list.add("[FX=48] DUAL_COLOR_WIPE_IN_OUT"); + fx_list.add("[FX=49] DUAL_COLOR_WIPE_IN_IN"); + fx_list.add("[FX=50] DUAL_COLOR_WIPE_OUT_OUT"); + fx_list.add("[FX=51] DUAL_COLOR_WIPE_OUT_IN"); + fx_list.add("[FX=52] CIRCUS_COMBUSTUS"); + fx_list.add("[FX=53] HALLOWEEN"); + fx_list.add("[FX=54] TRICOLOR_CHASE"); + fx_list.add("[FX=55] TRICOLOR_WIPE"); + fx_list.add("[FX=56] TRICOLOR_FADE"); + fx_list.add("[FX=57] LIGHTNING"); + fx_list.add("[FX=58] ICU"); + fx_list.add("[FX=59] MULTI_COMET"); + fx_list.add("[FX=60] DUAL_LARSON_SCANNER"); + fx_list.add("[FX=61] RANDOM_CHASE"); + fx_list.add("[FX=62] OSCILLATE"); + fx_list.add("[FX=63] PRIDE_2015"); + fx_list.add("[FX=64] JUGGLE"); + fx_list.add("[FX=65] PALETTE"); + fx_list.add("[FX=66] FIRE_2012"); + fx_list.add("[FX=67] COLORWAVES"); + fx_list.add("[FX=68] BPM"); + fx_list.add("[FX=69] FILLNOISE8"); + fx_list.add("[FX=70] NOISE16_1"); + fx_list.add("[FX=71] NOISE16_2"); + fx_list.add("[FX=72] NOISE16_3"); + fx_list.add("[FX=73] NOISE16_4"); + fx_list.add("[FX=74] COLORTWINKLE"); + fx_list.add("[FX=75] LAKE"); + fx_list.add("[FX=76] METEOR"); + fx_list.add("[FX=77] METEOR_SMOOTH"); + fx_list.add("[FX=78] RAILWAY"); + fx_list.add("[FX=79] RIPPLE"); + + size_t jlen = root.measureLength() + 1; + char buffer[jlen], pubt[21 + sizeof(serverDescription) + 8]; + root.printTo(buffer, jlen); + + DEBUG_PRINT("HA Discovery Sending >>"); + DEBUG_PRINTLN(buffer); + + strcpy(pubt, "homeassistant/light/"); + strcat(pubt, serverDescription); + strcat(pubt, "/config"); + mqtt->publish(pubt, 0, true, buffer); +} bool initMqtt() {