Moved ZPA functions to separate files
This commit is contained in:
		
							
								
								
									
										118
									
								
								ZPAElectricity.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								ZPAElectricity.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,118 @@
 | 
			
		||||
#include "ZPAElectricity.h"
 | 
			
		||||
 | 
			
		||||
// BCC is calculated as follows (source https://github.com/lvzon/dsmr-p1-parser/blob/master/doc/IEC-62056-21-notes.md):
 | 
			
		||||
// The BCC is calculated over the bytes after STX up to and including the ETX byte
 | 
			
		||||
// To calculate this BCC, take the first byte XOR 0xff
 | 
			
		||||
// XOR this value with the second byte, and so forth up to and including the last byte (include 0x03 ETX !!),
 | 
			
		||||
// and XOR the final value with 0xff.
 | 
			
		||||
 | 
			
		||||
// State flags
 | 
			
		||||
bool stateZPAreading = false;
 | 
			
		||||
uint32_t lastZPAcharRead = 0;
 | 
			
		||||
 | 
			
		||||
uint8_t localBCC;
 | 
			
		||||
String ZPAreadData = "";
 | 
			
		||||
 | 
			
		||||
bool ZPAreading() {
 | 
			
		||||
  return stateZPAreading;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ZPArequestData() {
 | 
			
		||||
  Serial2.updateBaudRate(300);
 | 
			
		||||
  Serial.println(F("Requesting data"));
 | 
			
		||||
  Serial2.print(F("/?!\r\n"));
 | 
			
		||||
 | 
			
		||||
  // Start reading, set up actual time
 | 
			
		||||
  stateZPAreading = true;
 | 
			
		||||
  lastZPAcharRead = millis();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ZPAchangeBaudrate(char baud) {
 | 
			
		||||
  int baudrate = 300;
 | 
			
		||||
 | 
			
		||||
  switch (baud) {
 | 
			
		||||
    case '1':
 | 
			
		||||
      baudrate = 300;
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case '2':
 | 
			
		||||
      baudrate = 1200;
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case '3':
 | 
			
		||||
      baudrate = 2400;
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case '4':
 | 
			
		||||
      baudrate = 4800;
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Serial.print(F("Change baudrate to "));
 | 
			
		||||
  Serial.print(baud);
 | 
			
		||||
  Serial.print(F(" ("));
 | 
			
		||||
  Serial.print(baudrate);
 | 
			
		||||
  Serial.println(F(")"));
 | 
			
		||||
 | 
			
		||||
  Serial2.write(0x06);
 | 
			
		||||
  Serial2.print(F("0"));
 | 
			
		||||
  Serial2.print(baud);
 | 
			
		||||
  Serial2.print(F("0\r\n"));
 | 
			
		||||
  Serial2.flush();
 | 
			
		||||
 | 
			
		||||
  Serial2.updateBaudRate(baudrate);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void handleZPASerial() {
 | 
			
		||||
  if (!stateZPAreading)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (Serial2.available()) {
 | 
			
		||||
    char r = Serial2.read();
 | 
			
		||||
    lastZPAcharRead = millis();
 | 
			
		||||
 | 
			
		||||
    if (r == 0x02) {
 | 
			
		||||
      Serial.println(F("<STX>"));
 | 
			
		||||
      localBCC = 0xFF;
 | 
			
		||||
      ZPAreadData = "";
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (r == 0x03) {
 | 
			
		||||
      Serial.println(F("<ETX>"));
 | 
			
		||||
      Serial.print(F("Checksum <BCC>: "));
 | 
			
		||||
      uint8_t remoteBCC = Serial2.read();
 | 
			
		||||
      Serial.print(remoteBCC, HEX);
 | 
			
		||||
      Serial.println();
 | 
			
		||||
      Serial.print(F("Calculated <BCC>: "));
 | 
			
		||||
      localBCC = localBCC ^ r;
 | 
			
		||||
      localBCC = localBCC ^ 0xFF;
 | 
			
		||||
      Serial.print(localBCC, HEX);
 | 
			
		||||
      Serial.println();
 | 
			
		||||
      Serial.println();
 | 
			
		||||
      Serial.println(F("Changing back baudrate to 300"));
 | 
			
		||||
      Serial2.updateBaudRate(300);
 | 
			
		||||
 | 
			
		||||
      stateZPAreading = false;
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Calculate BCC checksum
 | 
			
		||||
    localBCC = localBCC ^ r;
 | 
			
		||||
 | 
			
		||||
    ZPAreadData += r;
 | 
			
		||||
    Serial.write(r);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void handleZPA() {
 | 
			
		||||
  handleZPASerial();
 | 
			
		||||
 | 
			
		||||
  if (stateZPAreading && (millis() > lastZPAcharRead + ZPA_READ_TIMEOUT)) {
 | 
			
		||||
    Serial.println(F("ZPA Read TIMEOUT, stopping, setting baudrate to 300"));
 | 
			
		||||
 | 
			
		||||
    stateZPAreading = false;
 | 
			
		||||
    ZPAreadData = "";
 | 
			
		||||
    Serial2.updateBaudRate(300);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								ZPAElectricity.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								ZPAElectricity.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
#ifndef ZPAELECTRICITY_H
 | 
			
		||||
#define ZPAELECTRICITY_H
 | 
			
		||||
 | 
			
		||||
#include <Arduino.h>
 | 
			
		||||
 | 
			
		||||
#define ZPA_READ_TIMEOUT 10000 // 10 seconds timeout to read from ZPA serial line
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void ZPArequestData();
 | 
			
		||||
bool ZPAreading();
 | 
			
		||||
void ZPAchangeBaudrate(char baud);
 | 
			
		||||
void handleZPASerial();
 | 
			
		||||
void handleZPA();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -2,6 +2,8 @@
 | 
			
		||||
#include <WiFiClient.h>
 | 
			
		||||
#include <ArduinoOTA.h>
 | 
			
		||||
 | 
			
		||||
#include "ZPAElectricity.h"
 | 
			
		||||
 | 
			
		||||
const char* host = "zpaesp32";
 | 
			
		||||
const char* ssid = "...";
 | 
			
		||||
const char* password = "...";
 | 
			
		||||
@@ -77,97 +79,62 @@ void setup() {
 | 
			
		||||
  Serial.println("Ready");
 | 
			
		||||
  Serial.print("IP address: ");
 | 
			
		||||
  Serial.println(WiFi.localIP());
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BCC is calculated as follows (source https://github.com/lvzon/dsmr-p1-parser/blob/master/doc/IEC-62056-21-notes.md):
 | 
			
		||||
// The BCC is calculated over the bytes after STX up to and including the ETX byte
 | 
			
		||||
// To calculate this BCC, take the first byte XOR 0xff
 | 
			
		||||
// XOR this value with the second byte, and so forth up to and including the last byte (include 0x03 ETX !!),
 | 
			
		||||
// and XOR the final value with 0xff.
 | 
			
		||||
 | 
			
		||||
uint8_t localBCC;
 | 
			
		||||
 | 
			
		||||
void loop() {
 | 
			
		||||
 | 
			
		||||
  ArduinoOTA.handle();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  if (Serial2.available()) {
 | 
			
		||||
    char r = Serial2.read();
 | 
			
		||||
 | 
			
		||||
    if (r == 0x02) {
 | 
			
		||||
      Serial.print("<STX>");
 | 
			
		||||
      localBCC = 0xFF; // Set checksum to 0xFF (first byte is XORed with 0xFF)
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (r == 0x03) {
 | 
			
		||||
      Serial.println("<ETX>");
 | 
			
		||||
      Serial.print("Checksum <BCC>: ");
 | 
			
		||||
      Serial.print(Serial2.read());
 | 
			
		||||
      Serial.println();
 | 
			
		||||
      Serial.print("Calculated <BCC>: ");
 | 
			
		||||
      localBCC = localBCC ^ r;    // Include last byte (ETX) to checksum
 | 
			
		||||
      localBCC = localBCC ^ 0xFF; // Final value XORed with 0xFF
 | 
			
		||||
      Serial.print(localBCC);
 | 
			
		||||
      Serial.println();
 | 
			
		||||
      Serial.println();
 | 
			
		||||
      Serial.println("Changing back baudrate to 300");
 | 
			
		||||
      Serial2.updateBaudRate(300);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Calculate BCC checksum
 | 
			
		||||
    localBCC = localBCC ^ r;
 | 
			
		||||
    Serial.write(r);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void handlePCSerial() {
 | 
			
		||||
  if (Serial.available()) {
 | 
			
		||||
    char r = Serial.read();
 | 
			
		||||
 | 
			
		||||
    if (r == 'R') {
 | 
			
		||||
      Serial.println("Requesting data");
 | 
			
		||||
      Serial2.print("/?!\r\n");
 | 
			
		||||
      if (ZPAreading()) {
 | 
			
		||||
        Serial.println(F("Another reading already running"));
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      ZPArequestData();
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (r == '1') {
 | 
			
		||||
      Serial.println("Baudrate to 300");
 | 
			
		||||
      Serial.println(F("Baudrate to 300"));
 | 
			
		||||
      Serial2.updateBaudRate(300);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (r == '2') {
 | 
			
		||||
      Serial.println("Baudrate to 1200");
 | 
			
		||||
      Serial.println(F("Baudrate to 1200"));
 | 
			
		||||
      Serial2.updateBaudRate(1200);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (r == '3') {
 | 
			
		||||
      Serial.println("Baudrate to 2400");
 | 
			
		||||
      Serial.println(F("Baudrate to 2400"));
 | 
			
		||||
      Serial2.updateBaudRate(2400);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (r == '4') {
 | 
			
		||||
      Serial.println("Baudrate to 4800");
 | 
			
		||||
      Serial.println(F("Baudrate to 4800"));
 | 
			
		||||
      Serial2.updateBaudRate(4800);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (r == '5') {
 | 
			
		||||
      Serial.println("Baudrate to 9600");
 | 
			
		||||
      Serial.println(F("Baudrate to 9600"));
 | 
			
		||||
      Serial2.updateBaudRate(9600);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (r == 'C') {
 | 
			
		||||
      Serial.println("Change baudrate");
 | 
			
		||||
      Serial2.write(0x06);
 | 
			
		||||
      Serial2.print("040\r\n");
 | 
			
		||||
      Serial2.flush();
 | 
			
		||||
      Serial2.updateBaudRate(4800);
 | 
			
		||||
      ZPAchangeBaudrate('4');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Serial2.write(r);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void loop() {
 | 
			
		||||
 | 
			
		||||
  ArduinoOTA.handle();
 | 
			
		||||
 | 
			
		||||
  handleZPA();
 | 
			
		||||
 | 
			
		||||
  handlePCSerial();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user