mirror of
https://github.com/Laxilef/OTGateway.git
synced 2025-12-25 09:33:35 +05:00
Compare commits
1 Commits
b17ecd5ae8
...
ae58cfecb4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae58cfecb4 |
@@ -886,7 +886,7 @@ public:
|
||||
return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("equitherm_k_factor")).c_str(), doc);
|
||||
}
|
||||
|
||||
bool publishInputEquithermFactorE(bool enabledByDefault = true) {
|
||||
bool publishInputEquithermFactorK(bool enabledByDefault = true) {
|
||||
JsonDocument doc;
|
||||
doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->statusTopic.c_str();
|
||||
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
||||
@@ -906,7 +906,7 @@ public:
|
||||
doc[FPSTR(HA_EXPIRE_AFTER)] = this->expireAfter;
|
||||
doc.shrinkToFit();
|
||||
|
||||
return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("equitherm_e_factor")).c_str(), doc);
|
||||
return this->publish(this->makeConfigTopic(FPSTR(HA_ENTITY_NUMBER), F("equitherm_k_factor")).c_str(), doc);
|
||||
}
|
||||
|
||||
bool publishInputEquithermFactorT(bool enabledByDefault = true) {
|
||||
|
||||
@@ -214,12 +214,7 @@ protected:
|
||||
);
|
||||
}
|
||||
|
||||
// 5 request retries
|
||||
// 1000ms maximum response waiting time
|
||||
// 100ms delay between requests
|
||||
// +15%
|
||||
// 5 * (1000 + 100) * 1.15 = 6325 ms
|
||||
if (!vars.slave.connected && millis() - this->lastSuccessResponse < 6325) {
|
||||
if (!vars.slave.connected && millis() - this->lastSuccessResponse < 1325) {
|
||||
Log.sinfoln(
|
||||
FPSTR(L_OT),
|
||||
F("Connected, downtime: %lu s."),
|
||||
@@ -229,7 +224,7 @@ protected:
|
||||
this->connectedTime = millis();
|
||||
vars.slave.connected = true;
|
||||
|
||||
} else if (vars.slave.connected && millis() - this->lastSuccessResponse > 6325) {
|
||||
} else if (vars.slave.connected && millis() - this->lastSuccessResponse > 1325) {
|
||||
Log.swarningln(
|
||||
FPSTR(L_OT),
|
||||
F("Disconnected, uptime: %lu s."),
|
||||
|
||||
@@ -975,176 +975,176 @@
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
//График
|
||||
let equithermChart;
|
||||
//График
|
||||
let equithermChart;
|
||||
|
||||
async function initChart() {
|
||||
try {
|
||||
const response = await fetch("/api/settings", {
|
||||
cache: "no-cache",
|
||||
credentials: "include"
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Response not valid');
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
//График переменные
|
||||
const targetTemp = result?.heating?.target ?? 24;
|
||||
const maxOut = result?.heating?.maxTemp ?? 90;
|
||||
const Kn = result?.equitherm?.n_factor ?? 1;
|
||||
const Ke = result?.equitherm?.e_factor ?? 1.3;
|
||||
const Kk = result?.equitherm?.k_factor ?? 0;
|
||||
|
||||
function calculateTRad(targetTemp, outdoorTemp, maxOut, Kn, Ke, Kk) {
|
||||
let tempDiff = targetTemp - outdoorTemp;
|
||||
if (tempDiff < 0) {
|
||||
tempDiff = 0;
|
||||
}
|
||||
const minOutside = targetTemp - (maxOut - targetTemp) / Kn;
|
||||
let base = targetTemp - minOutside;
|
||||
if (base <= 0) {
|
||||
base = 0.0001;
|
||||
}
|
||||
const c1 = (maxOut - targetTemp) / Math.pow(base, 1.0 / Ke);
|
||||
let T_rad = targetTemp + c1 * Math.pow(tempDiff, 1.0 / Ke) + Kk;
|
||||
return Math.min(T_rad, maxOut);
|
||||
}
|
||||
|
||||
function generateChartData(targetTemp, maxOut, Kn, Ke, Kk) {
|
||||
const outdoorTemps = [];
|
||||
const predictedTRad = [];
|
||||
|
||||
for (let temp = 25; temp >= -30; temp -= 1) {
|
||||
outdoorTemps.push(temp);
|
||||
predictedTRad.push(calculateTRad(targetTemp, temp, maxOut, Kn, Ke, Kk).toFixed(1));
|
||||
}
|
||||
return { outdoorTemps, predictedTRad };
|
||||
}
|
||||
|
||||
// Стартовые данные
|
||||
const { outdoorTemps, predictedTRad } = generateChartData(targetTemp, maxOut, Kn, Ke, Kk);
|
||||
|
||||
// Создаем график
|
||||
const ctx = document.getElementById('equithermChart').getContext('2d');
|
||||
// Create gradient for the line
|
||||
const canvasHeight = ctx.canvas.height;
|
||||
const gradient = ctx.createLinearGradient(0, canvasHeight, 0, 0); // Adjust x1, y1, x2, y2 for direction
|
||||
gradient.addColorStop(0, 'rgba(75, 192, 192, 1)');
|
||||
gradient.addColorStop(0.5, 'rgba(255, 99, 132, 1)');
|
||||
|
||||
|
||||
equithermChart = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: outdoorTemps,
|
||||
datasets: [{
|
||||
label: 'Температура Радиатора (°C)',
|
||||
borderColor: gradient, // Use gradient instead of solid color
|
||||
borderWidth: 1,
|
||||
fill: false,
|
||||
tension: 0.1,
|
||||
pointRadius: 2, // Reduce dot size (default is 3)
|
||||
pointHoverRadius: 4,
|
||||
data: predictedTRad
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
scales: {
|
||||
x: {
|
||||
display: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Наружная температура (°C)'
|
||||
}
|
||||
},
|
||||
y: {
|
||||
display: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Температура Радиатора (°C)'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Показ формы
|
||||
document.getElementById('equitherm-settings-busy').classList.add('hidden');
|
||||
document.getElementById('equitherm-settings').classList.remove('hidden');
|
||||
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// Обновление графика
|
||||
function updateChart(formData) {
|
||||
if (!equithermChart) return;
|
||||
|
||||
fetch("/api/settings", {
|
||||
async function initChart() {
|
||||
try {
|
||||
const response = await fetch("/api/settings", {
|
||||
cache: "no-cache",
|
||||
credentials: "include"
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
const targetTemp = result?.heating?.target ?? 24;
|
||||
const maxOut = result?.heating?.maxTemp ?? 90;
|
||||
const Kn = parseFloat(formData.get('equitherm[n_factor]')) || 1;
|
||||
const Ke = parseFloat(formData.get('equitherm[e_factor]')) || 1.3;
|
||||
const Kk = parseFloat(formData.get('equitherm[k_factor]')) || 0;
|
||||
|
||||
function calculateTRad(targetTemp, outdoorTemp, maxOut, Kn, Ke, Kk) {
|
||||
let tempDiff = targetTemp - outdoorTemp;
|
||||
if (tempDiff < 0) {
|
||||
tempDiff = 0;
|
||||
}
|
||||
const minOutside = targetTemp - (maxOut - targetTemp) / Kn;
|
||||
let base = targetTemp - minOutside;
|
||||
if (base <= 0) {
|
||||
base = 0.0001;
|
||||
}
|
||||
const c1 = (maxOut - targetTemp) / Math.pow(base, 1.0 / Ke);
|
||||
let T_rad = targetTemp + c1 * Math.pow(tempDiff, 1.0 / Ke) + Kk;
|
||||
return Math.min(T_rad, maxOut);
|
||||
}
|
||||
|
||||
const outdoorTemps = [];
|
||||
const predictedTRad = [];
|
||||
for (let temp = 25; temp >= -30; temp -= 1) {
|
||||
outdoorTemps.push(temp);
|
||||
predictedTRad.push(calculateTRad(targetTemp, temp, maxOut, Kn, Ke, Kk).toFixed(1));
|
||||
}
|
||||
|
||||
equithermChart.data.labels = outdoorTemps;
|
||||
equithermChart.data.datasets[0].data = predictedTRad;
|
||||
equithermChart.update();
|
||||
})
|
||||
.catch(error => console.log(error));
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Response not valid');
|
||||
}
|
||||
|
||||
// Слушаем отправку
|
||||
const form = document.getElementById('equitherm-settings');
|
||||
form.addEventListener('submit', (e) => {
|
||||
const result = await response.json();
|
||||
|
||||
//График переменные
|
||||
const targetTemp = result?.heating?.target_temp ?? 24;
|
||||
const maxOut = result?.heating?.maxTemp ?? 90;
|
||||
const Kn = result?.equitherm?.n_factor ?? 1;
|
||||
const Ke = result?.equitherm?.e_factor ?? 1.3;
|
||||
const Kk = result?.equitherm?.k_factor ?? 0;
|
||||
|
||||
const formData = new FormData(form);
|
||||
updateChart(formData);
|
||||
function calculateTRad(targetTemp, outdoorTemp, maxOut, Kn, Ke, Kk) {
|
||||
let tempDiff = targetTemp - outdoorTemp;
|
||||
if (tempDiff < 0) {
|
||||
tempDiff = 0;
|
||||
}
|
||||
const minOutside = targetTemp - (maxOut - targetTemp) / Kn;
|
||||
let base = targetTemp - minOutside;
|
||||
if (base <= 0) {
|
||||
base = 0.0001;
|
||||
}
|
||||
const c1 = (maxOut - targetTemp) / Math.pow(base, 1.0 / Ke);
|
||||
let T_rad = targetTemp + c1 * Math.pow(tempDiff, 1.0 / Ke) + Kk;
|
||||
return Math.min(T_rad, maxOut);
|
||||
}
|
||||
|
||||
function generateChartData(targetTemp, maxOut, Kn, Ke, Kk) {
|
||||
const outdoorTemps = [];
|
||||
const predictedTRad = [];
|
||||
|
||||
for (let temp = 25; temp >= -30; temp -= 1) {
|
||||
outdoorTemps.push(temp);
|
||||
predictedTRad.push(calculateTRad(targetTemp, temp, maxOut, Kn, Ke, Kk).toFixed(1));
|
||||
}
|
||||
return { outdoorTemps, predictedTRad };
|
||||
}
|
||||
|
||||
// Стартовые данные
|
||||
const { outdoorTemps, predictedTRad } = generateChartData(targetTemp, maxOut, Kn, Ke, Kk);
|
||||
|
||||
// Создаем график
|
||||
const ctx = document.getElementById('equithermChart').getContext('2d');
|
||||
// Create gradient for the line
|
||||
const canvasHeight = ctx.canvas.height;
|
||||
const gradient = ctx.createLinearGradient(0, canvasHeight, 0, 0); // Adjust x1, y1, x2, y2 for direction
|
||||
gradient.addColorStop(0, 'rgba(75, 192, 192, 1)');
|
||||
gradient.addColorStop(0.5, 'rgba(255, 99, 132, 1)');
|
||||
|
||||
|
||||
equithermChart = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: outdoorTemps,
|
||||
datasets: [{
|
||||
label: 'Температура Радиатора (°C)',
|
||||
borderColor: gradient, // Use gradient instead of solid color
|
||||
borderWidth: 1,
|
||||
fill: false,
|
||||
tension: 0.1,
|
||||
pointRadius: 2, // Reduce dot size (default is 3)
|
||||
pointHoverRadius: 4,
|
||||
data: predictedTRad
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
scales: {
|
||||
x: {
|
||||
display: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Наружная температура (°C)'
|
||||
}
|
||||
},
|
||||
y: {
|
||||
display: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Температура Радиатора (°C)'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Слушаем кнопку сохранить
|
||||
const equithermSection = document.querySelector('details');
|
||||
const saveButton = equithermSection.querySelector('button[data-i18n="button.save"]');
|
||||
// Показ формы
|
||||
document.getElementById('equitherm-settings-busy').classList.add('hidden');
|
||||
document.getElementById('equitherm-settings').classList.remove('hidden');
|
||||
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// Обновление графика
|
||||
function updateChart(formData) {
|
||||
if (!equithermChart) return;
|
||||
|
||||
fetch("/api/settings", {
|
||||
cache: "no-cache",
|
||||
credentials: "include"
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
const targetTemp = result?.heating?.target_temp ?? 24;
|
||||
const maxOut = result?.heating?.maxTemp ?? 90;
|
||||
const Kn = parseFloat(formData.get('equitherm[n_factor]')) || 1;
|
||||
const Ke = parseFloat(formData.get('equitherm[e_factor]')) || 1.3;
|
||||
const Kk = parseFloat(formData.get('equitherm[k_factor]')) || 0;
|
||||
|
||||
function calculateTRad(targetTemp, outdoorTemp, maxOut, Kn, Ke, Kk) {
|
||||
let tempDiff = targetTemp - outdoorTemp;
|
||||
if (tempDiff < 0) {
|
||||
tempDiff = 0;
|
||||
}
|
||||
const minOutside = targetTemp - (maxOut - targetTemp) / Kn;
|
||||
let base = targetTemp - minOutside;
|
||||
if (base <= 0) {
|
||||
base = 0.0001;
|
||||
}
|
||||
const c1 = (maxOut - targetTemp) / Math.pow(base, 1.0 / Ke);
|
||||
let T_rad = targetTemp + c1 * Math.pow(tempDiff, 1.0 / Ke) + Kk;
|
||||
return Math.min(T_rad, maxOut);
|
||||
}
|
||||
|
||||
const outdoorTemps = [];
|
||||
const predictedTRad = [];
|
||||
for (let temp = 25; temp >= -30; temp -= 1) {
|
||||
outdoorTemps.push(temp);
|
||||
predictedTRad.push(calculateTRad(targetTemp, temp, maxOut, Kn, Ke, Kk).toFixed(1));
|
||||
}
|
||||
|
||||
equithermChart.data.labels = outdoorTemps;
|
||||
equithermChart.data.datasets[0].data = predictedTRad;
|
||||
equithermChart.update();
|
||||
})
|
||||
.catch(error => console.log(error));
|
||||
}
|
||||
|
||||
// Слушаем отправку
|
||||
const form = document.getElementById('equitherm-settings');
|
||||
form.addEventListener('submit', (e) => {
|
||||
|
||||
const formData = new FormData(form);
|
||||
updateChart(formData);
|
||||
});
|
||||
|
||||
// Слушаем кнопку сохранить
|
||||
const equithermSection = document.querySelector('details');
|
||||
const saveButton = equithermSection.querySelector('button[data-i18n="button.save"]');
|
||||
saveButton.addEventListener('click', () => {
|
||||
const form = document.getElementById('equitherm-settings');
|
||||
const formData = new FormData(form);
|
||||
updateChart(formData);
|
||||
});
|
||||
});
|
||||
|
||||
// инициализируем
|
||||
initChart();
|
||||
// инициализируем
|
||||
initChart();
|
||||
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user