Browse Source

Show home assistant configuration in web UI

pull/611/head
Xose Pérez 6 years ago
parent
commit
207f58f0e9
6 changed files with 2960 additions and 2802 deletions
  1. BIN
      code/espurna/data/index.html.gz
  2. +175
    -63
      code/espurna/homeassistant.ino
  3. +2728
    -2722
      code/espurna/static/index.html.gz.h
  4. +2
    -0
      code/html/custom.css
  5. +7
    -0
      code/html/custom.js
  6. +48
    -17
      code/html/index.html

BIN
code/espurna/data/index.html.gz View File


+ 175
- 63
code/espurna/homeassistant.ino View File

@ -14,78 +14,73 @@ bool _haEnabled = false;
bool _haSendFlag = false;
// -----------------------------------------------------------------------------
void _haWebSocketOnSend(JsonObject& root) {
root["haVisible"] = 1;
root["haPrefix"] = getSetting("haPrefix", HOMEASSISTANT_PREFIX);
root["haEnabled"] = getSetting("haEnabled", HOMEASSISTANT_ENABLED).toInt() == 1;
}
// SENSORS
// -----------------------------------------------------------------------------
#if SENSOR_SUPPORT
void _haSendMagnitude(unsigned char i) {
String output;
void _haSendMagnitude(unsigned char i, JsonObject& config) {
if (_haEnabled) {
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
unsigned char type = magnitudeType(i);
config["name"] = getSetting("hostname") + String(" ") + magnitudeTopic(type);
config["platform"] = "mqtt";
config["device_class"] = "sensor";
config["state_topic"] = mqttTopic(magnitudeTopicIndex(i).c_str(), false);
config["unit_of_measurement"] = magnitudeUnits(type);
}
root["device_class"] = "sensor";
root["name"] = getSetting("hostname") + String(" ") + magnitudeTopic(type);
root["state_topic"] = mqttTopic(magnitudeTopicIndex(i).c_str(), false);
root["unit_of_measurement"] = magnitudeUnits(type);
}
root.printTo(output);
void _haSendMagnitudes() {
}
for (unsigned char i=0; i<magnitudeCount(); i++) {
String topic = getSetting("haPrefix", HOMEASSISTANT_PREFIX) +
"/sensor/" +
getSetting("hostname") + "_" + String(i) +
"/config";
DynamicJsonBuffer jsonBuffer;
JsonObject& config = jsonBuffer.createObject();
mqttSendRaw(topic.c_str(), output.c_str());
mqttSend(MQTT_TOPIC_STATUS, MQTT_STATUS_ONLINE, true);
_haSendMagnitude(i, config);
}
String topic = getSetting("haPrefix", HOMEASSISTANT_PREFIX) +
"/sensor/" +
getSetting("hostname") + "_" + String(i) +
"/config";
String output;
if (config.size() > 0) config.printTo(output);
mqttSendRaw(topic.c_str(), output.c_str());
mqttSend(MQTT_TOPIC_STATUS, MQTT_STATUS_ONLINE, true);
void _haSendMagnitudes() {
for (unsigned char i=0; i<magnitudeCount(); i++) {
_haSendMagnitude(i);
}
}
#endif
#endif // SENSOR_SUPPORT
void _haSendSwitch(unsigned char i) {
// -----------------------------------------------------------------------------
// SWITCHES & LIGHTS
// -----------------------------------------------------------------------------
String output;
void _haSendSwitch(unsigned char i, JsonObject& config, String &type) {
if (_haEnabled) {
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
String name = getSetting("hostname");
if (relayCount() > 1) {
name += String(" switch #") + String(i);
name += String(" #") + String(i);
}
root["name"] = name;
root["platform"] = "mqtt";
config["name"] = name;
config["platform"] = "mqtt";
if (relayCount()) {
root["state_topic"] = mqttTopic(MQTT_TOPIC_RELAY, i, false);
root["command_topic"] = mqttTopic(MQTT_TOPIC_RELAY, i, true);
root["payload_on"] = String("1");
root["payload_off"] = String("0");
root["availability_topic"] = mqttTopic(MQTT_TOPIC_STATUS, false);
root["payload_available"] = String("1");
root["payload_not_available"] = String("0");
config["state_topic"] = mqttTopic(MQTT_TOPIC_RELAY, i, false);
config["command_topic"] = mqttTopic(MQTT_TOPIC_RELAY, i, true);
config["payload_on"] = String("1");
config["payload_off"] = String("0");
config["availability_topic"] = mqttTopic(MQTT_TOPIC_STATUS, false);
config["payload_available"] = String("1");
config["payload_not_available"] = String("0");
}
#if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
@ -93,45 +88,113 @@ void _haSendSwitch(unsigned char i) {
if (i == 0) {
if (lightHasColor()) {
root["brightness_state_topic"] = mqttTopic(MQTT_TOPIC_BRIGHTNESS, false);
root["brightness_command_topic"] = mqttTopic(MQTT_TOPIC_BRIGHTNESS, true);
root["rgb_state_topic"] = mqttTopic(MQTT_TOPIC_COLOR_RGB, false);
root["rgb_command_topic"] = mqttTopic(MQTT_TOPIC_COLOR_RGB, true);
root["color_temp_command_topic"] = mqttTopic(MQTT_TOPIC_MIRED, true);
config["brightness_state_topic"] = mqttTopic(MQTT_TOPIC_BRIGHTNESS, false);
config["brightness_command_topic"] = mqttTopic(MQTT_TOPIC_BRIGHTNESS, true);
config["rgb_state_topic"] = mqttTopic(MQTT_TOPIC_COLOR_RGB, false);
config["rgb_command_topic"] = mqttTopic(MQTT_TOPIC_COLOR_RGB, true);
config["color_temp_command_topic"] = mqttTopic(MQTT_TOPIC_MIRED, true);
}
if (lightChannels() > 3) {
root["white_value_state_topic"] = mqttTopic(MQTT_TOPIC_CHANNEL, 3, false);
root["white_value_command_topic"] = mqttTopic(MQTT_TOPIC_CHANNEL, 3, true);
config["white_value_state_topic"] = mqttTopic(MQTT_TOPIC_CHANNEL, 3, false);
config["white_value_command_topic"] = mqttTopic(MQTT_TOPIC_CHANNEL, 3, true);
}
}
#endif // LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
root.printTo(output);
}
#if (LIGHT_PROVIDER != LIGHT_PROVIDER_NONE) || (defined(ITEAD_SLAMPHER))
String component = String("light");
type = String("light");
#else
String component = String("switch");
type = String("switch");
#endif
String topic = getSetting("haPrefix", HOMEASSISTANT_PREFIX) +
"/" + component +
"/" + getSetting("hostname") + "_" + String(i) +
"/config";
}
void _haSendSwitches() {
for (unsigned char i=0; i<relayCount(); i++) {
DynamicJsonBuffer jsonBuffer;
JsonObject& config = jsonBuffer.createObject();
String type;
mqttSendRaw(topic.c_str(), output.c_str());
mqttSend(MQTT_TOPIC_STATUS, MQTT_STATUS_ONLINE, true);
_haSendSwitch(i, config, type);
String topic = getSetting("haPrefix", HOMEASSISTANT_PREFIX) +
"/" + type +
"/" + getSetting("hostname") + "_" + String(i) +
"/config";
String output;
if (config.size() > 0) config.printTo(output);
mqttSendRaw(topic.c_str(), output.c_str());
mqttSend(MQTT_TOPIC_STATUS, MQTT_STATUS_ONLINE, true);
}
}
void _haSendSwitches() {
// -----------------------------------------------------------------------------
String _haGetConfig() {
String output;
for (unsigned char i=0; i<relayCount(); i++) {
_haSendSwitch(i);
DynamicJsonBuffer jsonBuffer;
JsonObject& config = jsonBuffer.createObject();
String type;
_haSendSwitch(i, config, type);
output += "\n" + type + ":\n";
bool first = true;
for (auto kv : config) {
if (first) {
output += " - ";
first = false;
} else {
output += " ";
}
output += kv.key + String(": ") + kv.value.as<String>() + String("\n");
}
output += "\n";
}
#if SENSOR_SUPPORT
for (unsigned char i=0; i<magnitudeCount(); i++) {
DynamicJsonBuffer jsonBuffer;
JsonObject& config = jsonBuffer.createObject();
_haSendMagnitude(i, config);
output += "\nsensor:\n";
bool first = true;
for (auto kv : config) {
if (first) {
output += " - ";
first = false;
} else {
output += " ";
}
output += kv.key + String(": ") + kv.value.as<String>() + String("\n");
}
output += "\n";
}
#endif
return output;
}
void _haSend() {
@ -161,6 +224,49 @@ void _haConfigure() {
_haSend();
}
#if WEB_SUPPORT
void _haWebSocketOnSend(JsonObject& root) {
root["haVisible"] = 1;
root["haPrefix"] = getSetting("haPrefix", HOMEASSISTANT_PREFIX);
root["haEnabled"] = getSetting("haEnabled", HOMEASSISTANT_ENABLED).toInt() == 1;
}
void _haWebSocketOnAction(uint32_t client_id, const char * action, JsonObject& data) {
if (strcmp(action, "haconfig") == 0) {
String output = _haGetConfig();
output.replace(" ", "&nbsp;");
output.replace("\n", "<br />");
output = String("{\"haConfig\": \"") + output + String("\"}");
wsSend(client_id, output.c_str());
}
}
#endif
#if TERMINAL_SUPPORT
void _haInitCommands() {
settingsRegisterCommand(F("HA.CONFIG"), [](Embedis* e) {
DEBUG_MSG(_haGetConfig().c_str());
DEBUG_MSG_P(PSTR("+OK\n"));
});
settingsRegisterCommand(F("HA.SEND"), [](Embedis* e) {
setSetting("haEnabled", "1");
_haConfigure();
wsSend(_haWebSocketOnSend);
DEBUG_MSG_P(PSTR("+OK\n"));
});
settingsRegisterCommand(F("HA.CLEAR"), [](Embedis* e) {
setSetting("haEnabled", "0");
_haConfigure();
wsSend(_haWebSocketOnSend);
DEBUG_MSG_P(PSTR("+OK\n"));
});
}
#endif
// -----------------------------------------------------------------------------
void haSetup() {
@ -170,6 +276,7 @@ void haSetup() {
#if WEB_SUPPORT
wsOnSendRegister(_haWebSocketOnSend);
wsOnAfterParseRegister(_haConfigure);
wsOnActionRegister(_haWebSocketOnAction);
#endif
// On MQTT connect check if we have something to send
@ -177,6 +284,11 @@ void haSetup() {
if (type == MQTT_CONNECT_EVENT) _haSend();
});
#if TERMINAL_SUPPORT
_haInitCommands();
#endif
}
#endif // HOMEASSISTANT_SUPPORT

+ 2728
- 2722
code/espurna/static/index.html.gz.h
File diff suppressed because it is too large
View File


+ 2
- 0
code/html/custom.css View File

@ -160,6 +160,7 @@ div.state {
.button-rfb-learn,
.button-upgrade-browse,
.button-ha-add,
.button-ha-config,
.button-settings-backup,
.button-settings-restore,
.button-apikey {
@ -278,6 +279,7 @@ span.slider {
display: none;
}
#haConfig,
#scanResult {
color: #888;
font-family: 'Courier New', monospace;


+ 7
- 0
code/html/custom.js View File

@ -517,6 +517,12 @@ function doScan() {
return false;
}
function doHAConfig() {
$("#haConfig").html("");
sendAction("haconfig", {});
return false;
}
// -----------------------------------------------------------------------------
// Visualization
// -----------------------------------------------------------------------------
@ -1261,6 +1267,7 @@ $(function() {
$(".button-reboot").on("click", doReboot);
$(".button-reconnect").on("click", doReconnect);
$(".button-wifi-scan").on("click", doScan);
$(".button-ha-config").on("click", doHAConfig);
$(".button-settings-backup").on("click", doBackup);
$(".button-settings-restore").on("click", doRestore);
$(".button-settings-factory").on("click", doFactoryReset);


+ 48
- 17
code/html/index.html View File

@ -118,6 +118,10 @@
<a href="#" class="pure-menu-link" data="panel-domoticz">DOMOTICZ</a>
</li>
<li class="pure-menu-item module module-ha">
<a href="#" class="pure-menu-link" data="panel-ha">HASS</a>
</li>
<li class="pure-menu-item module module-idb">
<a href="#" class="pure-menu-link" data="panel-idb">INFLUXDB</a>
</li>
@ -313,22 +317,6 @@
<div class="pure-u-1 pure-u-lg-1-4"><input type="checkbox" name="alexaEnabled" tabindex="13" /></div>
</div>
<div class="pure-g module module-ha">
<label class="pure-u-1 pure-u-lg-1-4">Home Assistant</label>
<div class="pure-u-1 pure-u-lg-1-4"><input type="checkbox" name="haEnabled" tabindex="14" /></div>
<div class="pure-u-0 pure-u-lg-1-2"></div>
<div class="pure-u-0 pure-u-lg-1-4"></div>
<div class="pure-u-1 pure-u-lg-3-4 hint">
Home Assistant auto-discovery feature. Enable and save to add the device to your HA console.
When using a colour light you might want to disable CSS style so Home Assistant can parse the color.
</div>
</div>
<div class="pure-g module module-ha">
<label class="pure-u-1 pure-u-lg-1-4">Home Assistant Prefix</label>
<input class="pure-u-1 pure-u-lg-1-4" name="haPrefix" type="text" tabindex="15" />
</div>
</fieldset>
</div>
</div>
@ -579,7 +567,7 @@
<div class="pure-g">
<div class="pure-u-0 pure-u-lg-1-4"></div>
<span class="pure-u-1 pure-u-lg-3-4 terminal" id="scanResult" name="scanResult"></span>
<span class="pure-u-1 pure-u-lg-3-4" id="scanResult" name="scanResult"></span>
</div>
<legend>Networks</legend>
@ -810,6 +798,49 @@
</div>
<div class="panel" id="panel-ha">
<div class="header">
<h1>HOME ASSISTANT</h1>
<h2>
Add this device to your Home Assistant.
</h2>
</div>
<div class="page">
<fieldset>
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">Discover</label>
<div class="pure-u-1 pure-u-lg-1-4"><input type="checkbox" name="haEnabled" tabindex="14" /></div>
<div class="pure-u-0 pure-u-lg-1-2"></div>
<div class="pure-u-0 pure-u-lg-1-4"></div>
<div class="pure-u-1 pure-u-lg-3-4 hint">
Home Assistant auto-discovery feature. Enable and save to add the device to your HA console.
When using a colour light you might want to disable CSS style so Home Assistant can parse the color.
</div>
</div>
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">Prefix</label>
<input class="pure-u-1 pure-u-lg-1-4" name="haPrefix" type="text" tabindex="15" />
</div>
<div class="pure-g">
<div class="pure-u-0 pure-u-lg-1-4"></div>
<div class="pure-u-1-2 pure-u-lg-1-4"><button class="pure-button button-ha-config pure-u-23-24">Show HA config</button></div>
<div class="pure-u-0 pure-u-lg-1-4"></div>
<span class="pure-u-1 pure-u-lg-3-4" id="haConfig" name="haConfig"></span>
</div>
</fieldset>
</div>
</div>
<div class="panel" id="panel-thingspeak">
<div class="header">


Loading…
Cancel
Save