Home Assistant

Diskuze, rady a návody ohledně HomeAssistant
omega001
Příspěvky: 8
Registrován: úte dub 05, 2022 10:26 pm

Re: Home Assistant

Příspěvek od omega001 »

Uživatelský avatar
TomHC
Příspěvky: 1320
Registrován: pát lis 11, 2022 8:14 am
Lokalita: Hlohovec, SR
Systémové napětí: 48V
Výkon panelů [Wp]: 5520
Kapacita baterie [kWh]: 14
Chci prodávat energii: NE
Chci/Mám dotaci: NE
Bydliště: Hlohovec, SR

Re: Home Assistant

Příspěvek od TomHC »

rottenkiwi píše:Vdaka vsetkym za rady. Idem pozriet este toto video, ak to nepochopim, mazem HA.
3 dni strateneho casu dost.

Home Assistant How To - split your configuration files (YAML way)

https://www.youtube.com/watch?v=kgFwhYInzfA
Rovno to zmaž... Ideš pozerať 2 roky staré video. Zmenili sa configy, pribudli nové integrácie...
MUST PV1800 VHM 48V 5.5kW, 5.52kWp (12x TPL mono 460W, 2S2P východ, 2S4P juh), 16x 280 Ah LiFePO4 (14.3 kWh) BMS JBD-AP21S001-L21S-200A-B, SW: Home Assistant na Synology DS923+ ku tomu ESPHome, Tasmota, MariaDB, InfluxDB, Telegraf, Grafana, Zigbee2MQTT..., HW: ESPlan (ESP32 + LAN 8720 + RS485 + UART). Nejaké moje projekty: MUST-ESPhome, ELTEK Flatpack2 ESPhome, ESP32-EMON, PZEM-017@WiFi, diyBMS-CurrentShunt-ESPhome
Uživatelský avatar
rottenkiwi
Příspěvky: 5451
Registrován: pát úno 13, 2015 2:24 pm
Lokalita: SO, SK
Bydliště: SO, SK

Re: Home Assistant

Příspěvek od rottenkiwi »

Jak sa mozu v 2 r.. starom systeme menit konfigy ? CI dozera mi nieco na dom a FVE a oni tam nieco
zmenia a mne padne cely system ? Kto ucil tych ludi programovat ? No Uncle Bob keby toto videl .... :lol:

Ja mam 10 r. iduce Arduino Mega + 2 GB karta a nic sa nemeni, niekolko rokov iduce EPS32/8266
niekolko rokov iduce systemy na Grafane + Influx + NodeRed,
niekolko rokov iduce kamery na ZoneMinderi ci Motione,
ide stary mplayer + ffmpeg, ide avidemux cvi KdenLive.

To co je za inteligenta, ze meni nejake konfiguraky ?

Preco tu nie su snapshoty, ze nieco nejde, tak 30 min dozadu mi to islo, tak to obnovim a skusam dalej.


Zlate casy assmblera na Z80 ci prvych PC XT, clovek mal vypis ROM a presne vedel
co ktore prerusenie v ROM robi, kto je na to zaveseny, a teraz ma kod, ktory sa niekedy
zmestil do 512 B sektora, na ESP 1.2 MB , na RPI 4 GB a na amd64 je mu aj 32 GB malo.

Potom sa cudujeme, ze platime za cas programatorov, ale nic v state ani v EU nefunguje
a clovek beha po uradoch ci postach a jedine co sa dozvie: Padol nam system.

Ked ja do konfu po 40 r. stravenych za monitomi neviem dat 4 riadky na mQTT integraciu,
tak to kde sme sa dostali ?
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
Uživatelský avatar
rege
Příspěvky: 156
Registrován: úte bře 19, 2019 8:03 pm
Bydliště: Vychod SK

Re: Home Assistant

Příspěvek od rege »

Lepsie je si pozriet manual ako video. Ten system sa vyvija kazdy mesiac, prerabaju to tak aby sa minimalizovala yaml konfiguracia a vacsina sla nastavit cez gui. Tiez mi to na zaciatku chvilu trvalo kym som pochopil ako to nastavit a teraz to funguje k mojej spokojnosti uz 4-ty rok.
Zak
Příspěvky: 81
Registrován: pon říj 11, 2021 1:19 pm

Re: Home Assistant

Příspěvek od Zak »

camel1cz píše:
Zak píše: select: "tbody:nth-child(2) > tr:nth-child(x) > td"
Zkus něco jako:

Kód: Vybrat vše

select: "table:not(.seamless_table) > tbody:nth-child(2) > tr:nth-child(x) > td"
Jde o to, že v tvém zápisu nikde neomezuješ výběr na konkrétní tabulku a tak to najde tu první, co má dostatečný počet řádků.
Mají to trochu nešťastně ostylované, tak nevidím, jak to vybrat jinak než pře NOT... snad to bude ten hajzlík umět.
Díky moc, funguje!
Netušil by někdo, v kolik hodin se nové ceny na další den na webu OTE objevují? A jak nastavit pravidelný refresh vytvořených senzorů v HA pravidelně každý den v XY hodin?

Další otázka - existuje integrace
https://github.com/grinco/ote_rate
která zdá se vyčítá data odsud
https://www.ote-cr.cz/cs/kratkodobe-trh ... chart-data
...netipnul by někdo, u kterého z postupů by mohla být menší šance, že to bude nutné v dohledně době překopávat, protože OTE vzhled/výstup změní?
camel1cz
Příspěvky: 771
Registrován: pon bře 21, 2011 11:12 pm
Systémové napětí: 48V
Výkon panelů [Wp]: 3780
Kapacita baterie [kWh]: 18

Re: Home Assistant

Příspěvek od camel1cz »

Určitě je nejlepší použít existující integraci - když se něco změní, tak máš slušnou šanci, že to někdo opraví dřív než ty :)
A v nejhorším případě najdeš pomocnou ruku na konci svého ramene :)
5 kVA Axpert King @ 3,78 kWp [12x AUO 315Wp mono]
18 kWh [5x Pylontech US3000]
Rozpracováno:
Fangpusun MPPT 150/70 Tr @ 1,89 kWp [6x AUO 315Wp mono]
5 kVA Axpert King II @ 5,52 kWp [12 x AS 460Wp mono]
kodl69
Příspěvky: 7416
Registrován: sob črc 19, 2014 8:56 pm
Lokalita: severně od Brna
Systémové napětí: 48V
Výkon panelů [Wp]: 8kWp
Kapacita baterie [kWh]: 12kWh
Chci prodávat energii: NE
Chci/Mám dotaci: NE

Re: Home Assistant

Příspěvek od kodl69 »

Bych tak netvrdil, po aktualizaci mi přestalo fungovat vyčítání BMS přes mqtt, a celkem jsem se natrápil. Tj není zlato co se třpytí.
ostrov skoro 8kWp neustále ve stádiu zrodu: smartshunt(ex WBJR), MPPT150/45, MPPT 250/100(ex midnitesolar 150 clasic lite), 16S a různě P cca 340Ah Winston, MP II 5000,( ex Powerjack 8kW, ex samodomo cca 4kW). 48V DC rozvody a spotřebiče.
ringo
Příspěvky: 66
Registrován: ned zář 27, 2020 7:38 am

Re: Home Assistant

Příspěvek od ringo »

rottenkiwi píše: A este je problem, ze ked vypnem v noci menic a rano zapnem menic,
tak v HA zmizne 2. Daikin klima a ked ju dam znova zaradit do integracii,
tak pise, ze uz tam je, ale ona tam nie je, lebo v prehlade HA pise ze je nedostupna,
pritom ona na mobile v App Daikinu ide OK.
Tohle bych řekl že je problém že ta Daikin klima dostane jinou IP adresu než na kterou byla původní integrace nastavena. Integrace jako kód tam potom zůstává, ale nejsou naplněné entity v HA. Aplikace v mobilu tu IP adresu nepoužívá (alespoň u sebe jsem ji nenašel)a proto funguje správně.

