6 Commits

Author SHA1 Message Date
P43YM
82d8b7ed8d data/static 2025-02-28 23:08:53 +03:00
P43YM
8b88d133d4 Merge branch 'master' of https://github.com/P43YM/OTGateway 2025-02-28 22:25:05 +03:00
P43YM
bae540d67a Cleaning 2025-02-28 22:24:45 +03:00
P43YM
68514d3c9f Cleaning 2025-02-28 22:15:04 +03:00
P43YM
c3b127c868 Cleaning for chart code 2025-02-28 20:19:03 +03:00
P43YM
b7334b5f3e Snap to points in Chart 2025-02-28 19:20:42 +03:00
7 changed files with 126 additions and 122 deletions

0
build/.gitkeep Normal file
View File

0
data/static/.gitkeep Normal file
View File

View File

@@ -84,7 +84,7 @@ board_build.ldscript = eagle.flash.4m1m.ld
;platform_packages =
; framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.5
; framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-lib-builder/releases/download/idf-release_v5.1/esp32-arduino-libs-idf-release_v5.1-33fbade6.zip
platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.12/platform-espressif32.zip
platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.13/platform-espressif32.zip
platform_packages =
board_build.partitions = esp32_partitions.csv
lib_deps =
@@ -164,10 +164,10 @@ board_build.ldscript = ${esp8266_defaults.board_build.ldscript}
build_type = ${esp8266_defaults.build_type}
build_flags =
${esp8266_defaults.build_flags}
-D DEFAULT_OT_IN_GPIO=4
-D DEFAULT_OT_OUT_GPIO=5
-D DEFAULT_OT_IN_GPIO=13
-D DEFAULT_OT_OUT_GPIO=15
-D DEFAULT_SENSOR_OUTDOOR_GPIO=12
-D DEFAULT_SENSOR_INDOOR_GPIO=14
-D DEFAULT_SENSOR_INDOOR_GPIO=4
-D DEFAULT_STATUS_LED_GPIO=2
-D DEFAULT_OT_RX_LED_GPIO=16

View File

@@ -14,12 +14,12 @@ ap_password = otgateway123456
sta_ssid =
sta_password =
portal_login =
portal_password =
portal_login = admin
portal_password = admin
mqtt_enabled = false
mqtt_server =
mqtt_port = 1883
mqtt_user =
mqtt_password =
mqtt_prefix = otgateway
mqtt_prefix = opentherm

View File

@@ -978,7 +978,8 @@
//График
let equithermChart;
async function initChart() {
async function fetchSettings() {
try {
const response = await fetch("/api/settings", {
cache: "no-cache",
@@ -989,135 +990,137 @@
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');
return await response.json();
} catch (error) {
console.log(error);
}
}
// Обновление графика
// Считаем температуру
function calculateTRad(targetTemp, outdoorTemp, maxOut, Kn, Ke, Kk) {
let tempDelta = targetTemp - outdoorTemp;
const maxPoint = targetTemp - (maxOut - targetTemp) / Kn;
let base = targetTemp - maxPoint;
if (base <= 0) {
base = 0.0001;
}
const sf = (maxOut - targetTemp) / Math.pow(base, 1.0 / Ke);
let T_rad = targetTemp + sf * (tempDelta >= 0 ? Math.pow(tempDelta, 1.0 / Ke) : -Math.pow(-tempDelta, 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 };
}
// Создаем график
function createChart(outdoorTemps, predictedTRad) {
const ctx = document.getElementById('equithermChart').getContext('2d');
const canvasHeight = ctx.canvas.height;
const gradient = ctx.createLinearGradient(0, canvasHeight, 0, 0);
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,
borderWidth: 1,
fill: false,
tension: 0.1,
pointRadius: 2,
pointHoverRadius: 4,
data: predictedTRad
}]
},
options: {
responsive: true,
interaction: {
mode: 'nearest',
intersect: false
},
plugins: {
tooltip: {
enabled: true,
position: 'nearest',
}
},
scales: {
x: {
display: true,
title: {
display: true,
text: 'Наружная температура (°C)'
}
},
y: {
display: true,
title: {
display: true,
text: 'Температура Радиатора (°C)'
}
}
}
}
});
}
// Инициализируем график
async function initChart() {
try {
const result = await fetchSettings();
const { heating, equitherm } = result;
const targetTemp = heating?.target ?? 24;
const maxOut = heating?.maxTemp ?? 90;
const Kn = equitherm?.n_factor ?? 1;
const Ke = equitherm?.e_factor ?? 1.3;
const Kk = equitherm?.k_factor ?? 0;
const { outdoorTemps, predictedTRad } = generateChartData(targetTemp, maxOut, Kn, Ke, Kk);
createChart(outdoorTemps, predictedTRad);
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())
fetchSettings()
.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));
}
const { outdoorTemps, predictedTRad } = generateChartData(targetTemp, maxOut, Kn, Ke, Kk);
equithermChart.data.labels = outdoorTemps;
equithermChart.data.datasets[0].data = predictedTRad;
@@ -1126,6 +1129,7 @@
.catch(error => console.log(error));
}
// Слушаем отправку
const form = document.getElementById('equitherm-settings');
form.addEventListener('submit', (e) => {