first commit
This commit is contained in:
427
ESP8266_BATTERIE_INJECTION/victron.h
Normal file
427
ESP8266_BATTERIE_INJECTION/victron.h
Normal file
@@ -0,0 +1,427 @@
|
||||
char receivedChars[buffsize]; // an array to store the received data
|
||||
char tempChars[buffsize]; // an array to manipulate the received data
|
||||
char recv_label[num_keywords][label_bytes] = {0}; // {0} tells the compiler to initalize it with 0.
|
||||
char recv_value[num_keywords][value_bytes] = {0}; // That does not mean it is filled with 0's
|
||||
char value[num_keywords][value_bytes] = {0}; // The array that holds the verified data
|
||||
static byte blockindex = 0;
|
||||
bool blockend = false;
|
||||
double tension_batterie;
|
||||
|
||||
double intensite_decharge = 0;
|
||||
int outVal = 0;
|
||||
bool new_data = false;
|
||||
|
||||
long temps = 0;
|
||||
String last_serial_string = "";
|
||||
//
|
||||
//// ===================================================================
|
||||
//struct DataPair {
|
||||
// char key[10];
|
||||
// char value[20];
|
||||
//};
|
||||
//DataPair data[num_keywords]; // Tableau pour stocker les paires
|
||||
//int currentIndex = 0;
|
||||
//
|
||||
//
|
||||
//void storeDataPair(String line) {
|
||||
// int delimiterIndex = line.indexOf('\t'); // Trouver la position de la tabulation
|
||||
// if (delimiterIndex > 0 && currentIndex < num_keywords) {
|
||||
// // Extraire la clé et la valeur de la ligne
|
||||
// String key = line.substring(0, delimiterIndex);
|
||||
// String value = line.substring(delimiterIndex + 1);
|
||||
//
|
||||
// // Stocker la clé et la valeur dans le tableau
|
||||
// key.toCharArray(data[currentIndex].key, sizeof(data[currentIndex].key));
|
||||
// value.toCharArray(data[currentIndex].value, sizeof(data[currentIndex].value));
|
||||
// currentIndex++;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void processReceivedData(String data) {
|
||||
// currentIndex = 0; // Réinitialiser l'index pour les nouvelles données
|
||||
// int start = 0;
|
||||
// while (start < data.length()) {
|
||||
// int end = data.indexOf('\n', start);
|
||||
// if (end == -1) {
|
||||
// break;
|
||||
// }
|
||||
// String line = data.substring(start, end);
|
||||
// storeDataPair(line);
|
||||
// start = end + 1;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//
|
||||
//bool receivingData = false; // Indicateur pour savoir si nous sommes en train de recevoir des données
|
||||
//String receivedData = "";
|
||||
//// ===============================================================================
|
||||
|
||||
|
||||
|
||||
void addTension( struct tm* timeinfo, int value) {
|
||||
|
||||
if(value > 30000) {
|
||||
return;
|
||||
}
|
||||
// Si le tableau est plein, décaler toutes les valeurs vers la gauche
|
||||
if (to_store.total_elements >= maxSize) {
|
||||
for (int i = 1; i < maxSize; i++) {
|
||||
to_store.hour[i - 1] = to_store.hour[i];
|
||||
to_store.min[i - 1] = to_store.min[i];
|
||||
to_store.tensions[i - 1] = to_store.tensions[i];
|
||||
}
|
||||
to_store.hour[maxSize - 1] = timeinfo->tm_hour;
|
||||
to_store.min[maxSize - 1] = timeinfo->tm_min;
|
||||
to_store.tensions[maxSize - 1] = value; // Ajouter la nouvelle valeur à la fin
|
||||
} else {
|
||||
// Ajouter la nouvelle valeur à la fin
|
||||
//hour.toCharArray(to_store.hour[to_store.total_elements], sizeof(to_store.hour));
|
||||
to_store.hour[to_store.total_elements] = timeinfo->tm_hour;
|
||||
to_store.min[to_store.total_elements] = timeinfo->tm_min;
|
||||
to_store.tensions[to_store.total_elements] = value;
|
||||
to_store.total_elements++;
|
||||
}
|
||||
to_store.total_elements %= maxSize;
|
||||
|
||||
EEPROM.put(TO_STORE_ADDRESS, to_store);
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
// Serial Handling
|
||||
// ---
|
||||
// This block handles the serial reception of the data in a
|
||||
// non blocking way. It checks the Serial line for characters and
|
||||
// parses them in fields. If a block of data is send, which always ends
|
||||
// with "Checksum" field, the whole block is checked and if deemed correct
|
||||
// copied to the 'value' array.
|
||||
|
||||
void recvWithEndMarker() {
|
||||
static byte ndx = 0;
|
||||
char endMarker = '\n';
|
||||
char rc;
|
||||
// new_data = false;
|
||||
#ifdef ESP8266
|
||||
while (victronSerial.available() > 0 && new_data == false) {
|
||||
rc = victronSerial.read();
|
||||
#else
|
||||
while (Serial1.available() > 0 && new_data == false) {
|
||||
rc = Serial1.read();
|
||||
#endif
|
||||
last_serial_string += rc;
|
||||
if (rc != endMarker) {
|
||||
receivedChars[ndx] = rc;
|
||||
ndx++;
|
||||
if (ndx >= buffsize) {
|
||||
ndx = buffsize - 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
receivedChars[ndx] = '\0'; // terminate the string
|
||||
ndx = 0;
|
||||
new_data = true;
|
||||
}
|
||||
last_serial_string = String(receivedChars);
|
||||
|
||||
yield();
|
||||
}
|
||||
}
|
||||
|
||||
void parseData() {
|
||||
char * strtokIndx; // this is used by strtok() as an index
|
||||
strtokIndx = strtok(tempChars,"\t"); // get the first part - the label
|
||||
// The last field of a block is always the Checksum
|
||||
if (strcmp(strtokIndx, "Checksum") == 0) {
|
||||
blockend = true;
|
||||
}
|
||||
strcpy(recv_label[blockindex], strtokIndx); // copy it to label
|
||||
|
||||
// Now get the value
|
||||
strtokIndx = strtok(NULL, "\r"); // This continues where the previous call left off until '/r'.
|
||||
if (strtokIndx != NULL) { // We need to check here if we don't receive NULL.
|
||||
strcpy(recv_value[blockindex], strtokIndx);
|
||||
}
|
||||
blockindex++;
|
||||
|
||||
if (blockend) {
|
||||
// We got a whole block into the received data.
|
||||
// Check if the data received is not corrupted.
|
||||
// Sum off all received bytes should be 0;
|
||||
byte checksum = 0;
|
||||
for (int x = 0; x < blockindex; x++) {
|
||||
// Loop over the labels and value gotten and add them.
|
||||
// Using a byte so the the % 256 is integrated.
|
||||
char *v = recv_value[x];
|
||||
char *l = recv_label[x];
|
||||
while (*v) {
|
||||
checksum += *v;
|
||||
v++;
|
||||
}
|
||||
while (*l) {
|
||||
checksum+= *l;
|
||||
l++;
|
||||
}
|
||||
// Because we strip the new line(10), the carriage return(13) and
|
||||
// the horizontal tab(9) we add them here again.
|
||||
checksum += 32;
|
||||
}
|
||||
// Checksum should be 0, so if !0 we have correct data.
|
||||
if (!checksum) {
|
||||
// Since we are getting blocks that are part of a
|
||||
// keyword chain, but are not certain where it starts
|
||||
// we look for the corresponding label. This loop has a trick
|
||||
// that will start searching for the next label at the start of the last
|
||||
// hit, which should optimize it.
|
||||
int start = 0;
|
||||
for (int i = 0; i < blockindex; i++) {
|
||||
for (int j = start; (j - start) < num_keywords; j++) {
|
||||
if (strcmp(recv_label[i], keywords[j % num_keywords]) == 0) {
|
||||
// found the label, copy it to the value array
|
||||
strcpy(value[j], recv_value[i]);
|
||||
start = (j + 1) % num_keywords; // start searching the next one at this hit +1
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Reset the block index, and make sure we clear blockend.
|
||||
blockindex = 0;
|
||||
blockend = false;
|
||||
}
|
||||
}
|
||||
|
||||
void cleanValues() {
|
||||
// new_data = false;
|
||||
// strcpy("RESET", recv_value[CHECKSUM]);
|
||||
// for (int i = 0; i < num_keywords; i++){
|
||||
// strcpy("", recv_value[i]);
|
||||
// }
|
||||
}
|
||||
|
||||
void printValues() {
|
||||
for (int i = 0; i < num_keywords; i++){
|
||||
Serial.print(keywords[i]);
|
||||
Serial.print("=");
|
||||
Serial.print(value[i]);
|
||||
Serial.print("|");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
void printData() {
|
||||
static unsigned long prev_millis;
|
||||
if (millis() - prev_millis > PRINT_EVERY_SECONDS * 1000) {
|
||||
printValues();
|
||||
prev_millis = millis();
|
||||
}
|
||||
}
|
||||
|
||||
void handleNewData() {
|
||||
|
||||
// We have gotten a field of data
|
||||
if (new_data == true) {
|
||||
//Copy it to the temp array because parseData will alter it.
|
||||
strcpy(tempChars, receivedChars);
|
||||
parseData();
|
||||
new_data = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Méthode pour gérer la requête '/getData'
|
||||
void handleVictron() {
|
||||
blink();
|
||||
|
||||
#ifdef PIN_HALL
|
||||
getHall();
|
||||
#endif
|
||||
|
||||
#ifdef PIN_DALLAS
|
||||
// Command all devices on bus to read temperature
|
||||
// Serial.print("Temperature is: ");
|
||||
temperature = printTemperature(Probe);
|
||||
//Serial.println();
|
||||
#endif
|
||||
|
||||
#ifdef SERIAL_XY6020L
|
||||
printMem();
|
||||
#endif
|
||||
|
||||
#ifdef SERIAL_XY6020L_2
|
||||
printMem2();
|
||||
#endif
|
||||
|
||||
String JSON = F("[");
|
||||
for (int i = 0; i < num_keywords; i++){
|
||||
// String key = data[i].key; //String(keywords[i]);
|
||||
// String val = data[i].value; //String(value[i]);
|
||||
String key = String(keywords[i]);
|
||||
String val = String(value[i]);
|
||||
String label = "";
|
||||
String key_label = "";
|
||||
// if (key.equals("CS")) {
|
||||
// label = "Etat";
|
||||
// val = operationStates[val.toInt()].label;
|
||||
// }
|
||||
|
||||
for (int i = 0; i < mpptDataSize; i++) {
|
||||
if (key.equals(mpptData[i].code)) {
|
||||
key_label= key + " " + mpptData[i].label;
|
||||
}
|
||||
}
|
||||
if (key.equals("OR")) {
|
||||
for (int i = 0; i < offReasonsSize; i++) {
|
||||
if (val.equals(offReasons[i].code)) {
|
||||
label = offReasons[i].label;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (key.equals("CS")) {
|
||||
for (int i = 0; i < operationStatesSize; i++) {
|
||||
if (val.equals(operationStates[i].code)) {
|
||||
label = operationStates[i].label;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (key.equals("MPPT")) {
|
||||
for (int i = 0; i < mpptStatesSize; i++) {
|
||||
if (val.equals(mpptStates[i].code)) {
|
||||
label = mpptStates[i].label;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (key.equals("ERR")) {
|
||||
for (int i = 0; i < errorCodesSize; i++) {
|
||||
if (val.equals(errorCodes[i].code)) {
|
||||
label = errorCodes[i].label;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (key.equals("IL")) {
|
||||
intensite_decharge = val.toFloat() / 1000;
|
||||
}
|
||||
if (key.equals("V")) {
|
||||
tension_batterie = val.toFloat() / 1000;
|
||||
|
||||
}
|
||||
if (key.equals("Checksum")) {
|
||||
String tensions = "";
|
||||
String labels = "";
|
||||
for (int i = 0; i < maxSize; i++) {
|
||||
if (i == 0) {
|
||||
tensions = String(to_store.tensions[i]);
|
||||
labels = String(to_store.hour[i]) + ":" + String(to_store.min[i]);
|
||||
}
|
||||
else {
|
||||
tensions += "," + String(to_store.tensions[i]);
|
||||
labels += "," + String((to_store.hour[i] < 10 ? "0" : "") + String(to_store.hour[i]))
|
||||
+ ":"
|
||||
+ String((to_store.min[i] < 10 ? "0" : "") + String(to_store.min[i])) ;
|
||||
|
||||
}
|
||||
}
|
||||
JSON += "{\"id\":\"output-power\", \"value\":\"" + String(tension_batterie * intensite_decharge,1) + "\"},";
|
||||
|
||||
#ifdef TUYA
|
||||
JSON += "{\"id\":\"CONSO\", \"value\":\"" + String(String(conso_apparente).toFloat(),1) + "\"},";
|
||||
JSON += "{\"id\":\"PROD\", \"value\":\"" + String(String(production).toFloat(),1) + "\"},";
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef PIN_DALLAS
|
||||
JSON += "{\"id\":\"TEMPERATURE\", \"value\":\"" + String(temperature,1) + "\"},";
|
||||
#endif
|
||||
|
||||
#ifdef PIN_REGULATION
|
||||
JSON += "{\"id\":\"REGULATION\", \"value\":\"" + String(current_regulation) + "\"},";
|
||||
#endif
|
||||
|
||||
#ifdef PIN_DIMMER_OUTPUT
|
||||
JSON += "{\"id\":\"RADIATEUR\", \"value\":\"" + String(pwm) + "\"},";
|
||||
#endif
|
||||
#ifdef PIN_HALL
|
||||
getHall();
|
||||
JSON += "{\"id\":\"HALL_V\", \"value\":\"" + String(VRMS) + "\"},";
|
||||
JSON += "{\"id\":\"HALL_I\", \"value\":\"" + String(Amps) + "\"},";
|
||||
JSON += "{\"id\":\"HALL_W\", \"value\":\"" + String(Amps * 230) + "\"},";
|
||||
#endif
|
||||
#ifdef SERIAL_XY6020L
|
||||
if(xy.HRegUpdated()) {
|
||||
xy.ReadAllHRegs();
|
||||
}
|
||||
|
||||
JSON += "{\"id\":\"CHRG\", \"value\":\"" + String(digitalRead(PIN_CHARGE)) + "\"},";
|
||||
JSON += "{\"id\":\"XY_ON\", \"value\":\"" + String(xy.getOutputOn()) + "\"},";
|
||||
JSON += "{\"id\":\"XY_inV\", \"value\":\"" + String(xy.getInV()) + "\"},";
|
||||
JSON += "{\"id\":\"XY_V\", \"value\":\"" + String(xy.getCV()) + "\"},";
|
||||
JSON += "{\"id\":\"XY_C\", \"value\":\"" + String(xy.getCC()) + "\"},";
|
||||
JSON += "{\"id\":\"XY_T\", \"value\":\"" + String(xy.getTemp()) + "\"},";
|
||||
JSON += "{\"id\":\"XY_AV\", \"value\":\"" + String(xy.getActV()) + "\"},";
|
||||
JSON += "{\"id\":\"XY_AC\", \"value\":\"" + String(xy.getActC()) + "\"},";
|
||||
JSON += "{\"id\":\"XY_AW\", \"value\":\"" + String(xy.getActP()) + "\"},";
|
||||
JSON += "{\"id\":\"XY_CHG\", \"value\":\"" + String(xy.getCharge()) + "\"},";
|
||||
JSON += "{\"id\":\"XY_NRJ\", \"value\":\"" + String(xy.getEnergy()) + "\"},";
|
||||
#endif
|
||||
#ifdef SERIAL_XY6020L_2
|
||||
if(xy2.HRegUpdated()) {
|
||||
xy2.ReadAllHRegs();
|
||||
}
|
||||
JSON += "{\"id\":\"INJC\", \"value\":\"" + String(digitalRead(PIN_INJECTION)) + "\"},";
|
||||
|
||||
JSON += "{\"id\":\"XY2_ON\", \"value\":\"" + String(xy2.getOutputOn()) + "\"},";
|
||||
JSON += "{\"id\":\"XY2_inV\", \"value\":\"" + String(xy2.getInV()) + "\"},";
|
||||
JSON += "{\"id\":\"XY2_V\", \"value\":\"" + String(xy2.getCV()) + "\"},";
|
||||
JSON += "{\"id\":\"XY2_C\", \"value\":\"" + String(xy2.getCC()) + "\"},";
|
||||
JSON += "{\"id\":\"XY2_T\", \"value\":\"" + String(xy2.getTemp()) + "\"},";
|
||||
JSON += "{\"id\":\"XY2_AV\", \"value\":\"" + String(xy2.getActV()) + "\"},";
|
||||
JSON += "{\"id\":\"XY2_AC\", \"value\":\"" + String(xy2.getActC()) + "\"},";
|
||||
JSON += "{\"id\":\"XY2_AW\", \"value\":\"" + String(xy2.getActP()) + "\"},";
|
||||
JSON += "{\"id\":\"XY2_CHG\", \"value\":\"" + String(xy2.getCharge()) + "\"},";
|
||||
JSON += "{\"id\":\"XY2_NRJ\", \"value\":\"" + String(xy2.getEnergy()) + "\"},";
|
||||
#endif
|
||||
JSON += "{\"id\":\"MESSAGE\", \"value\":\"" + last_message + "\"},";
|
||||
|
||||
JSON += "{\"id\":\"tensions\", \"value\":\"" + tensions + "\",\"labels\":\"" + labels + "\"},";
|
||||
|
||||
// #ifndef SERIAL_BLUE_SOLAR
|
||||
// JSON += "{\"id\":\"" + key + "\",\"key_label\":\"" + key_label + "\",\"label\":\"" + label + "\", \"value\":\"" + val + "\"},";
|
||||
// #endif
|
||||
}
|
||||
else {
|
||||
// if (i == ERR) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// #ifdef SERIAL_BLUE_SOLAR
|
||||
JSON += "{\"id\":\"" + key + "\",\"key_label\":\"" + key_label + "\",\"label\":\"" + label + "\", \"value\":\"" + val + "\"},";
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
//to_store.tensions
|
||||
//JSON += "{\"id\":\"last_serial_string\", \"value\":\"" + last_serial_string + "\"},";
|
||||
|
||||
|
||||
JSON += "{\"id\":\"end\", \"value\":\"end\"}";
|
||||
JSON += "]";
|
||||
blink();
|
||||
server.send(200, "application/json", JSON);
|
||||
|
||||
// // Créer un objet JSON
|
||||
// DynamicJsonDocument doc(200);
|
||||
//
|
||||
// for (int i = 0; i < num_keywords; i++){
|
||||
// doc[String(keywords[i])] = String(value[i]);
|
||||
// }
|
||||
//
|
||||
// // Convertir l'objet jsonData en chaîne
|
||||
// String jsonData;
|
||||
// serializeJson(doc, jsonData);
|
||||
//
|
||||
// // Envoyer la réponse JSON au client
|
||||
// server.send(200, "application/json", jsonData);
|
||||
}
|
||||
|
||||
void handleDebug() {
|
||||
// Envoyer la réponse au client
|
||||
server.send(200, "text/plain", last_serial_string);
|
||||
}
|
||||
Reference in New Issue
Block a user