Pro ověření toho co skutečně běhá v MQTT zprávách doporučuji použít MQTT Explorer na PC.
4,4kWp, GoodWe 10K-ET, Pylontech Force H2 10.65kWh
TČ Fujitsu + vlastní řízení pomocí PWM + RS232 na SDS micro
SmartHome na Domoticz/Synology + SDS + ESPEasy/ ESP8266 (bazén, žaluzie,...)
postupný přechod na Home Assistant/Rpi4 -> NUC
cipis
Příspěvky: 4421
Registrován: pon srp 16, 2021 9:31 pm
Lokalita: blízko Brna
Bydliště: blízko Brna

Re: Home Assistant

Příspěvek od cipis »

Na tohle je lepsi pouzivat nazvy a ne ip adresy natvrdo. O preklad nazvu na aktualni ip adresu se postara DNS.
Nebo minimalne aspon v routeru nastavit dhcp natvrdo ip dane mac adrese, aby dostavala furt stejnou.
9,77 kWp: 6240 Wp Jih, 2040 Wp Východ, 1490 Wp Západ
Regulátory Epever a Victron
Phoenix 2 kVA + MP 24/5000 (můj byt + wifi/kamery/atd. + máti byt)
Epever 3kW vytěžování do bojlerů + žebříky
CARSPA aktuálně odpojené
1 kW "nabíječka" 24 V
31 080 Wh staré olovo 7 488 Wh Li-Ion
Modře píši jako moderátor, černě jako člen.
Uživatelský avatar
rottenkiwi
Příspěvky: 5451
Registrován: pát úno 13, 2015 2:24 pm
Lokalita: SO, SK
Bydliště: SO, SK

Re: Home Assistant

Příspěvek od rottenkiwi »

V IP to nebolo, 1. klima mala 192.168.1.20 , 2. 192.168.1.17, ta prva isla OK, grafy sa zobrazovali
ta 2. zmizla, grafy pisali ze entita neexistuje a ked som ju dal pridat, tak pisalo, ze je uz nastavena
ale pod. Daikin zaraideniami bola len ta 1. Tak kde je chyba ?
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
Uživatelský avatar
rottenkiwi
Příspěvky: 5451
Registrován: pát úno 13, 2015 2:24 pm
Lokalita: SO, SK
Bydliště: SO, SK

Re: Home Assistant

Příspěvek od rottenkiwi »

Mate niekto urobenu integraciu Victron Venus OS do HA ?
Je na to aj nejaky navod ? Ci vsetko, cely JSON z Grafany treba prepisat do YAML ?

Nejak nie som z toho mudry, ako to on urobil:

https://www.youtube.com/watch?v=dlvlhou70VA

.
HA_victron.png
Je na to nejaky tool, co zoberie celu specifikaciu Victron 24 a Victron 48
z Grafany v JSON formate a urobi integraciu do HA ?
Bude sa dat potom pomocou HA, napr. na zaklade pocasia riadit FVE ?

.
grafana_FVE_II_FVE_III.png
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
glottis
Příspěvky: 2101
Registrován: stř úno 02, 2022 10:30 am
Lokalita: okolí Mělníka
Systémové napětí: 48V
Výkon panelů [Wp]: 13000
Kapacita baterie [kWh]: 15

Re: Home Assistant

Příspěvek od glottis »

v HACS, tedy comunitnim storu integraci je

Victron GX modbusTCP integration

minuly tyden jsem to pro zajimavost zkousel. Na venus se jen povoli modbus a v HA zada ip a vse se tam dotahne. Jestli uplne vsechno nevim ale muzes to zkusit

je to tahle integrace
https://github.com/sfstar/hass-victron
Uživatelský avatar
rottenkiwi
Příspěvky: 5451
Registrován: pát úno 13, 2015 2:24 pm
Lokalita: SO, SK
Bydliště: SO, SK

Re: Home Assistant

Příspěvek od rottenkiwi »

TomHC píše:rottenkiwi: aj čítaš čo ti tu ľudia radia? Nezdá sa mi... YAML a jeho parsery sú smrť, neakceptuje to tabulátor, treba to správne odsadzovať, uvodzovky niekde áno, niekde nie... Skús toto

Kód: Vybrat vše

mqtt:
  sensor:
    - name: Esp32_Cell_1
      state_topic: "esp32/V1"
      unique_id: Esp32V1
      unit_of_measurement: "V"
      value_template: "{{ voltage }}"
Tak mam mierny pokrok:

entitu "Esp32_Cell_1" mi zobralo, ale je tam 0 V
ale MQTT ide aj na ESP32 aj v HA.

Tak kde moze byt problem ?

.
HA_MQTT_0V.png
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
Uživatelský avatar
TomHC
Příspěvky: 1320
Registrován: pát lis 11, 2022 8:14 am
Lokalita: Hlohovec, SR
Systémové napětí: 48V
Výkon panelů [Wp]: 5520
Kapacita baterie [kWh]: 14
Chci prodávat energii: NE
Chci/Mám dotaci: NE
Bydliště: Hlohovec, SR

Re: Home Assistant

Příspěvek od TomHC »

Hmm, teraz mi napadlo, ja mám všade payload v JSON formáte. Skús to takto ({{ value }}):

Kód: Vybrat vše

mqtt:
  sensor:
    - name: Esp32_Cell_1
      state_topic: "esp32/V1"
      unique_id: Esp32V1
      unit_of_measurement: "V"
      value_template: "{{ value }}"
HA-mqtt-value.png
MUST PV1800 VHM 48V 5.5kW, 5.52kWp (12x TPL mono 460W, 2S2P východ, 2S4P juh), 16x 280 Ah LiFePO4 (14.3 kWh) BMS JBD-AP21S001-L21S-200A-B, SW: Home Assistant na Synology DS923+ ku tomu ESPHome, Tasmota, MariaDB, InfluxDB, Telegraf, Grafana, Zigbee2MQTT..., HW: ESPlan (ESP32 + LAN 8720 + RS485 + UART). Nejaké moje projekty: MUST-ESPhome, ELTEK Flatpack2 ESPhome, ESP32-EMON, PZEM-017@WiFi, diyBMS-CurrentShunt-ESPhome
Uživatelský avatar
rottenkiwi
Příspěvky: 5451
Registrován: pát úno 13, 2015 2:24 pm
Lokalita: SO, SK
Bydliště: SO, SK

Re: Home Assistant

Příspěvek od rottenkiwi »

DIk. Vyskusam.

SKusam aj Venus OS ale toto nejde:
Ako nastavit modbus tcp ?

Jemu to v tomto videu ide:
Od jakej verzie su uz nove konfiguraký ?

https://www.youtube.com/watch?v=giosYremoss
.

Kód: Vybrat vše

modbus:
  - name: victron
    type: tcp
    host: 192.168.1.11
    port: 502
    sensor:
      - name: "Battery Power"
        unit_of_measurement: "W"
        slave: 239
        address: 842
      - name: "Battery SOC"
        unit_of_measurement: "%"
        scale: 1
        precision: 1
        slave: 239
        address: 843
      - name: "Battery Voltage"    
        unit_of_measurement: "V"
        scale: 0.1
        precision: 1
        slave: 239
        address: 841
Naposledy upravil(a) rottenkiwi dne pát led 06, 2023 7:29 pm, celkem upraveno 1 x.
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
Uživatelský avatar
TomHC
Příspěvky: 1320
Registrován: pát lis 11, 2022 8:14 am
Lokalita: Hlohovec, SR
Systémové napětí: 48V
Výkon panelů [Wp]: 5520
Kapacita baterie [kWh]: 14
Chci prodávat energii: NE
Chci/Mám dotaci: NE
Bydliště: Hlohovec, SR

Re: Home Assistant

Příspěvek od TomHC »

rottenkiwi píše:DIk. Vyskusam.

SKusam aj Venus OS ale toto nejde:
Ako nastavit modbus tcp ?

