Add config for direct MQTT messages to Domoticz

This commit is contained in:
Atle Johansen 2020-04-30 18:56:21 +02:00
parent a78fdc0b59
commit 41784511e9
13 changed files with 602 additions and 9 deletions

View File

@ -178,7 +178,6 @@ void AmsConfiguration::ackMqttChange() {
mqttChanged = false;
}
byte AmsConfiguration::getAuthSecurity() {
return authSecurity;
}
@ -264,7 +263,71 @@ int AmsConfiguration::getDebugLevel() {
void AmsConfiguration::setDebugLevel(int debugLevel) {
this->debugLevel = debugLevel;
}
//
// Domoticz start
//
int AmsConfiguration::getDomoELIDX() {
return domoELIDX;
}
int AmsConfiguration::getDomoVL1IDX() {
return domoVL1IDX;
}
int AmsConfiguration::getDomoVL2IDX() {
return domoVL2IDX;
}
int AmsConfiguration::getDomoVL3IDX() {
return domoVL3IDX;
}
int AmsConfiguration::getDomoCL1IDX() {
return domoCL1IDX;
}
double AmsConfiguration::getDomoEnergy() {
return domoEnergy;
}
void AmsConfiguration::setDomoELIDX(int domoELIDX) {
domoChanged |= this->domoELIDX != domoELIDX;
this->domoELIDX = domoELIDX;
}
void AmsConfiguration::setDomoVL1IDX(int domoVL1IDX) {
domoChanged |= this->domoVL1IDX != domoVL1IDX;
this->domoVL1IDX = domoVL1IDX;
}
void AmsConfiguration::setDomoVL2IDX(int domoVL2IDX) {
domoChanged |= this->domoVL2IDX != domoVL2IDX;
this->domoVL2IDX = domoVL2IDX;
}
void AmsConfiguration::setDomoVL3IDX(int domoVL3IDX) {
domoChanged |= this->domoVL3IDX != domoVL3IDX;
this->domoVL3IDX = domoVL3IDX;
}
void AmsConfiguration::setDomoCL1IDX(int domoCL1IDX) {
domoChanged |= this->domoCL1IDX != domoCL1IDX;
this->domoCL1IDX = domoCL1IDX;
}
void AmsConfiguration::setDomoEnergy(double domoEnergy) {
domoChanged |= this->domoEnergy != domoEnergy;
this->domoEnergy = domoEnergy;
}
void AmsConfiguration::clearDomo() {
setDomoELIDX(0);
setDomoVL1IDX(0);
setDomoVL2IDX(0);
setDomoVL3IDX(0);
setDomoCL1IDX(0);
setDomoEnergy(-1.0);
}
bool AmsConfiguration::isDomoChanged() {
return domoChanged;
}
void AmsConfiguration::ackDomoChange() {
domoChanged = false;
}
//
// Domoticz end
//
bool AmsConfiguration::hasConfig() {
if(configVersion == 0) {
@ -278,6 +341,7 @@ bool AmsConfiguration::hasConfig() {
case 75:
case 80:
case 81:
case 91: // domoticz (based on 81)
return true;
default:
configVersion = 0;
@ -310,6 +374,9 @@ bool AmsConfiguration::load() {
case 81:
success = loadConfig81(address);
break;
case 91:
success = loadConfig91(address);
break;
}
EEPROM.end();
return success;
@ -603,6 +670,128 @@ bool AmsConfiguration::loadConfig81(int address) {
address += readInt(address, &i);
setDebugLevel(i);
bool domo = false;
address += readBool(address, &domo);
ackWifiChange();
return true;
}
//
// domoticz (based on 81)
//
bool AmsConfiguration::loadConfig91(int address) {
char* temp;
address += readString(address, &temp);
setWifiSsid(temp);
address += readString(address, &temp);
setWifiPassword(temp);
bool staticIp = false;
address += readBool(address, &staticIp);
if(staticIp) {
address += readString(address, &temp);
setWifiIp(temp);
address += readString(address, &temp);
setWifiGw(temp);
address += readString(address, &temp);
setWifiSubnet(temp);
address += readString(address, &temp);
setWifiDns1(temp);
address += readString(address, &temp);
setWifiDns2(temp);
}
address += readString(address, &temp);
setWifiHostname(temp);
bool mqtt = false;
address += readBool(address, &mqtt);
if(mqtt) {
address += readString(address, &temp);
setMqttHost(temp);
int port;
address += readInt(address, &port);
setMqttPort(port);
address += readString(address, &temp);
setMqttClientId(temp);
address += readString(address, &temp);
setMqttPublishTopic(temp);
address += readString(address, &temp);
setMqttSubscribeTopic(temp);
bool secure = false;
address += readBool(address, &secure);
if (secure)
{
address += readString(address, &temp);
setMqttUser(temp);
address += readString(address, &temp);
setMqttPassword(temp);
} else {
setMqttUser("");
setMqttPassword("");
}
int payloadFormat;
address += readInt(address, &payloadFormat);
setMqttPayloadFormat(payloadFormat);
} else {
clearMqtt();
}
address += readByte(address, &authSecurity);
if (authSecurity > 0) {
address += readString(address, &temp);
setAuthUser(temp);
address += readString(address, &temp);
setAuthPassword(temp);
} else {
clearAuth();
}
int i;
address += readInt(address, &i);
setMeterType(i);
address += readInt(address, &i);
setDistributionSystem(i);
address += readInt(address, &i);
setMainFuse(i);
address += readInt(address, &i);
setProductionCapacity(i);
bool debugTelnet = false;
address += readBool(address, &debugTelnet);
setDebugTelnet(debugTelnet);
bool debugSerial = false;
address += readBool(address, &debugSerial);
setDebugSerial(debugSerial);
address += readInt(address, &i);
setDebugLevel(i);
bool domo = false;
address += readBool(address, &domo);
if(domo) {
int domoELIDX;
address += readInt(address, &domoELIDX);
setDomoELIDX(domoELIDX);
int domoVL1IDX;
address += readInt(address, &domoVL1IDX);
setDomoVL1IDX(domoVL1IDX);
int domoVL2IDX;
address += readInt(address, &domoVL2IDX);
setDomoVL2IDX(domoVL2IDX);
int domoVL3IDX;
address += readInt(address, &domoVL3IDX);
setDomoVL3IDX(domoVL3IDX);
int domoCL1IDX;
address += readInt(address, &domoCL1IDX);
setDomoCL1IDX(domoCL1IDX);
// address += readString(address, &temp);
// domoEnergy = String(temp).toDouble();
// setDomoEnergy(domoEnergy);
} else {
clearDomo();
}
ackWifiChange();
return true;
@ -661,7 +850,20 @@ bool AmsConfiguration::save() {
address += saveBool(address, debugTelnet);
address += saveBool(address, debugSerial);
address += saveInt(address, debugLevel);
//
// Domoticz
//
if(domoELIDX) {
address += saveBool(address, true);
address += saveInt(address, domoELIDX);
address += saveInt(address, domoVL1IDX);
address += saveInt(address, domoVL2IDX);
address += saveInt(address, domoVL3IDX);
address += saveInt(address, domoCL1IDX);
//address += saveString(address, String(domoEnergy).c_str());
} else {
address += saveBool(address, false);
}
bool success = EEPROM.commit();
EEPROM.end();

View File

@ -78,7 +78,26 @@ public:
void setDebugLevel(int debugLevel);
void print(Print* debugger);
//
// Domoticz
//
int getDomoELIDX();
int getDomoVL1IDX();
int getDomoVL2IDX();
int getDomoVL3IDX();
int getDomoCL1IDX();
double getDomoEnergy();
void setDomoELIDX(int domoELIDX);
void setDomoVL1IDX(int domoVL1IDX);
void setDomoVL2IDX(int domoVL2IDX);
void setDomoVL3IDX(int domoVL3IDX);
void setDomoCL1IDX(int domoCL1IDX);
void setDomoEnergy(double domoEnergy);
void clearDomo();
bool isDomoChanged();
void ackDomoChange();
protected:
private:
@ -113,14 +132,27 @@ private:
bool debugTelnet = false, debugSerial = false;
int debugLevel = 3;
//
// Domoticz
//
int domoELIDX;
int domoVL1IDX;
int domoVL2IDX;
int domoVL3IDX;
int domoCL1IDX;
double domoEnergy = -1.0;
bool domoChanged;
const int EEPROM_SIZE = 512;
const int EEPROM_CHECK_SUM = 81; // Used to check if config is stored. Change if structure changes
const int EEPROM_CHECK_SUM = 91; // Used to check if config is stored. Change if structure changes
const int EEPROM_CONFIG_ADDRESS = 0;
bool loadConfig72(int address);
bool loadConfig75(int address);
bool loadConfig80(int address);
bool loadConfig81(int address);
bool loadConfig91(int address); // domoticz
int saveString(int pAddress, const char* pString);
int readString(int pAddress, char* pString[]);

View File

@ -86,7 +86,7 @@ void setup() {
debugI("Voltage: %.2fV", vcc);
}
#if SELF_POWERED
#if SELF_POWERED
if (vcc > 2.5 && vcc < 3.25) { // Only sleep if voltage is realistic and too low
if(Debug.isActive(RemoteDebug::INFO)) {
debugI("Voltage is too low, sleeping");
@ -94,7 +94,7 @@ void setup() {
}
ESP.deepSleep(10000000); //Deep sleep to allow output cap to charge up
}
#endif
#endif
#if HAS_RGB_LED
// Initialize RGB LED pins
@ -257,6 +257,9 @@ unsigned long lastSuccessfulRead = 0;
unsigned long lastErrorBlink = 0;
int lastError = 0;
// domoticz energy init
double energy = -1.0;
void loop() {
Debug.handle();
unsigned long now = millis();
@ -462,6 +465,154 @@ void readHanPort() {
String msg;
serializeJson(json, msg);
mqtt.publish(config.getMqttPublishTopic(), msg.c_str());
//
// Start DOMOTICZ
//
} else if(config.getMqttPayloadFormat() == 2) {
StaticJsonDocument<512> json;
hanToJson(json, data, hw, temperature);
if (Debug.isActive(RemoteDebug::INFO)) {
debugI("Sending data to MQTT");
if (Debug.isActive(RemoteDebug::DEBUG)) {
serializeJsonPretty(json, Debug);
}
}
String msg;
serializeJson(json, msg);
mqtt.publish(config.getMqttPublishTopic(), msg.c_str()); // keep for now...
//
// Special MQTT messages for DOMOTIZ (https://www.domoticz.com/wiki/MQTT)
// -All messages should be published to topic "domoticz/in"
//
// message msg_PE : send active power and and cumulative energy consuption to virtual meter "Electricity (instant and counter)"
//
// /json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=POWER;ENERGY
//
// MQTT sample message: {"command": "udevice", "idx" : IDX , "nvalue" : 0, "svalue" : "POWER;ENERGY"}
// IDX = id of your device (This number can be found in the devices tab in the column "IDX")
// POWER = current power (Watt)
// ENERGY = cumulative energy in Watt-hours (Wh) This is an incrementing counter.
// (if you choose as type "Energy read : Computed", this is just a "dummy" counter, not updatable because it's the result of DomoticZ calculs from POWER)
//
// message msg_V1 : send Voltage of L1 to virtual Voltage meter
//
// /json.htm?type=command&param=udevice&idx=IDX&nvalue=0&svalue=VOLTAGE
//
// MQTT sample message: {"command": "udevice", "idx" : IDX , "nvalue" : 0, "svalue" : "VOLTAGE"}
// IDX = id of your device (This number can be found in the devices tab in the column "IDX")
// VOLTAGE = Voltage (V)
//
int idx1 = config.getDomoELIDX();
// TODO, this should be configurable....
if (idx1 > 0) {
String PowerEnergy;
int p;
// double energy = config.getDomoEnergy();
double tmp_energy;
StaticJsonDocument<200> json_PE;
p = json["data"]["P"].as<int>();
// cumulative energy is given only once pr hour. check if value is different from 0 and store last valid value on global variable.
tmp_energy = json["data"]["tPI"].as<double>();
if (tmp_energy > 1.0) energy = tmp_energy;
// power_unit: watt, energy_unit: watt*h. Stored as kwh, need watth
PowerEnergy = String((double) p/1.0) + ";" + String((double) energy*1000.0) ;
json_PE["command"] = "udevice";
json_PE["idx"] = idx1;
json_PE["nvalue"] = 0;
json_PE["svalue"] = PowerEnergy;
// Stringify the json
String msg_PE;
serializeJson(json_PE, msg_PE);
// publish power data directly to domoticz/in, but only after first reading of total power, once an hour... . (otherwise total consumtion will be wrong.)
if (energy > 0.0 ) mqtt.publish("domoticz/in", msg_PE.c_str());
}
int idxu1 =config.getDomoVL1IDX();
if (idxu1 > 0){
StaticJsonDocument<200> json_u1;
double u1;
//
// prepare message msg_u1 for virtual Voltage meter"
//
u1 = json["data"]["U1"].as<double>();
if (u1 > 0.1){
json_u1["command"] = "udevice";
json_u1["idx"] = idxu1;
json_u1["nvalue"] = 0;
json_u1["svalue"] = String(u1);
// Stringify the json
String msg_u1;
serializeJson(json_u1, msg_u1);
// publish power data directly to domoticz/in
mqtt.publish("domoticz/in", msg_u1.c_str());
}
}
int idxu2 =config.getDomoVL2IDX();
if (idxu2 > 0){
StaticJsonDocument<200> json_u2;
double u2;
//
// prepare message msg_u2 for virtual Voltage meter"
//
u2 = json["data"]["U2"].as<double>();
if (u2 > 0.1){
json_u2["command"] = "udevice";
json_u2["idx"] = idxu2;
json_u2["nvalue"] = 0;
json_u2["svalue"] = String(u2);
// Stringify the json
String msg_u2;
serializeJson(json_u2, msg_u2);
// publish power data directly to domoticz/in
mqtt.publish("domoticz/in", msg_u2.c_str());
}
}
int idxu3 =config.getDomoVL3IDX();
if (idxu3 > 0){
StaticJsonDocument<200> json_u3;
double u3;
//
// prepare message msg_u3 for virtual Voltage meter"
//
u3 = json["data"]["U3"].as<double>();
if (u3 > 0.1){
json_u3["command"] = "udevice";
json_u3["idx"] = idxu3;
json_u3["nvalue"] = 0;
json_u3["svalue"] = String(u3);
// Stringify the json
String msg_u3;
serializeJson(json_u3, msg_u3);
// publish power data directly to domoticz/in
mqtt.publish("domoticz/in", msg_u3.c_str());
}
}
int idxi1 =config.getDomoCL1IDX();
if (idxi1 > 0){
StaticJsonDocument<200> json_i1;
double i1, i2, i3;
String Ampere3;
//
// prepare message msg_i1 for virtual Current/Ampere 3phase mater"
//
i1 = json["data"]["I1"].as<double>();
i2 = json["data"]["I2"].as<double>();
i3 = json["data"]["I3"].as<double>();
Ampere3 = String(i1) + ";" + String(i2) + ";" + String(i3) ;
json_i1["command"] = "udevice";
json_i1["idx"] = idxi1;
json_i1["nvalue"] = 0;
json_i1["svalue"] = Ampere3;
// Stringify the json
String msg_i1;
serializeJson(json_i1, msg_i1);
// publish power data directly to domoticz/in
if (i1 > 0.0) mqtt.publish("domoticz/in", msg_i1.c_str());
}
//
// End DOMOTICZ
//
} else if(config.getMqttPayloadFormat() == 1) {
mqtt.publish(config.getMqttPublishTopic() + "/meter/dlms/timestamp", String(data.getPackageTimestamp()));
switch(data.getListType()) {

View File

@ -6,6 +6,7 @@
#include "root/configwifi_html.h"
#include "root/configmqtt_html.h"
#include "root/configweb_html.h"
#include "root/configdomoticz_html.h"
#include "root/configsystem_html.h"
#include "root/restartwait_html.h"
#include "root/boot_css.h"
@ -26,6 +27,7 @@ void AmsWebServer::setup(AmsConfiguration* config, MQTTClient* mqtt) {
server.on("/config-wifi", HTTP_GET, std::bind(&AmsWebServer::configWifiHtml, this));
server.on("/config-mqtt", HTTP_GET, std::bind(&AmsWebServer::configMqttHtml, this));
server.on("/config-web", HTTP_GET, std::bind(&AmsWebServer::configWebHtml, this));
server.on("/config-domoticz",HTTP_GET, std::bind(&AmsWebServer::configDomoticzHtml, this));
server.on("/boot.css", HTTP_GET, std::bind(&AmsWebServer::bootCss, this));
server.on("/gaugemeter.js", HTTP_GET, std::bind(&AmsWebServer::gaugemeterJs, this));
server.on("/data.json", HTTP_GET, std::bind(&AmsWebServer::dataJson, this));
@ -248,7 +250,7 @@ void AmsWebServer::configMqttHtml() {
html.replace("${config.mqttUser}", config->getMqttUser());
html.replace("${config.mqttPassword}", config->getMqttPassword());
html.replace("${config.mqttPayloadFormat}", String(config->getMqttPayloadFormat()));
for(int i = 0; i<2; i++) {
for(int i = 0; i<3; i++) {
html.replace("${config.mqttPayloadFormat" + String(i) + "}", config->getMqttPayloadFormat() == i ? "selected" : "");
}
@ -256,6 +258,40 @@ void AmsWebServer::configMqttHtml() {
server.send(200, "text/html", html);
}
void AmsWebServer::configDomoticzHtml() {
printD("Serving /config/domoticz.html over http...");
if(!checkSecurity(1))
return;
String html = String((const __FlashStringHelper*) CONFIGDOMOTICZ_HTML);
html.replace("${version}", VERSION);
if(WiFi.getMode() != WIFI_AP) {
html.replace("boot.css", BOOTSTRAP_URL);
}
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
server.sendHeader("Pragma", "no-cache");
html.replace("${config.domo}", config->getDomoELIDX() == 0 ? "" : "checked");
if(config->getDomoELIDX() > 0){ html.replace("${config.domoELIDX}", String(config->getDomoELIDX()));
} else { html.replace("${config.domoELIDX}", ""); }
if(config->getDomoVL1IDX() > 0){ html.replace("${config.domoVL1IDX}", String(config->getDomoVL1IDX()));
} else { html.replace("${config.domoVL1IDX}", ""); }
if(config->getDomoVL2IDX() > 0){ html.replace("${config.domoVL2IDX}", String(config->getDomoVL2IDX()));
} else { html.replace("${config.domoVL2IDX}", ""); }
if(config->getDomoVL3IDX() > 0){ html.replace("${config.domoVL3IDX}", String(config->getDomoVL3IDX()));
} else { html.replace("${config.domoVL3IDX}", ""); }
if(config->getDomoCL1IDX() > 0){ html.replace("${config.domoCL1IDX}", String(config->getDomoCL1IDX()));
} else { html.replace("${config.domoCL1IDX}", ""); }
if(config->getDomoEnergy() > 0.0){ html.replace("${config.domoEnergy}", String(config->getDomoEnergy()));
} else { html.replace("${config.domoEnergy}", ""); }
server.setContentLength(html.length());
server.send(200, "text/html", html);
}
void AmsWebServer::configWebHtml() {
printD("Serving /config-web.html over http...");
@ -443,6 +479,18 @@ void AmsWebServer::dataJson() {
json.createNestedObject("mqtt");
json["mqtt"]["lastError"] = (int) mqtt->lastError();
String domoStatus;
if(String(config->getDomoELIDX()).isEmpty()) {
domoStatus = "secondary";
} else if(mqtt->connected() && config->getMqttPayloadFormat() == 2 && config->getDomoELIDX() > 0) {
domoStatus = "success";
} else if(mqtt->lastError() == 0) {
domoStatus = "warning";
} else {
domoStatus = "danger";
}
json["status"]["domo"] = domoStatus;
serializeJson(json, jsonStr);
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
@ -494,6 +542,21 @@ void AmsWebServer::handleSave() {
}
}
if(server.hasArg("domoConfig") && server.arg("domoConfig") == "true") {
if(server.hasArg("domo") && server.arg("domo") == "true") {
config->setDomoELIDX(server.arg("domoELIDX").toInt());
config->setDomoVL1IDX(server.arg("domoVL1IDX").toInt());
config->setDomoVL2IDX(server.arg("domoVL2IDX").toInt());
config->setDomoVL3IDX(server.arg("domoVL3IDX").toInt());
config->setDomoCL1IDX(server.arg("domoCL1IDX").toInt());
config->setDomoEnergy(server.arg("domoEnergy").toDouble());
} else {
config->clearDomo();
}
}
if(server.hasArg("authConfig") && server.arg("authConfig") == "true") {
config->setAuthSecurity((byte)server.arg("authSecurity").toInt());
if(config->getAuthSecurity() > 0) {

View File

@ -60,6 +60,7 @@ private:
void configWifiHtml();
void configMqttHtml();
void configWebHtml();
void configDomoticzHtml();
void bootCss();
void gaugemeterJs();
void dataJson();

120
web/configdomoticz.html Normal file
View File

@ -0,0 +1,120 @@
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AMS reader - WiFi configuration</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" type="text/css" href="boot.css"/>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
</head>
<body class="bg-light">
<main role="main" class="container">
<header class="navbar navbar-expand navbar-dark flex-column flex-md-row bg-purple rounded mt-2 mb-4" style="background-color: var(--purple);">
<a href="/" class=""><h6 class="navbar-brand">AMS reader <small>${version}</small></h6></a>
<div class="navbar-nav-scroll">
<ul class="navbar-nav bd-navbar-nav flex-row">
<li class="nav-item">
<a class="nav-link " href="/config-meter">Meter</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config-wifi">WiFi</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config-mqtt">MQTT</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config-web">Web</a>
</li>
<li class="nav-item">
<a class="nav-link active " href="/config-domoticz">Domoticz</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/config-system">System</a>
</li>
</ul>
</div>
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
<li class="nav-item">
<a class="nav-link p-2" href="https://github.com/gskjold/AmsToMqttBridge" target="_blank" rel="noopener" aria-label="GitHub">
<svg class="d-inline-block align-text-top" style="width: 2rem; height: 2rem;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 499.36" focusable="false"><title>GitHub</title><path d="M256 0C114.64 0 0 114.61 0 256c0 113.09 73.34 209 175.08 242.9 12.8 2.35 17.47-5.56 17.47-12.34 0-6.08-.22-22.18-.35-43.54-71.2 15.49-86.2-34.34-86.2-34.34-11.64-29.57-28.42-37.45-28.42-37.45-23.27-15.84 1.73-15.55 1.73-15.55 25.69 1.81 39.21 26.38 39.21 26.38 22.84 39.12 59.92 27.82 74.5 21.27 2.33-16.54 8.94-27.82 16.25-34.22-56.84-6.43-116.6-28.43-116.6-126.49 0-27.95 10-50.8 26.35-68.69-2.63-6.48-11.42-32.5 2.51-67.75 0 0 21.49-6.88 70.4 26.24a242.65 242.65 0 0 1 128.18 0c48.87-33.13 70.33-26.24 70.33-26.24 14 35.25 5.18 61.27 2.55 67.75 16.41 17.9 26.31 40.75 26.31 68.69 0 98.35-59.85 120-116.88 126.32 9.19 7.9 17.38 23.53 17.38 47.41 0 34.22-.31 61.83-.31 70.23 0 6.85 4.61 14.81 17.6 12.31C438.72 464.97 512 369.08 512 256.02 512 114.62 397.37 0 256 0z" fill="currentColor" fill-rule="evenodd"></path></svg>
</a>
</li>
</ul>
</header>
<form method="post" action="/save">
<input type="hidden" name="domoConfig" value="true"/>
<div class="my-3 p-3 bg-white rounded shadow">
<div class="text"></div>Domoticz Configuration. Requires that a Domoticz MQTT-message-broker is setup. HOWTO: https://www.domoticz.com/wiki/MQTT. <br/>(This implementation assumes that the host defined on the MQTT tab is used.) <br/><br/>The following virtual sensors can currently be used: <br/>
"Electricity (instant and counter)", "Electricity Current/Ampere 3 Phase" and "Voltage", see https://www.domoticz.com/wiki/Domoticz_API/JSON_URL's <br/><br/>
Create the sensors in Domoticz under Hardware > Dummy > Create virtual sensor, and use the IDX assigned to the sensor as input here. <br/><br/>
"Electricity (instant and counter)" relies on Total energy import "tPI" and will not start before the first value is read (once an hour). </div>
</div>
<div class="row">
<div class="col-md-4">
<div class="row form-group">
<label class="col-4">Enable</label>
<div class="col-4">
<input id="domoEnable" type="checkbox" name="domo" value="true" ${config.domo}/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="row form-group">
<label class="col-6">Electricity IDX</label>
<div class="col-6">
<input type="text" class="form-control domo-config" name="domoELIDX" value="${config.domoELIDX}"/>
</div>
</div>
<div class="row form-group">
<label class="col-6">Current (3 Phase) IDX</label>
<div class="col-6">
<input type="text" class="form-control domo-config" name="domoCL1IDX" value="${config.domoCL1IDX}"/>
</div>
</div>
</div>
<div class="col-md-4">
<div class="row form-group">
<label class="col-6">Voltage L1 IDX</label>
<div class="col-6">
<input type="text" class="form-control domo-config" name="domoVL1IDX" value="${config.domoVL1IDX}"/>
</div>
</div>
<div class="row form-group">
<label class="col-6">Voltage L2 IDX</label>
<div class="col-6">
<input type="text" class="form-control domo-config" name="domoVL2IDX" value="${config.domoVL2IDX}"/>
</div>
</div><div class="row form-group">
<label class="col-6">Voltage L3 IDX</label>
<div class="col-6">
<input type="text" class="form-control domo-config" name="domoVL3IDX" value="${config.domoVL3IDX}"/>
</div>
</div>
</div>
</div>
</div>
<hr/>
<div class="row form-group">
<div class="col-6">
<a href="/" class="btn btn-outline-secondary">Back</a>
</div>
<div class="col-6 text-right">
<button class="btn btn-primary">Save</button>
</div>
</div>
</form>
</main>
<script>
$('#domoEnable').on('change', function() {
var inputs = $('.domo-config');
inputs.prop('disabled', !$(this).is(':checked'));
});
$(function() {
$('#domoEnable').trigger('change');
});
</script>
</body>
</html>

View File

@ -25,6 +25,9 @@
<a class="nav-link" href="/config-web">Web</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config-domoticz">Domoticz</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/config-system">System</a>
</li>
</ul>

View File

@ -25,6 +25,9 @@
<li class="nav-item">
<a class="nav-link" href="/config-web">Web</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config-domoticz">Domoticz</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/config-system">System</a>
</li>
@ -55,6 +58,7 @@
<select class="form-control mqtt-config" name="mqttPayloadFormat">
<option value="0" ${config.mqttPayloadFormat0}>JSON</option>
<option value="1" ${config.mqttPayloadFormat1}>Raw</option>
<option value="2" ${config.mqttPayloadFormat2}>Domoticz</option>
</select>
</div>
</div>

View File

@ -26,9 +26,12 @@
<a class="nav-link" href="/config-web">Web</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config-domoticz">Domoticz</a>
</li>
<li class="nav-item">
<a class="nav-link active" href="/config-system">System</a>
</li>
</ul>
</ul>
</div>
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
<li class="nav-item">

View File

@ -25,6 +25,9 @@
<li class="nav-item">
<a class="nav-link active" href="/config-web">Web</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config-domoticz">Domoticz</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/config-system">System</a>
</li>

View File

@ -25,6 +25,9 @@
<li class="nav-item">
<a class="nav-link" href="/config-web">Web</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config-domoticz">Domoticz</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/config-system">System</a>
</li>

View File

@ -52,7 +52,7 @@
</head>
<body class="bg-light">
<main role="main" class="container">
<header class="navbar navbar-expand navbar-dark flex-column flex-md-row rounded mt-2 mb-4" style="background-color: var(--purple);">
<header class="navbar navbar-expand navbar-dark flex-column flex-md-row rounded mt-2 mb-4" style="background-color: var(--purple);">
<a href="/" class=""><h6 class="navbar-brand">AMS reader <small>${version}</small></h6></a>
<div class="navbar-nav-scroll">
<ul class="navbar-nav bd-navbar-nav flex-row">
@ -68,6 +68,9 @@
<li class="nav-item">
<a class="nav-link" href="/config-web">Web</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config-domoticz">Domoticz</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/config-system">System</a>
</li>
@ -79,6 +82,7 @@
<div id="han" class="d-none m-2">HAN</div>
<div id="wifi" class="d-none m-2">WiFi</div>
<div id="mqtt" class="d-none m-2">MQTT</div>
<div id="domo" class="d-none m-2">DOMO</div>
</div>
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
<li class="nav-item">
@ -346,6 +350,7 @@ var fetch = function() {
append: "W"
});
setStatus("domo", "secondary");
setStatus("mqtt", "secondary");
setStatus("wifi", "secondary");
setStatus("han", "secondary");

View File

@ -28,6 +28,9 @@
<li class="nav-item">
<a class="nav-link" href="/config-system">System</a>
</li>
<li class="nav-item">
<a class="nav-link " href="/config-domoticz">Domoticz</a>
</li>
</ul>
</div>
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">