.
S tým neporadím, Victron nemám.
MUST PV1800 VHM 48V 5.5kW, 5.52kWp (12x TPL mono 460W, 2S2P východ, 2S4P juh), 16x 280 Ah LiFePO4 (14.3 kWh) BMS JBD-AP21S001-L21S-200A-B, SW: Home Assistant na Synology DS923+ ku tomu ESPHome, Tasmota, MariaDB, InfluxDB, Telegraf, Grafana, Zigbee2MQTT..., HW: ESPlan (ESP32 + LAN 8720 + RS485 + UART). Nejaké moje projekty: MUST-ESPhome, ELTEK Flatpack2 ESPhome, ESP32-EMON, PZEM-017@WiFi, diyBMS-CurrentShunt-ESPhome
Uživatelský avatar
rottenkiwi
Příspěvky: 5451
Registrován: pát úno 13, 2015 2:24 pm
Lokalita: SO, SK
Bydliště: SO, SK

Re: Home Assistant

Příspěvek od rottenkiwi »

:celebrate2: Parada, uz pise aj hodnotu. :celebrate2:
Přílohy
HA_MQTT_II.png
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
Uživatelský avatar
rottenkiwi
Příspěvky: 5451
Registrován: pát úno 13, 2015 2:24 pm
Lokalita: SO, SK
Bydliště: SO, SK

Re: Home Assistant

Příspěvek od rottenkiwi »

Teraz by som chcel na zaklade tychto napati, teplot a switchov urobit automatizaciu:

Napr. ak je Esp32_Cell_3 < 3.111 V
a sucasne je Esp32_Temp_2 > 25.0 *C
a sucasne je Esp32_SW_2 == "ON"

zapni mi SamsungTV a na nom spust "putin.mp3" z adresara Media.

.
HA_automation.png
Tu je kod z ESP32:

Kód: Vybrat vše

#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <AsyncMqttClient.h>
#include <Arduino_JSON.h>
#include <AsyncElegantOTA.h>
#include <Audio.h>
#include <SD.h>
#include <FS.h>
#include <SPI.h>
//#include "SPIFFS.h"
#include <Adafruit_ADS1X15.h>
//#include <LiquidCrystal_I2C.h>
//#include <OneWire.h>
//#include <DallasTemperature.h>
//#include <DS1307ESP.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_AMG88xx.h>
//#include <WiFiManager.h>


#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define SCREEN_ADDRESS 0x3C //< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1   );

Adafruit_AMG88xx amg;

Adafruit_ADS1115 ads0;
/*
uint8_t address = 0x27;
uint8_t cols = 20;
uint8_t rows = 4;
LiquidCrystal_I2C lcd( address, cols, rows );

DS1307ESP rtc;
*/

RTC_DATA_ATTR int bootCount = 0;

const char* host = "esp32_1";
const char* ssid = "guest";
const char* password = "kiwi123";

#define MQTT_HOST IPAddress(192, 168, 1, 25)

#define MQTT_PORT 1883

#define MQTT_V1 "esp32/V1"
#define MQTT_V2  "esp32/V2"
#define MQTT_V3 "esp32/V3"
#define MQTT_V4  "esp32/V4"
#define MQTT_A1  "esp32/A1"
#define MQTT_A2  "esp32/A2"
#define MQTT_T1  "esp32/T1"
#define MQTT_T2  "esp32/T2"
#define MQTT_SW1 "esp32/SW1"
#define MQTT_SW2 "esp32/SW2"
#define MQTT_SW3 "esp32/SW3"
#define MQTT_SW4 "esp32/SW4"
#define MQTT_SW5 "esp32/SW5"
#define MQTT_SW6 "esp32/SW6"

AsyncMqttClient mqttClient;
TimerHandle_t mqttReconnectTimer;
TimerHandle_t wifiReconnectTimer;


String ssid_sd;
String pass_sd;
char   ssid_ch [32] ;
char   pass_ch [32] ;

File ff_sd;
int cred_OK;

File dataFile;

AsyncWebServer server(80);
AsyncWebSocket ws("/ws");

String tempA [10] = { "29.12","28.95","0.22","0.21","3.674","3.756","3.811", "3.770","3.18","3.62"  };

String message = "";
String buffer_1 = "                  ";
String sliderValue1 = "0";
String sliderValue2 = "0";
String sliderValue3 = "0";
String sliderValue4 = "0";

int dutyCycle1;
int dutyCycle2;
int dutyCycle3;
int dutyCycle4;

const float volts0_off =  0.001;
const float volts1_off =  0.002;
const float volts2_off =  0.002;
const float volts3_off =  0.002;
const float min_cell_v = 3.001;
const float max_cell_v = 3.390;

int16_t adc0, adc1, adc2, adc3, adc1_0;
int32_t adc_avg;

float volts0, volts1, volts2, volts3, volts1_0, V_IN, V_OUT, V_OC;
float cell0, cell1, cell2, cell3;

unsigned long previous = 0;   // Stores last time temperature was published
const long interval = 9999;   

JSONVar sliderValues;

bool ledState_0, previos_ledState_0 = 0;
bool ledState_1, previos_ledState_1 = 0;
bool ledState_2, previos_ledState_2 = 0;
bool ledState_3, previos_ledState_3 = 0;
bool ledState_4, previos_ledState_4 = 0;
bool ledState_5, previos_ledState_5 = 0;

int volume = 21;
int ledPin = 2;

int PWM_Pin_12 = 12;
int PWM_Pin_14 = 14;

#define MAX_PWM 1000
#define MIN_PWM 400

int PWM_1_duty = MIN_PWM;
int PWM_2_duty = MIN_PWM;

const int PWM_1_freq = 10000;
const int PWM_1_channel = 0;
const int PWM_1_resolution = 10;

const int PWM_2_freq = 10000;
const int PWM_2_channel = 1;
const int PWM_2_resolution = 10;

#define NUM_OUTPUTS 6

// Assign each GPIO to an output
int outputGPIOs [NUM_OUTPUTS][ 2 ] = { {2, 0 }, { 4, 0 }, { 13,0 }, { 15, 0}, { 16,0 }, { 17, 0}  };

bool amg_status;
float pixels [AMG88xx_PIXEL_ARRAY_SIZE];
float amg_t_min, amg_t_max;

#define SD_CS     5
#define SPI_MOSI  23
#define SPI_MISO  19
#define SPI_SCK   18

#define I2S_DOUT  25
#define I2S_BCLK  26
#define I2S_LRC   27

Audio audio;

String file_list[32];
String file_list_i [6];
int file_num_i = 0;
int file_index_i = 0;
char filename  [64];
int file_num = 0;
int file_index = 0;


void connectToWifi() {
  Serial.println("Connecting to Wi-Fi...");
  WiFi.begin( ssid, password );
}


void connectToMqtt() {
  Serial.println("Connecting to MQTT...");
  mqttClient.connect();
}


void WiFiEvent(WiFiEvent_t event) {
  Serial.printf("[WiFi-event] event: %d\n", event);
  switch(event) {
    case SYSTEM_EVENT_STA_GOT_IP:
      Serial.println("WiFi connected");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());
      connectToMqtt();
      break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
      Serial.println("WiFi lost connection");
      xTimerStop(mqttReconnectTimer, 0); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi
      xTimerStart(wifiReconnectTimer, 0);
      break;
  }
}


void onMqttConnect(bool sessionPresent) {
  Serial.println("Connected to MQTT.");
  Serial.print("Session present: ");
  Serial.println(sessionPresent);
}

void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
  Serial.println("Disconnected from MQTT.");
  if (WiFi.isConnected()) {
    xTimerStart(mqttReconnectTimer, 0);
  }
}

void onMqttPublish(uint16_t packetId) {
  
}


struct Music_info
{
    String name;
    int length;
    int runtime;
    int volume;
    int status;
    int mute_volume;
} music_info = {"", 0, 0, 0, 0, 0};
 


void initFS() {
  if (!SPIFFS.begin()) {
    Serial.println("An error has occurred while mounting SPIFFS");
  }
  else{
   Serial.println("SPIFFS mounted successfully");
  }
}


void initWiFi() {
  WiFi.mode(WIFI_STA);


  if ( cred_OK )
  {
    int len = ssid_sd.length () + 1;
    ssid_sd.toCharArray ( ssid_ch, len ) ;
    len = pass_sd.length () + 1;
    pass_sd.toCharArray ( ssid_ch, len ) ;
    WiFi.begin(ssid_ch, pass_ch);
    display.clearDisplay();
    display.setTextSize(1); // Draw 2X-scale text
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(10, 0);
    display.println( "Wifi Cred OK");
    //Serial.println(WiFi.localIP());
    display.println( WiFi.localIP());
    display.display(); 
    delay(900);
  
  }
  else
  {
    WiFi.begin(ssid, password); 
    display.clearDisplay();
    display.setTextSize(1); // Draw 2X-scale text
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(10, 0);
    display.println( "Wifi Cred Missing");
    //Serial.println(WiFi.localIP());
    display.println( WiFi.localIP());
    display.display(); 
    delay(900);
  }
     int i = 0;
    while ( ( WiFi.status() != WL_CONNECTED) && ( i < 5  )) {
      Serial.print('.');
      delay(900);
      i++;
    }
     display.clearDisplay();
   display.setTextSize(1); // Draw 2X-scale text
   display.setTextColor(SSD1306_WHITE);
   display.setCursor(10, 0);
   display.println( WiFi.localIP());
   display.display(); 
     delay(900);
}


void notifyClients(String state) {
  ws.textAll(state);
}

/*
void notifyClients() {
  ws.textAll(String(ledState));
  ws.textAll(String(ledState_1));
  ws.textAll(String(amg_t_max));
}
*/

String getSliderValues(){
  sliderValues["sliderValue1"] = String(sliderValue1);
  sliderValues["sliderValue2"] = String(sliderValue2);
  sliderValues["sliderValue3"] = String(sliderValue3);
  sliderValues["sliderValue4"] = String(sliderValue4);
  String jsonString = JSON.stringify(sliderValues);
  return jsonString;
}


String getOutputStates(){
  JSONVar myArray;
  for (int i =0; i<NUM_OUTPUTS; i++){
    myArray["gpios"][i]["output"] = String( outputGPIOs[i][0]);
    myArray["gpios"][i]["state"] = String( outputGPIOs[i][1]);
  }
  String jsonString = JSON.stringify(myArray);
  return jsonString;
}


void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) {
  AwsFrameInfo *info = (AwsFrameInfo*)arg;
  if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
    data[len] = 0;
    if (strcmp((char*)data, "states") == 0) {
      notifyClients(getOutputStates());
    }
    else{
      int gpio = atoi((char*)data);   
      digitalWrite(gpio, !digitalRead(gpio));
      if ( gpio == 2 ) ledState_0 = !ledState_0;
      if ( gpio == 4 ) ledState_1 = !ledState_1;
      if ( gpio == 13 ) ledState_2 = !ledState_2;
      if ( gpio == 15 ) ledState_3 = !ledState_3;
      if ( gpio == 16 ) ledState_4 = !ledState_4;
      if ( gpio == 17 ) ledState_5 = !ledState_5;
      for (int i =0; i<NUM_OUTPUTS; i++){
         if ( gpio == outputGPIOs[i][0]) outputGPIOs[i][1] = !outputGPIOs[i][1];
          
      }
      notifyClients(getOutputStates());
    }
  
    if (strcmp((char*)data, "getValues") == 0) {
      notifyClients(getSliderValues());
    }
  }
}

void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type,
             void *arg, uint8_t *data, size_t len) {
  switch (type) {
    case WS_EVT_CONNECT:
      Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
      break;
    case WS_EVT_DISCONNECT:
      Serial.printf("WebSocket client #%u disconnected\n", client->id());
      break;
    case WS_EVT_DATA:
      handleWebSocketMessage(arg, data, len);
      break;
    case WS_EVT_PONG:
    case WS_EVT_ERROR:
      break;
  }
}

void initWebSocket() {
  ws.onEvent(onEvent);
  server.addHandler(&ws);
}

String processor(const String& var){
  Serial.println(var);
    if(var == "TEMPERATUREA"){
    return tempA[0];
  }
  else if(var == "TEMPERATUREB"){
    return tempA[1];
  }
  else if(var == "TEMPERATUREC"){
    return tempA[2];
  }
  else if(var == "TEMPERATURED"){
    return tempA[3];
  }
   else if(var == "TEMPERATUREE"){
    return tempA[4];
  }
   else if(var == "TEMPERATUREF"){
    return tempA[5];
  }
   else if(var == "TEMPERATUREG"){
    return tempA[6];
  }
   else if(var == "TEMPERATUREH"){
    return tempA[7];
  }
   else if(var == "TEMPERATUREI"){
    return tempA[8];
  }
   else if(var == "TEMPERATUREJ"){
    return tempA[9];
  }
  return String();
}
 
int get_music_list(fs::FS &fs, const char *dirname, uint8_t levels, String wavlist[30])
{
    Serial.printf("Listing directory: %s\n", dirname);
    int i = 0;
 
    File root = fs.open(dirname);
    if (!root)
    {
        Serial.println("Failed to open directory");
        return i;
    }
    if (!root.isDirectory())
    {
        Serial.println("Not a directory");
        return i;
    }
 
    File file = root.openNextFile();
    while (file)
    {
        if (file.isDirectory())
        {
        }
        else
        {
            String temp = file.name();
            if (temp.endsWith(".wav"))
            {
                wavlist[i] = temp;
                i++;
            }
            else if (temp.endsWith(".mp3"))
            {
                wavlist[i] = temp;
                i++;
            }
        }
        file = root.openNextFile();
    }
    return i;
}


void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
    Serial.printf("Listing directory: %s\n", dirname);

    File root = fs.open(dirname);
    if(!root){
        Serial.println("Failed to open directory");
        return;
    }
    if(!root.isDirectory()){
        Serial.println("Not a directory");
        return;
    }

    File file = root.openNextFile();
    while(file){
        if(file.isDirectory()){
            Serial.print("  DIR : ");
            Serial.println(file.name());
            if(levels){
                listDir(fs, file.path(), levels -1);
            }
        } else {
            Serial.print("  FILE: ");
            Serial.print(file.name());
            Serial.print("  SIZE: ");
            Serial.println(file.size());
        }
        file = root.openNextFile();
    }
}

void createDir(fs::FS &fs, const char * path){
    Serial.printf("Creating Dir: %s\n", path);
    if(fs.mkdir(path)){
        Serial.println("Dir created");
    } else {
        Serial.println("mkdir failed");
    }
}

void removeDir(fs::FS &fs, const char * path){
    Serial.printf("Removing Dir: %s\n", path);
    if(fs.rmdir(path)){
        Serial.println("Dir removed");
    } else {
        Serial.println("rmdir failed");
    }
}

void readFile(fs::FS &fs, const char * path){
    Serial.printf("Reading file: %s\n", path);

    File file = fs.open(path);
    if(!file){
        Serial.println("Failed to open file for reading");
        return;
    }

    Serial.print("Read from file: ");
    while(file.available()){
        Serial.write(file.read());
    }
    file.close();
}

void writeFile(fs::FS &fs, const char * path, const char * message){
    Serial.printf("Writing file: %s\n", path);

    File file = fs.open(path, FILE_WRITE);
    if(!file){
        Serial.println("Failed to open file for writing");
        return;
    }
    if(file.print(message)){
        Serial.println("File written");
    } else {
        Serial.println("Write failed");
    }
    file.close();
}

void appendFile(fs::FS &fs, const char * path, const char * message){
    Serial.printf("Appending to file: %s\n", path);

    File file = fs.open(path, FILE_APPEND);
    if(!file){
        Serial.println("Failed to open file for appending");
        return;
    }
    if(file.print(message)){
        Serial.println("Message appended");
    } else {
        Serial.println("Append failed");
    }
    file.close();
}

void renameFile(fs::FS &fs, const char * path1, const char * path2){
    Serial.printf("Renaming file %s to %s\n", path1, path2);
    if (fs.rename(path1, path2)) {
        Serial.println("File renamed");
    } else {
        Serial.println("Rename failed");
    }
}

void deleteFile(fs::FS &fs, const char * path){
    Serial.printf("Deleting file: %s\n", path);
    if(fs.remove(path)){
        Serial.println("File deleted");
    } else {
        Serial.println("Delete failed");
    }
}

void testFileIO(fs::FS &fs, const char * path){
    File file = fs.open(path);
    static uint8_t buf[512];
    size_t len = 0;
    uint32_t start = millis();
    uint32_t end = start;
    if(file){
        len = file.size();
        size_t flen = len;
        start = millis();
        while(len){
            size_t toRead = len;
            if(toRead > 512){
                toRead = 512;
            }
            file.read(buf, toRead);
            len -= toRead;
        }
        end = millis() - start;
        Serial.printf("%u bytes read for %u ms\n", flen, end);
        file.close();
    } else {
        Serial.println("Failed to open file for reading");
    }


    file = fs.open(path, FILE_WRITE);
    if(!file){
        Serial.println("Failed to open file for writing");
        return;
    }

    size_t i;
    start = millis();
    for(i=0; i<2048; i++){
        file.write(buf, 512);
    }
    end = millis() - start;
    Serial.printf("%u bytes written for %u ms\n", 2048 * 512, end);
    file.close();
}

Kód: Vybrat vše

const char* loginIndex =
 "<form name='loginForm'>"
    "<table width='20%' bgcolor='A09F9F' align='center'>"
        "<tr>"
            "<td colspan=2>"
                "<center><font size=4><b>ESP32 Login Page</b></font></center>"
                "<br>"
            "</td>"
            "<br>"
            "<br>"
        "</tr>"
        "<tr>"
             "<td>Username:</td>"
             "<td><input type='text' size=25 name='userid'><br></td>"
        "</tr>"
        "<br>"
        "<br>"
        "<tr>"
            "<td>Password:</td>"
            "<td><input type='Password' size=25 name='pwd'><br></td>"
            "<br>"
            "<br>"
        "</tr>"
        "<tr>"
            "<td><input type='submit' onclick='check(this.form)' value='Login'></td>"
        "</tr>"
    "</table>"
"</form>"
"<script>"
    "function check(form)"
    "{"
    "if(form.userid.value=='admin' && form.pwd.value=='admin')"
    "{"
    "window.open('/serverIndex')"
    "}"
    "else"
    "{"
    " alert('Error Password or Username')/*displays error message*/"
    "}"
    "}"
"</script>";

/*
 * Server Index Page
 */

const char* serverIndex =
"<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>"
"<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"
   "<input type='file' name='update'>"
        "<input type='submit' value='Update'>"
    "</form>"
 "<div id='prg'>progress: 0%</div>"
 "<script>"
  "$('form').submit(function(e){"
  "e.preventDefault();"
  "var form = $('#upload_form')[0];"
  "var data = new FormData(form);"
  " $.ajax({"
  "url: '/update',"
  "type: 'POST',"
  "data: data,"
  "contentType: false,"
  "processData:false,"
  "xhr: function() {"
  "var xhr = new window.XMLHttpRequest();"
  "xhr.upload.addEventListener('progress', function(evt) {"
  "if (evt.lengthComputable) {"
  "var per = evt.loaded / evt.total;"
  "$('#prg').html('progress: ' + Math.round(per*100) + '%');"
  "}"
  "}, false);"
  "return xhr;"
  "},"
  "success:function(d, s) {"
  "console.log('success!')"
 "},"
 "error: function (a, b, c) {"
 "}"
 "});"
 "});"
 "</script>";

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <title>ESP Web Server</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="data:,">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
  <style>
  html {
    font-family: Arial, Helvetica, sans-serif;
    text-align: center;
  }
  h1 {
    font-size: 1.8rem;
    color: white;
  }
  h2{
    font-size: 1.5rem;
    font-weight: bold;
    color: #143642;
  }
   p { font-size: 3.0rem; }
    .units { font-size: 1.2rem; }
    .ds-labels{
      font-size: 1.5rem;
      vertical-align:middle;
      padding-bottom: 15px;
   }
  .topnav {
    overflow: hidden;
    background-color: #143642;
  }
  body {
    margin: 0;
  }
  .content {
    padding: 30px;
    max-width: 1600px;
    margin: 0 auto;
  }
  .card-grid { 
    max-width: 1600px; 
    margin: 0 auto; 
    display: grid; 
    gap: 2rem; 
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  }
  .card {
    background-color: #989799;;
    box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5);
    padding-top:10px;
    padding-bottom:20px;
  }
  .card-title { 
    font-size: 1.2rem;
    font-weight: bold;
    color: #034078
  }
  .button {
    padding: 15px 50px;
    font-size: 24px;
    text-align: center;
    outline: none;
    color: #fff;
    background-color: #0f8b8d;
    border: none;
    border-radius: 5px;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: rgba(0,0,0,0);
   }
   /*.button:hover {background-color: #0f8b8d}*/
   .button:active {
     background-color: #0f8b8d;
     box-shadow: 2 2px #CDCDCD;
     transform: translateY(2px);
   }
   .state {
     font-size: 1.5rem;
     color:#3c3cac;
     font-weight: bold;
   }
   .state_temp {
     font-size: 1.5rem;
     color:#cc2c2c;
     font-weight: bold;
   }
   .switch {
    position: relative; 
    display: inline-block; 
    width: 120px; 
    height: 68px
   } 
.switch input {
    display: none
   }
.slider {
    position: absolute; 
    top: 0; left: 0; right: 0; bottom: 0; 
    background-color: #ccc; 
    border-radius: 50px
   }
.slider_1 {
    -webkit-appearance: none;
    margin: 0 auto;
    width: 100%;
    height: 10px;
    border-radius: 50px;
    background: #03D65C;
    outline: none;
  }  
.slider:before {
    position: absolute; 
    content: ""; 
    height: 52px; 
    width: 52px; 
    left: 8px; 
    bottom: 8px; 
    background-color: #fff; 
    -webkit-transition: .4s; 
    transition: .4s;
    border-radius: 50px;
   }
input:checked+.slider {
    background-color: #c31020;
   }
input:checked+.slider:before {
    -webkit-transform: translateX(52px);
    -ms-transform: translateX(52px); 
    transform: translateX(52px);
   }
  </style>
<title>ESP Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
</head>
<body>
  <div class="topnav">
    <h1>ESP WebSocket Server</h1>
  </div>
  <div class="content">
    <div class="card-grid">
        <div class="card">             
            <p class="card-title"><i class="fas fa-lightbulb"></i> GPIO 2</p>
            <label class="switch">
                <input type="checkbox" onchange="toggleCheckbox(this)" id="2">
                <span class="slider"></span>
            </label>
            <p class ="state">State: <span id="2s"></span></p>
        </div>
        <div class="card">
            <p class="card-title"><i class="fas fa-lightbulb"></i> GPIO 4</p>
            <label class="switch">
                <input type="checkbox" onchange="toggleCheckbox(this)" id="4">
                <span class="slider"></span>
            </label>
            <p class ="state">State: <span id="4s"></span></p>
        </div>
        <div class="card">
            <p class="card-title"><i class="fas fa-lightbulb"></i> GPIO 12</p>
            <label class="switch">
                <input type="checkbox" onchange="toggleCheckbox(this)" id="13">
                <span class="slider"></span>
            </label>
            <p class ="state">State: <span id="13s"></span></p>
        </div>
        <div class="card">
            <p class="card-title"><i class="fas fa-lightbulb"></i> GPIO 14</p>
            <label class="switch">
                <input type="checkbox" onchange="toggleCheckbox(this)" id="15">
                <span class="slider"></span>
            </label>
            <p class="state">State: <span id="15s"></span></p>
        </div>
                <div class="card">
            <p class="card-title"><i class="fas fa-lightbulb"></i> GPIO 16</p>
            <label class="switch">
                <input type="checkbox" onchange="toggleCheckbox(this)" id="16">
                <span class="slider"></span>
            </label>
            <p class ="state">State: <span id="16s"></span></p>
        </div>
        <div class="card">
            <p class="card-title"><i class="fas fa-lightbulb"></i> GPIO 17</p>
            <label class="switch">
                <input type="checkbox" onchange="toggleCheckbox(this)" id="17">
                <span class="slider"></span>
            </label>
            <p class="state">State: <span id="17s"></span></p>
        </div>
    </div>
  </div>
   <p>
    <i class="fa-thermometer-half" style="color:#fe0e8a;"></i> 
    <span class="ds-labels">Temp AMG_0</span> 
    <span id="temperaturea">%TEMPERATUREA%</span>
    <sup class="units">°C</sup>
    <i class="fa-thermometer-half" style="color:#a5beba;"></i> 
    <span class="ds-labels">Temp AMG_1</span>
    <span id="temperatureb">%TEMPERATUREB%</span>
    <sup class="units">°C</sup>
     </p>
  <p>
    <i class="fa-thermometer-half" style="color:#9eff8a;"></i> 
    <span class="ds-labels">BMS AMPS_0</span> 
    <span id="temperaturec">%TEMPERATUREC%</span>
    <sup class="units">°A</sup>
    <i class="fa-thermometer-half" style="color:#97aeaa;"></i> 
    <span class="ds-labels">BMS_AMPS_1</span>
    <span id="temperatured">%TEMPERATURED%</span>
    <sup class="units">°A</sup>
  </p>
  <p>
    <i class="fa-thermometer-half" style="color:#08aefa;"></i> 
    <span class="ds-labels">V CELL_0</span>
    <span id="temperaturee">%TEMPERATUREE%</span>
    <sup class="units">°V</sup>
    <i class="fa-thermometer-half" style="color:#9eff8a;"></i> 
    <span class="ds-labels">V CELL_1</span> 
    <span id="temperaturef">%TEMPERATUREF%</span>
    <sup class="units">°V</sup>
    <i class="fa-thermometer-half" style="color:#9eff8a;"></i> 
    <span class="ds-labels">V CELL_2</span> 
    <span id="temperatureg">%TEMPERATUREG%</span>
    <sup class="units">°V</sup>
    <i class="fa-thermometer-half" style="color:#9eff8a;"></i> 
    <span class="ds-labels">V CELL_3</span> 
    <span id="temperatureh">%TEMPERATUREH%</span>
    <sup class="units">°V</sup>
  </p> 
  <p>
    <i class="fa-thermometer-half" style="color:#97aeaa;"></i> 
    <span class="ds-labels">W OUT</span>
    <span id="temperaturei">%TEMPERATUREI%</span>
    <sup class="units">°W</sup>
    <i class="fa-thermometer-half" style="color:#9eff8a;"></i> 
    <span class="ds-labels">W IN</span> 
    <span id="temperaturej">%TEMPERATUREJ%</span>
    <sup class="units">°W</sup>
  </p>
<script>
  var gateway = `ws://${window.location.hostname}/ws`;
  var websocket;
  window.addEventListener('load', onLoad);
  function initWebSocket() {
    console.log('Trying to open a WebSocket connection...');
    websocket = new WebSocket(gateway);
    websocket.onopen    = onOpen;
    websocket.onclose   = onClose;
    websocket.onmessage = onMessage;
  }
  function getValues(){
    websocket.send("getValues");
  }
  function onOpen(event) {
    console.log('Connection opened');
    getValues();
    websocket.send("states");
  }
  function onClose(event) {
    console.log('Connection closed');
    setTimeout(initWebSocket, 2000);
  }
  function onMessage_0 (event) {
    var myObj = JSON.parse(event.data);
            console.log(myObj);
    var keys = Object.keys(myObj);      
            for (i in myObj.gpios){
                var output = myObj.gpios[i].output;
                var state = myObj.gpios[i].state;
                console.log(output);
                console.log(state);
                if (state == "1"){
                    document.getElementById(output).checked = true;
                    document.getElementById(output+"s").innerHTML = "ON";
                }
                else{
                    document.getElementById(output).checked = false;
                    document.getElementById(output+"s").innerHTML = "OFF";
                }
            }
         
    console.log(event.data);
  }
  function onMessage_TEMP (event) {
    var state;
    document.getElementById('temp_1').innerHTML = event.data;
  }
  function onLoad(event) {
    initWebSocket();
  }
  function toggleCheckbox (element) {
    console.log(element.id);
    websocket.send(element.id);
    if (element.checked){
        document.getElementById(element.id+"s").innerHTML = "ON";
    }
    else {
        document.getElementById(element.id+"s").innerHTML = "OFF"; 
    }
  }
  function updateSliderPWM(element) {
    var sliderNumber = element.id.charAt(element.id.length-1);
    var sliderValue = document.getElementById(element.id).value;
    document.getElementById("sliderValue"+sliderNumber).innerHTML = sliderValue;
    console.log(sliderValue);
    websocket.send(sliderNumber+"s"+sliderValue.toString());
 }
 setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperaturea").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperaturea", true);
  xhttp.send();
}, 4000) ;
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperatureb").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperatureb", true);
  xhttp.send();
}, 4000) ;
  setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperaturec").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperaturec", true);
  xhttp.send();
}, 4000) ;
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperatured").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperatured", true);
  xhttp.send();
}, 4000) ;
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperaturee").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperaturee", true);
  xhttp.send();
}, 4000) ;
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {

    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperaturef").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperaturef", true);
  xhttp.send();
}, 4000) ;
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {

    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperatureg").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperatureg", true);
  xhttp.send();
}, 4000) ;
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {

    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperatureh").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperatureh", true);
  xhttp.send();
}, 4000) ;
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {

    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperaturei").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperaturei", true);
  xhttp.send();
}, 4000) ;
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {

    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("temperaturej").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/temperaturej", true);
  xhttp.send();
}, 4000) ;
</script>
</body>
</html>)rawliteral";

Kód: Vybrat vše

void loop() {
  // put your main code here, to run repeatedly:
   audio.loop();
   char buff[20];
   unsigned long now = millis();
   if (now - previous > interval ) {
      previous = now;
      adc0 =  ads0.readADC_SingleEnded(0);
      adc1  = ads0.readADC_SingleEnded(1);
      adc2 = ads0.readADC_SingleEnded(2);
      adc3 = ads0.readADC_SingleEnded(3);
      volts0 = ads0.computeVolts(adc0);
      volts1 = ads0.computeVolts(adc1);
      volts2 = ads0.computeVolts(adc2);
      volts3 = ads0.computeVolts(adc3);
      volts0 = volts0_off + volts0 * 6.1559;  // 3.318  3.321 3.312 3.312
      volts1 = volts1_off + volts1 * 6.1430;  //        6.639 9.951 13.263
      volts2 = volts2_off + volts2 * 6.1290;  // 3.33   6.68  10.04 13.34
      volts3 = volts3_off + volts3 * 6.1481;
      cell0 = volts0;
      cell1 = volts1 - volts0;
      cell2 = volts2 - volts1;
      cell3 = volts3 - volts2;
      tempA [4] = String ( cell0,3 ); 
      tempA [5] = String ( cell1,3 ); 
      tempA [6] = String( cell2,3 ); 
      tempA [7] = String( cell3,3 ); 
      String s = String(cell0,4)+ ", "+String(cell1,4)+", "+String(cell2,4)+", "+String(cell1,3)+" \n";
      
      appendFile(SD, "/datalog_0.txt", String(s).c_str() );
     
   
          // Publish an MQTT message on topic esp32/V1
   uint16_t packetIdPub1 = mqttClient.publish(MQTT_V1, 1, true, String(cell0,4).c_str());                            
  // Serial.printf("Publishing on topic %s at QoS 1, packetId: %i", MQTT_V1, packetIdPub1);
  // Serial.printf("Message: %.2f \n", cell0);

    // Publish an MQTT message on topic esp32/V2
    uint16_t packetIdPub2 = mqttClient.publish(MQTT_V2, 1, true, String(cell1,4).c_str());                            
 //  Serial.printf("Publishing on topic %s at QoS 1, packetId %i: ", MQTT_V2, packetIdPub2);
 //  Serial.printf("Message: %.2f \n", cell1);

     // Publish an MQTT message on topic esp32/V3
   uint16_t packetIdPub3 = mqttClient.publish(MQTT_V3, 1, true, String(cell2,4).c_str());                            
  // Serial.printf("Publishing on topic %s at QoS 1, packetId: %i", MQTT_V3, packetIdPub3);
   //Serial.printf("Message: %.2f \n",cell2);

     // Publish an MQTT message on topic esp32/V3
   uint16_t packetIdPub4 = mqttClient.publish(MQTT_V4, 1, true, String(cell3,4).c_str());                            
   //Serial.printf("Publishing on topic %s at QoS 1, packetId: %i", MQTT_V4, packetIdPub3);
  // Serial.printf("Message: %.2f \n",cell3);


    // Publish an MQTT message on topic esp32/V4
   uint16_t packetIdPub5 = mqttClient.publish(MQTT_A2, 1, true, tempA [2].c_str());                            
   //Serial.printf("Publishing on topic %s at QoS 1, packetId %i: ", MQTT_A2, packetIdPub4);
  // Serial.printf("Message: %.2f \n", tempA [2]);
    
    // Publish an MQTT message on topic esp32/A1
    uint16_t packetIdPub6 = mqttClient.publish(MQTT_A1, 1, true, tempA [3].c_str());                            
 //   Serial.printf("Publishing on topic %s at QoS 1, packetId %i: ", MQTT_A1, packetIdPub5);
  // Serial.printf("Message: %.2f \n", tempA [3]);

       // Publish an MQTT message on topic esp32/V4
   uint16_t packetIdPub7 = mqttClient.publish(MQTT_T1, 1, true, String(amg_t_min,4).c_str());                            
 //  Serial.printf("Publishing on topic %s at QoS 1, packetId %i: ", MQTT_T1, packetIdPub4);
 //  Serial.printf("Message: %.2f \n", amg_t_min);
    
    // Publish an MQTT message on topic esp32/A1
    uint16_t packetIdPub8 = mqttClient.publish(MQTT_T2, 1, true, String(amg_t_max,4).c_str());                            
 //   Serial.printf("Publishing on topic %s at QoS 1, packetId %i: ", MQTT_T2, packetIdPub5);
 //  Serial.printf("Message: %.2f \n", amg_t_max);

      
   }
   if ( previos_ledState_0 != ledState_0 )
   {
       previos_ledState_0 = ledState_0;
       if ( ledState_0 )
       {
         uint16_t packetIdPub9 = mqttClient.publish(MQTT_SW1, 1, true, String("ON").c_str()); 
       }
       else
       {
         uint16_t packetIdPub9 = mqttClient.publish(MQTT_SW1, 1, true, String("OFF").c_str());
       }
       file_list[file_index++ ].toCharArray(filename, 64);
       Serial.println( filename );
       delay (1);
       audio.connecttoFS (SD, filename );
       file_index = file_index % file_num;
        display.clearDisplay();
          
        display.setTextSize(1); // Draw 2X-scale text
        display.setTextColor(SSD1306_WHITE);
        display.setCursor(10, 0);
        display.println( filename );
        sprintf(buff, "%d:%d", audio.getAudioCurrentTime(),audio.getAudioFileDuration() );
        display.println(buff);
        display.println( audio.getAudioFileDuration() );
        
        amg.readPixels(pixels);
        amg_t_min = 200.0;
        amg_t_max = 0.0;
        for(int i=0; i<AMG88xx_PIXEL_ARRAY_SIZE; i++){
           if ( pixels[i] < amg_t_min )
           {
              amg_t_min = pixels[i];
                tempA [0] = String(amg_t_min);
           }
           if ( pixels[i] > amg_t_max )
           {
              amg_t_max = pixels[i];
              tempA [1] = String(amg_t_max);
           }
        }
        display.println( amg_t_max );
        display.println( " *C" );
        display.display();      // Show initial text
        delay(10);
   }

    if ( previos_ledState_1 != ledState_1 )
   {
       previos_ledState_1 = ledState_1;
       if ( ledState_1 )
       {
         uint16_t packetIdPub10 = mqttClient.publish(MQTT_SW2, 1, true, String("ON").c_str()); 
       }
       else
       {
         uint16_t packetIdPub10 = mqttClient.publish(MQTT_SW2, 1, true, String("OFF").c_str());
       }
       file_list_i [file_index_i++ ].toCharArray(filename, 64);
        file_index_i = file_index_i % file_num_i;
       Serial.println( filename );
       delay (1);
        audio.connecttohost( filename );
        display.clearDisplay();
          
        display.setTextSize(1); // Draw 2X-scale text
        display.setTextColor(SSD1306_WHITE);
        display.setCursor(10, 0);
        display.println( filename );
        amg.readPixels(pixels);
        amg_t_min = 200.0;
        amg_t_max = 0.0;
        for(int i=0; i<AMG88xx_PIXEL_ARRAY_SIZE; i++){
           if ( pixels[i] < amg_t_min )
           {
              amg_t_min = pixels[i];
               tempA [0] = String(amg_t_min);
           }
           if ( pixels[i] > amg_t_max )
           {
              amg_t_max = pixels[i];
               tempA [1] = String(amg_t_max);
           }
        }
        display.println( amg_t_max );
        display.println( " *C" );
        display.display();      // Show initial text
        delay(10);
   }


   if ( previos_ledState_2 != ledState_2 )
   {
    
       previos_ledState_2 = ledState_2;
       if ( ledState_2 )
       {
         uint16_t packetIdPub11 = mqttClient.publish(MQTT_SW3, 1, true, String("ON").c_str()); 
       }
       else
       {
         uint16_t packetIdPub11 = mqttClient.publish(MQTT_SW3, 1, true, String("OFF").c_str());
       }
        volume = volume + 1;
        volume = volume % 22;
        audio.setVolume ( volume );
        
        amg.readPixels(pixels);
        amg_t_min = 200.0;
        amg_t_max = 0.0;
        for(int i=0; i<AMG88xx_PIXEL_ARRAY_SIZE; i++){
           if ( pixels[i] < amg_t_min )
           {
              amg_t_min = pixels[i];
               tempA [0] = String(amg_t_min);
           }
           if ( pixels[i] > amg_t_max )
           {
              amg_t_max = pixels[i];
               tempA [1] = String(amg_t_max);
           }
        }
        
        display.clearDisplay();
          
        display.setTextSize(1); // Draw 2X-scale text
        display.setTextColor(SSD1306_WHITE);
        display.setCursor(10, 0);
        display.print( "Volume: ");
        display.println( volume );
        display.print( amg_t_max );
        display.println( " *C" );
        display.print( "Cell_0: ");
        display.print ( cell0 );
        display.print( " Cell_1: ");
        display.println ( cell1 );
        display.print( "Cell_2: ");
        display.print ( cell2 );
        display.print( " Cell_3: ");
        display.println ( cell3 );   
        display.display();      // Show initial text
        delay(1);
    }
   
  
   if ( previos_ledState_4 != ledState_4 )
   {
       previos_ledState_4 = ledState_4; 
         if ( ledState_4 )
       {
         uint16_t packetIdPub12 = mqttClient.publish(MQTT_SW5, 1, true, String("ON").c_str()); 
       }
       else
       {
         uint16_t packetIdPub12 = mqttClient.publish(MQTT_SW5, 1, true, String("OFF").c_str());
       }  
       PWM_1_duty = PWM_1_duty + 50;
       if ( PWM_1_duty >= MAX_PWM ) PWM_1_duty = MIN_PWM;
       ledcWrite(PWM_1_channel, PWM_1_duty );    
   }


   if ( previos_ledState_5 != ledState_5 )
   {
       previos_ledState_5 = ledState_5;
       if ( ledState_5 )
       {
         uint16_t packetIdPub13 = mqttClient.publish(MQTT_SW6, 1, true, String("ON").c_str()); 
       }
       else
       {
         uint16_t packetIdPub13 = mqttClient.publish(MQTT_SW6, 1, true, String("OFF").c_str());
       }  
          PWM_2_duty = PWM_2_duty + 50;
       if ( PWM_2_duty >= MAX_PWM ) PWM_2_duty = MIN_PWM;
        ledcWrite(PWM_2_channel , PWM_2_duty);
   }
  
   
   // ws.cleanupClients();
}

Kód: Vybrat vše


void setup() {

   Serial.begin(115200);
   //rtc.begin();
   pinMode (SD_CS, OUTPUT);
   digitalWrite (SD_CS, HIGH  );

   SPI.begin (SPI_SCK, SPI_MISO, SPI_MOSI, SD_CS );

   cred_OK = 0;

   if (!SD.begin(SD_CS)) {
    Serial.println("Failed to initializeSD.");
    /*
   lcd.init();    
   lcd.backlight(); 
   lcd.setCursor(1,0);
   lcd.print("uSD card_NOTOK");
   */
    while (1);
  }

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

   pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

    pinMode(4, OUTPUT);   digitalWrite(4, LOW);

  pinMode(16, OUTPUT);   digitalWrite(16, LOW); 
  pinMode(17, OUTPUT);   digitalWrite(17, LOW);
  pinMode(13, OUTPUT);   digitalWrite(13, LOW); 
  pinMode(15, OUTPUT);   digitalWrite(15, LOW);


   ff_sd = SD.open("arduino.txt", FILE_READ);
   if (ff_sd) {
     cred_OK = 1; 
     if ( ff_sd.available()) {
       ssid_sd = ff_sd.readString();
       pass_sd = ff_sd.readString();
     }
   }
   ff_sd.close();
   
   initWiFi();

  mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(1000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
  wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(1000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToWifi));

  WiFi.onEvent(WiFiEvent);

  mqttClient.onConnect(onMqttConnect);
  mqttClient.onDisconnect(onMqttDisconnect);
  //mqttClient.onSubscribe(onMqttSubscribe);
  //mqttClient.onUnsubscribe(onMqttUnsubscribe);
  mqttClient.onPublish(onMqttPublish);
  mqttClient.setServer(MQTT_HOST, MQTT_PORT);
  // If your broker requires authentication (username and password), set them below
  mqttClient.setCredentials("mqtt", "kiwi123");
  connectToWifi();


   amg_status = amg.begin ();

   display.clearDisplay();
   display.setTextSize(1); // Draw 2X-scale text
   display.setTextColor(SSD1306_WHITE);
   display.setCursor(10, 0);
   display.println( "BMS Init..." );
   if (!amg_status) {
      display.println("Could not find a valid AMG88xx sensor, check wiring!");
      while (1);
   }
   display.display(); 
   delay  (1000); 

   initWebSocket();

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(200, "text/plain", "Hi! I am ESP32. IP/update");
  });

  server.on("/index", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html, processor);
  });

  server.on("/temperaturea", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", tempA[0].c_str());
  });
  server.on("/temperatureb", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", tempA[1].c_str());
  });

    server.on("/temperaturee", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", tempA[4].c_str());
  });
   server.on("/temperaturef", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", tempA[5].c_str());
  });
   server.on("/temperatureg", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", tempA[6].c_str());
  });
   server.on("/temperatureh", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", tempA[7].c_str());
  });

  
 
  AsyncElegantOTA.begin(&server);
 
  server.begin();

  
    ledcSetup (PWM_1_channel, PWM_1_freq, PWM_1_resolution);
    ledcAttachPin(PWM_Pin_12 , PWM_1_channel);
    ledcWrite(PWM_1_channel, PWM_1_duty );

    ledcSetup (PWM_2_channel, PWM_2_freq, PWM_2_resolution);
    ledcAttachPin(PWM_Pin_14 , PWM_2_channel);
    ledcWrite(PWM_2_channel , PWM_2_duty);

  audio.setPinout (I2S_BCLK, I2S_LRC, I2S_DOUT);

  audio.setVolume (volume );
  // put your setup code here, to run once:

  ads0.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV
  if (!ads0.begin(0x48)) {
    Serial.println("Failed to initialize ADS.");
        display.clearDisplay();
        display.setTextSize(1); // Draw 2X-scale text
        display.setTextColor(SSD1306_WHITE);
        display.setCursor(10, 0);
        display.println( "1115_x48_NOTOK");
        display.display();      // Show initial text
        delay(1100);
  }
  
  
//  audio.connecttohost("http://iskatel.hostingradio.ru:8015/iskatel-320.aac");  // aac
//  audio.connecttohost("http://mcrscast.mcr.iol.pt/cidadefm");                  // mp3
//  audio.connecttohost("http://www.wdr.de/wdrlive/media/einslive.m3u");         // m3u
//  audio.connecttohost("https://stream.srg-ssr.ch/rsp/aacp_48.asx");            // asx
//  audio.connecttohost("http://tuner.classical102.com/listen.pls");             // pls
//  audio.connecttohost("http://stream.radioparadise.com/flac");   
  
  file_num_i = 6;
  file_list_i [5] = "http://iskatel.hostingradio.ru:8015/iskatel-320.aac";
  file_list_i [3] = "http://edge-bauerabsolute-05-gos2.sharp-stream.com/absolute90shigh.aac";
   file_list_i [0] = "http://www.wdr.de/wdrlive/media/einslive.m3u";
  file_list_i [4] = "http://edge.clrmedia.co.uk:10000/chiptunes";
   file_list_i [1] = "http://tuner.classical102.com/listen.pls";
  file_list_i [2] = "http://www.radiofeeds.net/playlists/80srhythmhq.m3u";
  
  
  Serial.println(file_list_i [0]);
  

  file_num = get_music_list(SD, "/", 0, file_list);
  Serial.print("Music file count:");
  Serial.println(file_num);
  Serial.println("All music:");
  for (int i = 0; i < file_num; i++)
  {
     Serial.println(file_list[i]);
  }

  file_list_i [0].toCharArray(filename, 64);
  audio.connecttoFS (SD, filename  );
  
  /*
    // ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default)
  ads0.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV
  //ads1.setGain(GAIN_ONE);  
  // ads.setGain(GAIN_TWO);        // 2x gain   +/- 2.048V  1 bit = 1mV      0.0625mV
  // ads.setGain(GAIN_FOUR);       // 4x gain   +/- 1.024V  1 bit = 0.5mV    0.03125mV
  // ads.setGain(GAIN_EIGHT);      // 8x gain   +/- 0.512V  1 bit = 0.25mV   0.015625mV
  // ads.setGain(GAIN_SIXTEEN);    // 16x gain  +/- 0.256V  1 bit = 0.125mV  0.0078125mV
  lcd.init();    
  lcd.backlight(); 
  lcd.setCursor(1,0);
  rtc.DSread(); 
  lcd.print( rtc.getTime() );
  lcd.setCursor(1,1);
  lcd.print( rtc.getDate() ); 
  delay (199);
  */
  file_index = 0;      
  file_index_i = 0;
  previous = millis();
  
}
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
Uživatelský avatar
rottenkiwi
Příspěvky: 5451
Registrován: pát úno 13, 2015 2:24 pm
Lokalita: SO, SK
Bydliště: SO, SK

Re: Home Assistant

Příspěvek od rottenkiwi »

Mam pridanu integraciu Victron
ale ziadne entity nie su k dispozicii ???

A dalsi problem je ze sa nedaju konfigurovat dve Venus OS zariadenia
integracia podporuje len jednu instanciu.

Tak ako si napisat vlastnu integraciu Venus OS, co podporuje vsetko co chcem ?

.-
HA_victron.png
DC-AC inverter REC Lion DC-AC ESP32 DIY inv. 15 GB za sekundu DIY MPPT Holder
Zjedz vsetko, co si kupil, v obchode a netreba ti tasku, auto ci chladnicku.
glottis
Příspěvky: 2101
Registrován: stř úno 02, 2022 10:30 am
Lokalita: okolí Mělníka
Systémové napětí: 48V
Výkon panelů [Wp]: 13000
Kapacita baterie [kWh]: 15

Re: Home Assistant

Příspěvek od glottis »

ip a port jsi zadal dobre? Modbus TCP v services na venus os mas zapnute?

Mas vic venus os? proc? Fakt nejde pridat znova stejna integrace na jine ip?

Pokud to nejde, muzes si to proste nacitat po staru po modbusu rucne no :)

  • Podobná témata
    Odpovědi
    Zobrazení
    Poslední příspěvek