Gniazdko Neo Coolcam z pomiarem energii

Shafter
Posty: 20
Rejestracja: sob wrz 19, 2020 10:50 am

Wiem, że powinno lecieć coś po UART, dlatego jestem tak zdziwiony.
Załączniki
IMG_3950.jpg
IMG_3950.jpg (1.81 MiB) Przejrzano 2387 razy
borbet7
Posty: 7
Rejestracja: wt wrz 15, 2020 6:14 pm

kamay pisze: pt paź 16, 2020 8:51 pm Wojtas567 ma w 100% rację
Ostatnio również walczyłem z jakimś tam klonen Neo, tak było opisane na aukcji, przyszło bez opisu.
Co prawda działało bez problemu w aplikacji Smart life, ale chciałem "poćwiczyć" SUPLĘ.
Moje ma (bo działa z SUPLĄ) następujące wyjścia:
GPIO 14 - przekaźnik
GPIO 13 - dioda
GPIO 0 - przycisk

GPIO szukałem miernikiem

Próbowałem kilku wersji firmware z tego forum, z różnym skutkiem, ostatecznie wgrałem i skonfigurowałem GUI-generic od Espablo.
Nie działa mi co prawda dioda i pomiar energii ale podstawowa funkcjonalność jest. No i wszystko mam w SUPLI, a o to mi chodziło.
Idealnie byłoby wrócić do tematu ale to pewnie zabawa z kodem, może kiedy, ktoś .....:).
Ja następnym razem, już bardziej świadomie, kupię coś co na 100% gada z SUPLĄ ->>> Zamel, Sonoff, Blitzwolf (?)
Niestety nie znalazłem żadnego softu do mojego gniazdka (Nous A1). Przepraszam za trochę lamerskie pytanie: w jaki sposób edytować ten soft (może udałoby mi się znaleźć właściwe GPIO)?
------------------------------------------------------
MEW-01 | SRW-01 x2
Awatar użytkownika
PuteR
Posty: 1421
Rejestracja: śr gru 06, 2017 10:07 am

kamay pisze: pt paź 16, 2020 8:51 pm ...
Próbowałem kilku wersji firmware z tego forum, z różnym skutkiem, ostatecznie wgrałem i skonfigurowałem GUI-generic od Espablo.
Nie działa mi co prawda dioda i pomiar energii ale podstawowa funkcjonalność jest. No i wszystko mam w SUPLI, a o to mi chodziło.
Idealnie byłoby wrócić do tematu ale to pewnie zabawa z kodem, może kiedy, ktoś .....:).
Ja następnym razem, już bardziej świadomie, kupię coś co na 100% gada z SUPLĄ ->>> Zamel, Sonoff, Blitzwolf (?)
Jest soft stworzony przez @elmaya, który bardzo dobrze sprawuje się w tym gniazdku włącznie w pomiarem energii (oczywiście w wersji 16A).
borbet7
Posty: 7
Rejestracja: wt wrz 15, 2020 6:14 pm

Cześć,

Być może to przyda się innym "walczącym" z Nous A1 poprzez tuya-convert. Tak jak pisałem w pierwszym wpisie jedynym softem, który udało mi się wgrać być ten do Neo Coolcam (Supla_neo_10A_DOUT_8Mbit), który ewidentnie nie jest właściwym. Inne jak np. Blitzwolf_BW_SHP6 nie były wykrywane przez tuya-convert. Okazało się że problem tkwi w skrypcie, który sprawdza bin-y pod kątem magic byte i uniemożliwia użycie tych bez właściwej wartości:

Kod: Zaznacz cały

MAGIC=$(printf "\xe9")

while true; do
	echo
	echo "Available options:"
	echo "  0) return to stock"
	index=0
	for file in ../files/*.bin; do
		# skip null glob
		[[ -e $file ]] || continue
		# get short name
		filename=$(basename "$file")
		# skip files too large or too small
		filesize=$(stat -Lc%s "$file")
		[[ "$filesize" -gt 0x1000 && "$filesize" -le 0x80000 ]] || continue
		[b]# skip files without magic byte[/b]
		[[ $(head -c 1 "$file") == "$MAGIC" ]] || continue
		echo "  $((++index))) flash $filename"
		options[$index]="$filename"
		# only show first 9 options, accessible with a single keypress
		if (( index == 9 )); then
			break
		fi
	done
	echo "  q) quit; do nothing"
	echo -n "Please select 0-$index: "
Z tego samego powodu nie było też możliwe wgranie innego softu poprzez OTA. Sprawdzałem w edytorze Hex i faktycznie pierwszy bajt był właściwy tylko w sofcie do Neo Coolcam. Nie czuję się na siłach aby edytować ten kod, więc odpuściłem i postanowiłem otworzyć gniazdko. I tu dwie dobre informacje:

1. gniazdko otwiera się bajecznie łatwo
2. patrząc na naklejkę z kodem "SP111-7" zakładam, że jest to idealny klon Gosund SP111, a właśnie dwa dni temu wgrałem do dwóch Gosund SP111 soft Blitzwolf BW-SHP-6 15A

BTW
W przypadku Godund SP111 nie trzeba nawet lutować ze względu na specjalne otwory w płytce. Same gniazdka można kupić w Polsce w promocji za 38zł. Polecam.
Załączniki
Nous A1
Nous A1
1604959931016 (Large).jpg (64.43 KiB) Przejrzano 2231 razy
Nous A1
Nous A1
1604959931020 (Large).jpg (196.62 KiB) Przejrzano 2231 razy
------------------------------------------------------
MEW-01 | SRW-01 x2
bigthomas
Posty: 234
Rejestracja: pn sie 12, 2019 3:35 pm

borbet7 pisze: pn lis 09, 2020 10:45 pm
Czy po wgraniu tego softu jest potem możliwość aktualizacji OTA?
Czy za każdym razem trzeba rozbierać?
elmaya
Posty: 1482
Rejestracja: śr cze 27, 2018 5:48 pm
Lokalizacja: El Saucejo - Sevilla

for Gosund SP111

Kod: Zaznacz cały

/*
Copyright (C) AC SOFTWARE SP. Z O.O.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#include "LittleFS.h" // LittleFS is declared  
#include <SuplaDevice.h>
#include <supla/sensor/one_phase_electricity_meter.h>
#include <supla/control/relay.h>
#include <WiFiManager.h>
#include <ArduinoJson.h> //--------- V6 ------
#include <EEPROM.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPUpdateServer.h>
#include <Ticker.h>      //for LED status
#include <ESP8266TrueRandom.h>
#include <HLW8012.h>
extern "C"
{
#include "user_interface.h"
} 

//#define D0 16  //no internal pullup resistor
//#define D1  5
//#define D2  4
//#define D3  0  //must not be pulled low during power on/reset, toggles value during boot
//#define D4  2  //must not be pulled low during power on/reset, toggles value during boot
//#define D5 14
//#define D6 12
//#define D7 13
//#define D8 15  //must not be pulled high during power on/reset

#define SEL_PIN    12
#define CF1_PIN    14
#define CF_PIN     5
#define status_led 0
int wificonfig_pin = 13; 
int relay_pin = 15;       
int C_W_state = HIGH; 
int last_C_W_state = HIGH;
unsigned long time_last_C_W_change = 0; 
long C_W_delay = 10000;                      // config delay 10 seconds     
int C_W_state2 = HIGH; 
long C_W_delay2 = 100;
unsigned long eep_milis = 10000;
bool recover = true;                       
char Supla_server[81]=("Set server address");
char Email[81]=("set email address");
char Supla_name[51];
char Supla_status[51];
char Volt[8];
char Wats[8];
byte mac[6];
bool shouldSaveConfig = false;
bool initialConfig = false;
int s = 0;
bool starting = true;
bool Tik = true;
unsigned long  mem_energy_milis = 3000000;
float mem_energy = 0;
float _mem_energy = 0;
int customFieldLength = 40;
WiFiManagerParameter custom_field; // global param ( for non blocking w params )
char GUID[SUPLA_GUID_SIZE];
char AUTHKEY[SUPLA_AUTHKEY_SIZE];
byte uuidNumber[16]; // UUIDs in binary form are 16 bytes long
static const char custom_radio_str[] PROGMEM = "<br><div style='text-align:center; width:100%; padding:0;'><label for='customfieldid'>Counter mem</label><input type='radio' name='customfieldid' value='0' checked>keep Storage<input type='radio' name='customfieldid' value='1'>clear Storage</div>";
ESP8266WebServer httpServer(81);
ESP8266HTTPUpdateServer httpUpdater;
WiFiManager wifiManager;
Ticker ticker;
#include <supla/network/esp_wifi.h>
Supla::ESPWifi wifi("", "");  //------ Do not change----wifimanager takes care------

Supla::Control::Relay *relay1 = nullptr;

#define CURRENT_MODE                    LOW
#define HJL01_CURRENT_RATIO             25740
#define HJL01_VOLTAGE_RATIO             313400
#define HJL01_POWER_RATIO               3414290
HLW8012 hjl01;

class Hj101 : public Supla::Sensor::OnePhaseElectricityMeter {
    public:
        Hj101()  {
        }

        void onInit() {
            readValuesFromDevice();
            updateChannelValues();
        }

        virtual void readValuesFromDevice() {

            unsigned int _reactive =  0;
            double _pf = 0;
            double _current = hjl01.getCurrent();
            unsigned int _voltage = hjl01.getVoltage();
            unsigned int _active = hjl01.getActivePower();
            unsigned int _apparent = _voltage * _current;
            if (_apparent > _active) {_reactive = sqrt(_apparent * _apparent - _active * _active); } else {_reactive =  0;}                           
            if (_active > _apparent){ _pf = 1;} if (_apparent == 0){ _pf = 0;}else{ _pf = (double) _active / _apparent;}                                    
            // voltage in 0.01 V
            setVoltage(0,_voltage * 100);
            // current in 0.001 A
            setCurrent(0, _current * 1000);
            // power in 0.00001 kW
            setPowerActive(0, _active * 100000);
            // energy in 0.00001 kWh
            setFwdActEnergy(0, ((float)hjl01.getEnergy() + mem_energy) / 6 / 6 );
            // power in 0.00001 kVA 
            setPowerApparent(0, _apparent * 100000);
            // power in 0.00001 kvar 
            setPowerReactive(0, _reactive * 100000);
            // power in 0.001
            setPowerFactor(0, _pf * 1000);
        }


};

void tick() {
  int state = digitalRead(status_led);  
  digitalWrite(status_led, !state);     
}
void ICACHE_RAM_ATTR hjl01_cf1_interrupt() {
    hjl01.cf1_interrupt();
}
void ICACHE_RAM_ATTR hjl01_cf_interrupt() {
    hjl01.cf_interrupt();
}
void calibrate_hj101() {

   int ex_volt = atoi(Volt); 
   int ex_pow = atoi(Wats);
   double ex_amps = ((float)ex_pow / (float)ex_volt);
   Serial.print("volt:"); Serial.println(ex_volt); 
   Serial.print("wats:"); Serial.println(ex_pow); 
   Serial.print("amps:"); Serial.println(ex_amps); 
   digitalWrite(relay_pin,HIGH); 
   Serial.println("Relay On:");    

    unsigned long timeout1 = millis();
    while ((millis() - timeout1) < 10000) { delay(10);}
          
    hjl01.expectedActivePower(ex_pow);
    hjl01.expectedVoltage(ex_volt);
    hjl01.expectedCurrent(ex_amps);

    unsigned long timeout2 = millis();
    while ((millis() - timeout2) < 2000) {delay(10);}
           
    double current_multi = hjl01.getCurrentMultiplier();
    double voltage_multi = hjl01.getVoltageMultiplier();
    double power_multi = hjl01.getPowerMultiplier();

    Serial.print("[HLW] New current multiplier : "); Serial.println(current_multi);
    Serial.print("[HLW] New voltage multiplier : "); Serial.println(voltage_multi);
    Serial.print("[HLW] New power multiplier   : "); Serial.println(power_multi);

    EEPROM.put(400, current_multi);
    EEPROM.put(410, voltage_multi);
    EEPROM.put(420, power_multi);
    EEPROM.write(430, 60);

  EEPROM.commit();
  yield();
}
void get_hj101_config(){
  if (EEPROM.read(430) == 60){
      Serial.println("get eep multiplier ");
       double p_m;double v_m;double c_m;
        EEPROM.get(400,c_m);
         EEPROM.get(410,v_m);
          EEPROM.get(420,p_m);
           hjl01.setCurrentMultiplier(c_m);
            hjl01.setVoltageMultiplier(v_m);
             hjl01.setPowerMultiplier(p_m);
   }
}
void saveConfigCallback () {          
  Serial.println("Should save config");
  shouldSaveConfig = true;
}
void ondemandwifiCallback () {
   ticker.attach(1.5, tick); 
   WiFiManagerParameter custom_Supla_server("server", "supla server", Supla_server, 81,"required");
   WiFiManagerParameter custom_Email("email", "Email", Email, 81,"required");
   WiFiManagerParameter custom_Supla_name("name", "Supla Device Name", Supla_name, 51,"required");
   WiFiManagerParameter custom_Supla_status("status", "Supla Last State", Supla_status, 51,"readonly");
   WiFiManagerParameter custom_Volt("Volt", "expectedVoltage", Volt, 8);
   WiFiManagerParameter custom_Wats("Wats", "expectedActivePower", Wats, 8);
   
   new (&custom_field) WiFiManagerParameter(custom_radio_str); // custom html input

   wifiManager.setBreakAfterConfig(true);
   wifiManager.setSaveConfigCallback(saveConfigCallback);
   wifiManager.setSaveParamsCallback(saveParamCallback);
  
   wifiManager.addParameter(&custom_Supla_server);
   wifiManager.addParameter(&custom_Email);
   wifiManager.addParameter(&custom_Supla_name);
   wifiManager.addParameter(&custom_Supla_status);
   wifiManager.addParameter(&custom_Volt);
   wifiManager.addParameter(&custom_Wats);
   wifiManager.addParameter(&custom_field);

   wifiManager.setCustomHeadElement("<style>html{ background-color: #01DF3A;}</style><div class='s'><svg version='1.1' id='l' x='0' y='0' viewBox='0 0 200 200' xml:space='preserve'><path d='M59.3,2.5c18.1,0.6,31.8,8,40.2,23.5c3.1,5.7,4.3,11.9,4.1,18.3c-0.1,3.6-0.7,7.1-1.9,10.6c-0.2,0.7-0.1,1.1,0.6,1.5c12.8,7.7,25.5,15.4,38.3,23c2.9,1.7,5.8,3.4,8.7,5.3c1,0.6,1.6,0.6,2.5-0.1c4.5-3.6,9.8-5.3,15.7-5.4c12.5-0.1,22.9,7.9,25.2,19c1.9,9.2-2.9,19.2-11.8,23.9c-8.4,4.5-16.9,4.5-25.5,0.2c-0.7-0.3-1-0.2-1.5,0.3c-4.8,4.9-9.7,9.8-14.5,14.6c-5.3,5.3-10.6,10.7-15.9,16c-1.8,1.8-3.6,3.7-5.4,5.4c-0.7,0.6-0.6,1,0,1.6c3.6,3.4,5.8,7.5,6.2,12.2c0.7,7.7-2.2,14-8.8,18.5c-12.3,8.6-30.3,3.5-35-10.4c-2.8-8.4,0.6-17.7,8.6-22.8c0.9-0.6,1.1-1,0.8-2c-2-6.2-4.4-12.4-6.6-18.6c-6.3-17.6-12.7-35.1-19-52.7c-0.2-0.7-0.5-1-1.4-0.9c-12.5,0.7-23.6-2.6-33-10.4c-8-6.6-12.9-15-14.2-25c-1.5-11.5,1.7-21.9,9.6-30.7C32.5,8.9,42.2,4.2,53.7,2.7c0.7-0.1,1.5-0.2,2.2-0.2C57,2.4,58.2,2.5,59.3,2.5z M76.5,81c0,0.1,0.1,0.3,0.1,0.6c1.6,6.3,3.2,12.6,4.7,18.9c4.5,17.7,8.9,35.5,13.3,53.2c0.2,0.9,0.6,1.1,1.6,0.9c5.4-1.2,10.7-0.8,15.7,1.6c0.8,0.4,1.2,0.3,1.7-0.4c11.2-12.9,22.5-25.7,33.4-38.7c0.5-0.6,0.4-1,0-1.6c-5.6-7.9-6.1-16.1-1.3-24.5c0.5-0.8,0.3-1.1-0.5-1.6c-9.1-4.7-18.1-9.3-27.2-14c-6.8-3.5-13.5-7-20.3-10.5c-0.7-0.4-1.1-0.3-1.6,0.4c-1.3,1.8-2.7,3.5-4.3,5.1c-4.2,4.2-9.1,7.4-14.7,9.7C76.9,80.3,76.4,80.3,76.5,81z M89,42.6c0.1-2.5-0.4-5.4-1.5-8.1C83,23.1,74.2,16.9,61.7,15.8c-10-0.9-18.6,2.4-25.3,9.7c-8.4,9-9.3,22.4-2.2,32.4c6.8,9.6,19.1,14.2,31.4,11.9C79.2,67.1,89,55.9,89,42.6z M102.1,188.6c0.6,0.1,1.5-0.1,2.4-0.2c9.5-1.4,15.3-10.9,11.6-19.2c-2.6-5.9-9.4-9.6-16.8-8.6c-8.3,1.2-14.1,8.9-12.4,16.6C88.2,183.9,94.4,188.6,102.1,188.6z M167.7,88.5c-1,0-2.1,0.1-3.1,0.3c-9,1.7-14.2,10.6-10.8,18.6c2.9,6.8,11.4,10.3,19,7.8c7.1-2.3,11.1-9.1,9.6-15.9C180.9,93,174.8,88.5,167.7,88.5z'/></svg>");
   wifiManager.setMinimumSignalQuality(8);
   //wifiManager.setShowStaticFields(true); // force show static ip fields
   //wifiManager.setShowDnsFields(true);    // force show dns field always
   wifiManager.setConfigPortalTimeout(180);

   if (!wifiManager.startConfigPortal("Gosund_SP111")) { Serial.println("Not connected to WiFi but continuing anyway.");} else { Serial.println("connected...yeey :)");}                
    strcpy(Supla_server, custom_Supla_server.getValue());
    strcpy(Email, custom_Email.getValue());
    strcpy(Supla_name, custom_Supla_name.getValue()); 
    strcpy(Volt, custom_Volt.getValue());
    strcpy(Wats, custom_Wats.getValue());
    if(strcmp(Supla_server, "get_new_guid_and_authkey") == 0){
      Serial.println("new guid & authkey.");
      EEPROM.write(300, 0);
      EEPROM.commit();
      ESP.reset(); 
    }
    if ((strlen(Volt) != 0) && (strlen(Wats) != 0)){
      calibrate_hj101();
    }
    WiFi.softAPdisconnect(true);   //  close AP
}
void status_func(int status, const char *msg) {    //    ------------------------ Status --------------------------

  if (s != status){
    s = status; 
      if (s != 10){
        strcpy(Supla_status, msg);
          Serial.print("Status: ");Serial.print(s);Serial.print(" ");Serial.println(Supla_status);
  }  }            
}
String getParam(String name){
  String value;
  if(wifiManager.server->hasArg(name)) {
    value = wifiManager.server->arg(name);
      if (value == "1"){
        float cler = 0.0; 
         EEPROM.put(460, cler);
          EEPROM.commit();
           Serial.println("clearStorage");
         }
  }
  return value;
}
void saveParamCallback(){
  Serial.println("[CALLBACK] saveParamCallback fired");
  Serial.println("PARAM customfieldid = " + getParam("customfieldid"));
}

void Eeprom_save(){
  if (digitalRead(relay_pin)!= EEPROM.read(431)){
    _mem_energy = (double)hjl01.getEnergy() + mem_energy;
    EEPROM.put(460, _mem_energy);
    EEPROM.write(431,digitalRead(relay_pin));
    EEPROM.commit();
    Serial.println("mem relay + energy");
  }
}
void guid_authkey(void) {
  if (EEPROM.read(300) != 60){
    int eep_gui = 301;

    ESP8266TrueRandom.uuid(uuidNumber);

    String uuidString = "";
    for (int i = 0; i < 16; i++) {
      int topDigit = uuidNumber[i] >> 4;
      int bottomDigit = uuidNumber[i] & 0x0f;
      uuidString += "0123456789abcdef"[topDigit];
      uuidString += "0123456789abcdef"[bottomDigit];
    }
    int length_uuid = uuidString.length();
    for (int i = 0; i < length_uuid; ++i) {
      EEPROM.put(eep_gui + i, uuidString[i]);
    }

    int eep_aut = 341;

    ESP8266TrueRandom.uuid(uuidNumber);

    String uuidString2 = "";
    for (int i = 0; i < 16; i++) {
      int topDigit = uuidNumber[i] >> 4;
      int bottomDigit = uuidNumber[i] & 0x0f;
      uuidString2 += "0123456789abcdef"[topDigit];
      uuidString2 += "0123456789abcdef"[bottomDigit];
    }
    int length_uuid2 = uuidString2.length();
    for (int i = 0; i < length_uuid2; ++i) {
      EEPROM.put(eep_aut + i, uuidString2[i]);
    }
    float cler = 0.0;
    EEPROM.put(460, cler);
    EEPROM.write(300, 60);
    EEPROM.commit();
  }
  read_guid();
  read_authkey();
  Serial.print("GUID : ");Serial.println(read_guid()); 
  Serial.print("AUTHKEY : ");Serial.println(read_authkey()); 
}

String read_guid(void) {
  String read_eeprom = "";
  int i, ii = 0;
  int eep_star = 301;
  int end_guid = eep_star + SUPLA_GUID_SIZE;
  String temp_read = "0x";
  for (i = eep_star; i < end_guid + 16;  i = i + 1) {
    temp_read += char(EEPROM.read(i));
    read_eeprom += char(EEPROM.read(i));
    if ( (i % 2) == 0) {
      char *_guid = strcpy((char*)malloc(temp_read.length() + 1), temp_read.c_str());
      GUID[ii] = strtoul( _guid, NULL, 16);
      temp_read = "0x";
      ii++;
    }
  }
  return read_eeprom;
}
String read_authkey(void) {
  String read_eeprom = "";
  int i, ii = 0;
  int eep_star = 341;
  int end_authkey = eep_star + SUPLA_AUTHKEY_SIZE;
  String temp_read = "0x";
  for (i = eep_star; i < end_authkey + 16;  i = i + 1) {
    temp_read += char(EEPROM.read(i));
    read_eeprom += char(EEPROM.read(i));
    if ( (i % 2) == 0) {
      char *_authkey = strcpy((char*)malloc(temp_read.length() + 1), temp_read.c_str());
      AUTHKEY[ii] = strtoul( _authkey, NULL, 16);
      temp_read = "0x";
      ii++;
    }
  }
  return read_eeprom;
}
void setup() {
  wifi_set_sleep_type(NONE_SLEEP_T);
  Serial.begin(115200);
  Serial.println();
  EEPROM.begin(1024);
  pinMode(wificonfig_pin, INPUT_PULLUP); 
  pinMode(status_led,OUTPUT); 
  digitalWrite(relay_pin, EEPROM.read(431));
  guid_authkey();
  ticker.attach(0.5, tick);
  
  if (WiFi.SSID()==""){ initialConfig = true;} 

  if (LittleFS.begin()) {  // ------------------------- wificonfig read -----------------
    Serial.println("mounted file system");
    if (LittleFS.exists("/config.json")) {
      Serial.println("reading config file");
       File configFile = LittleFS.open("/config.json", "r");
      if (configFile) {
        Serial.println("opened config file");
         size_t size = configFile.size();
         std::unique_ptr<char[]> buf(new char[size]);
         configFile.readBytes(buf.get(), size);
        DynamicJsonDocument json(1024);
        DeserializationError deserializeError = deserializeJson(json, buf.get());
        serializeJsonPretty(json, Serial);
        if (!deserializeError) {Serial.println("\nparsed json");         
          if (json.containsKey("Supla_server")) strcpy(Supla_server, json["Supla_server"]);
          if (json.containsKey("Email")) strcpy(Email, json["Email"]);
          if (json.containsKey("Supla_name")) strcpy(Supla_name, json["Supla_name"]);       
        } else {
          Serial.println("failed to load json config");
           initialConfig = true;
        }
        configFile.close(); 
      }
    }
   } else {
    Serial.println("failed to mount FS");
  } 
   wifi_station_set_hostname(Supla_name);
  
     hjl01.setCurrentMultiplier(HJL01_CURRENT_RATIO);
     hjl01.setVoltageMultiplier(HJL01_VOLTAGE_RATIO);
     hjl01.setPowerMultiplier(HJL01_POWER_RATIO);
    // void begin(unsigned char cf_pin, unsigned char cf1_pin, unsigned char sel_pin, unsigned char currentWhen = HIGH, bool use_interrupts = false, unsigned long pulse_timeout = PULSE_TIMEOUT);
    hjl01.begin(CF_PIN, CF1_PIN, SEL_PIN, CURRENT_MODE, true);
    get_hj101_config();
     
    attachInterrupt(CF1_PIN, hjl01_cf1_interrupt, FALLING);
    attachInterrupt(CF_PIN, hjl01_cf_interrupt, FALLING);
    EEPROM.get(460, mem_energy);
    _mem_energy = mem_energy;
    Serial.print("mem energy: ");
    Serial.println(mem_energy);

    relay1 = new Supla::Control::Relay(relay_pin);
    new Hj101(); 
            
    SuplaDevice.setName(Supla_name);
    SuplaDevice.setStatusFuncImpl(&status_func);
    wifi.enableSSL(false);  
    SuplaDevice.begin(GUID,Supla_server,Email,AUTHKEY);
                      
}
char buffer[50];
void loop() {
  
  if (initialConfig == true){ondemandwifiCallback();EEPROM.write(431, 0); EEPROM.commit();}

   int C_W_read = digitalRead(wificonfig_pin);{  
   if (C_W_read != last_C_W_state) {            
     time_last_C_W_change = millis();
   }
   if ((millis() - time_last_C_W_change) > C_W_delay2) {     
     if (C_W_read != C_W_state2) {     
       C_W_state2 = C_W_read; 
       if (C_W_state2 == LOW) { 
        Serial.println("short press");     
         if (!relay1->isOn()) {
          relay1->turnOn();
          yield();
          Serial.println("relayOn");
          Eeprom_save() ;
       }else{
         relay1->turnOff();
         yield();
         Serial.println("relayOff");
         Eeprom_save() ;
     }}}       
    }
   if ((millis() - time_last_C_W_change) > C_W_delay) {     
     if (C_W_read != C_W_state) {     
       Serial.println("long press");
       C_W_state = C_W_read;       
       if (C_W_state == LOW) {
        ondemandwifiCallback () ;
       }
     }
    }
   last_C_W_state = C_W_read;            
 }
  
  if (shouldSaveConfig == true) { // ------------------------ wificonfig save --------------
    Serial.println(" config...");  
    DynamicJsonDocument json(1024);
    json["Supla_server"] = Supla_server;
    json["Email"] = Email;
    json["Supla_name"] = Supla_name;
    File configFile = LittleFS.open("/config.json", "w");
    if (!configFile) {
      Serial.println("failed to open config file for writing");
    }
        serializeJsonPretty(json, Serial);
        serializeJson(json, configFile);
    configFile.close();
    Serial.println("Config written successfully");
    shouldSaveConfig = false;
    initialConfig = false; 
    WiFi.mode(WIFI_STA);   
    delay(5000);
    ESP.restart();     
  }
  
  if (s == 17){
    if ((Tik == true) && (WiFi.status() == WL_CONNECTED)){ticker.detach();Tik = false;}
    if(millis() > eep_milis){
     Eeprom_save() ;
     eep_milis = millis() + 3000 ; 
    }
    if (recover){
     Serial.println("ticker off");
      if (EEPROM.read(431) == true){
       relay1->turnOn();
        yield();
         Serial.println("relayOn");
          eep_milis = millis() + 3000 ;
       }
       recover = false; 
      }
    }
  if ((s != 17) && (Tik == false)) { ticker.attach(0.5, tick);Tik = true;Serial.println("ticker on  no 17"); }    
  //if ((WiFi.status() != WL_CONNECTED) && (Tik == false)){ticker.attach(0.5, tick);Tik = true;Serial.println("ticker on no wifi"); }         
  if (s == 10){recover = true;} 
     
   SuplaDevice.iterate();
   delay(50);
   
   if (WiFi.status() == WL_CONNECTED){
    if (starting){
      httpUpdater.setup(&httpServer, "/update", "admin", "pass");
      httpServer.begin(); 
      starting = false;         
     }
    httpServer.handleClient();
    if ((digitalRead(relay_pin) == digitalRead(status_led)) && (s ==17)){
    digitalWrite(status_led,!digitalRead(relay_pin));
   }
   }

   if(millis() > mem_energy_milis){
    if ((float(hjl01.getEnergy()) + mem_energy > _mem_energy) && (digitalRead(relay_pin) == HIGH)){
     Serial.println("save energy");
      _mem_energy = (float)hjl01.getEnergy() + mem_energy;
      EEPROM.put(460, _mem_energy);
      EEPROM.commit();
     mem_energy_milis = millis() + 600000 ;  
    }
   }

}
To access the Wi-Fi configuration, press button for at least 10 seconds, Led winks in wificonfig.
in the configuration page enter the data for "suplaServer, Email and Supla Device Name (name with which it will be seen in the cloud and DHCP)"

expectedVoltage = for calibration.

expectedActivePower = for calibration.

clear Storage = reset counter.

calibration process:
connect a resistive load with a known consumption, for example a 60W bulb.
access wificonfig (button pressed 10 seconds)
in the "expectedVoltage" field set the voltage of your line for example 227.
in the "expectedActivePower" field, set the consumption of the connected load, for example 60.
press save.
The procedure takes about 15 seconds, then the device restarts and the readings will be correct.
the calibration is only executed if there are data in both fields "expectedVoltage" and "expectedActivePower"
This allows for example to change the Wi-Fi network without recalibrating.
Gosund_SP111_DOUT_8Mbit.rar
compiled firmware
(379.57 KiB) Pobrany 172 razy
borbet7
Posty: 7
Rejestracja: wt wrz 15, 2020 6:14 pm

bigthomas pisze: wt lis 10, 2020 8:23 am
borbet7 pisze: pn lis 09, 2020 10:45 pm
Czy po wgraniu tego softu jest potem możliwość aktualizacji OTA?
Czy za każdym razem trzeba rozbierać?
Nie, nie widzę takiej opcji.
------------------------------------------------------
MEW-01 | SRW-01 x2
borbet7
Posty: 7
Rejestracja: wt wrz 15, 2020 6:14 pm

elmaya pisze: wt lis 10, 2020 3:24 pm for Gosund SP111

Kod: Zaznacz cały

/*
Copyright (C) AC SOFTWARE SP. Z O.O.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#include "LittleFS.h" // LittleFS is declared  
#include <SuplaDevice.h>
#include <supla/sensor/one_phase_electricity_meter.h>
#include <supla/control/relay.h>
#include <WiFiManager.h>
#include <ArduinoJson.h> //--------- V6 ------
#include <EEPROM.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPUpdateServer.h>
#include <Ticker.h>      //for LED status
#include <ESP8266TrueRandom.h>
#include <HLW8012.h>
extern "C"
{
#include "user_interface.h"
} 

//#define D0 16  //no internal pullup resistor
//#define D1  5
//#define D2  4
//#define D3  0  //must not be pulled low during power on/reset, toggles value during boot
//#define D4  2  //must not be pulled low during power on/reset, toggles value during boot
//#define D5 14
//#define D6 12
//#define D7 13
//#define D8 15  //must not be pulled high during power on/reset

#define SEL_PIN    12
#define CF1_PIN    14
#define CF_PIN     5
#define status_led 0
int wificonfig_pin = 13; 
int relay_pin = 15;       
int C_W_state = HIGH; 
int last_C_W_state = HIGH;
unsigned long time_last_C_W_change = 0; 
long C_W_delay = 10000;                      // config delay 10 seconds     
int C_W_state2 = HIGH; 
long C_W_delay2 = 100;
unsigned long eep_milis = 10000;
bool recover = true;                       
char Supla_server[81]=("Set server address");
char Email[81]=("set email address");
char Supla_name[51];
char Supla_status[51];
char Volt[8];
char Wats[8];
byte mac[6];
bool shouldSaveConfig = false;
bool initialConfig = false;
int s = 0;
bool starting = true;
bool Tik = true;
unsigned long  mem_energy_milis = 3000000;
float mem_energy = 0;
float _mem_energy = 0;
int customFieldLength = 40;
WiFiManagerParameter custom_field; // global param ( for non blocking w params )
char GUID[SUPLA_GUID_SIZE];
char AUTHKEY[SUPLA_AUTHKEY_SIZE];
byte uuidNumber[16]; // UUIDs in binary form are 16 bytes long
static const char custom_radio_str[] PROGMEM = "<br><div style='text-align:center; width:100%; padding:0;'><label for='customfieldid'>Counter mem</label><input type='radio' name='customfieldid' value='0' checked>keep Storage<input type='radio' name='customfieldid' value='1'>clear Storage</div>";
ESP8266WebServer httpServer(81);
ESP8266HTTPUpdateServer httpUpdater;
WiFiManager wifiManager;
Ticker ticker;
#include <supla/network/esp_wifi.h>
Supla::ESPWifi wifi("", "");  //------ Do not change----wifimanager takes care------

Supla::Control::Relay *relay1 = nullptr;

#define CURRENT_MODE                    LOW
#define HJL01_CURRENT_RATIO             25740
#define HJL01_VOLTAGE_RATIO             313400
#define HJL01_POWER_RATIO               3414290
HLW8012 hjl01;

class Hj101 : public Supla::Sensor::OnePhaseElectricityMeter {
    public:
        Hj101()  {
        }

        void onInit() {
            readValuesFromDevice();
            updateChannelValues();
        }

        virtual void readValuesFromDevice() {

            unsigned int _reactive =  0;
            double _pf = 0;
            double _current = hjl01.getCurrent();
            unsigned int _voltage = hjl01.getVoltage();
            unsigned int _active = hjl01.getActivePower();
            unsigned int _apparent = _voltage * _current;
            if (_apparent > _active) {_reactive = sqrt(_apparent * _apparent - _active * _active); } else {_reactive =  0;}                           
            if (_active > _apparent){ _pf = 1;} if (_apparent == 0){ _pf = 0;}else{ _pf = (double) _active / _apparent;}                                    
            // voltage in 0.01 V
            setVoltage(0,_voltage * 100);
            // current in 0.001 A
            setCurrent(0, _current * 1000);
            // power in 0.00001 kW
            setPowerActive(0, _active * 100000);
            // energy in 0.00001 kWh
            setFwdActEnergy(0, ((float)hjl01.getEnergy() + mem_energy) / 6 / 6 );
            // power in 0.00001 kVA 
            setPowerApparent(0, _apparent * 100000);
            // power in 0.00001 kvar 
            setPowerReactive(0, _reactive * 100000);
            // power in 0.001
            setPowerFactor(0, _pf * 1000);
        }


};

void tick() {
  int state = digitalRead(status_led);  
  digitalWrite(status_led, !state);     
}
void ICACHE_RAM_ATTR hjl01_cf1_interrupt() {
    hjl01.cf1_interrupt();
}
void ICACHE_RAM_ATTR hjl01_cf_interrupt() {
    hjl01.cf_interrupt();
}
void calibrate_hj101() {

   int ex_volt = atoi(Volt); 
   int ex_pow = atoi(Wats);
   double ex_amps = ((float)ex_pow / (float)ex_volt);
   Serial.print("volt:"); Serial.println(ex_volt); 
   Serial.print("wats:"); Serial.println(ex_pow); 
   Serial.print("amps:"); Serial.println(ex_amps); 
   digitalWrite(relay_pin,HIGH); 
   Serial.println("Relay On:");    

    unsigned long timeout1 = millis();
    while ((millis() - timeout1) < 10000) { delay(10);}
          
    hjl01.expectedActivePower(ex_pow);
    hjl01.expectedVoltage(ex_volt);
    hjl01.expectedCurrent(ex_amps);

    unsigned long timeout2 = millis();
    while ((millis() - timeout2) < 2000) {delay(10);}
           
    double current_multi = hjl01.getCurrentMultiplier();
    double voltage_multi = hjl01.getVoltageMultiplier();
    double power_multi = hjl01.getPowerMultiplier();

    Serial.print("[HLW] New current multiplier : "); Serial.println(current_multi);
    Serial.print("[HLW] New voltage multiplier : "); Serial.println(voltage_multi);
    Serial.print("[HLW] New power multiplier   : "); Serial.println(power_multi);

    EEPROM.put(400, current_multi);
    EEPROM.put(410, voltage_multi);
    EEPROM.put(420, power_multi);
    EEPROM.write(430, 60);

  EEPROM.commit();
  yield();
}
void get_hj101_config(){
  if (EEPROM.read(430) == 60){
      Serial.println("get eep multiplier ");
       double p_m;double v_m;double c_m;
        EEPROM.get(400,c_m);
         EEPROM.get(410,v_m);
          EEPROM.get(420,p_m);
           hjl01.setCurrentMultiplier(c_m);
            hjl01.setVoltageMultiplier(v_m);
             hjl01.setPowerMultiplier(p_m);
   }
}
void saveConfigCallback () {          
  Serial.println("Should save config");
  shouldSaveConfig = true;
}
void ondemandwifiCallback () {
   ticker.attach(1.5, tick); 
   WiFiManagerParameter custom_Supla_server("server", "supla server", Supla_server, 81,"required");
   WiFiManagerParameter custom_Email("email", "Email", Email, 81,"required");
   WiFiManagerParameter custom_Supla_name("name", "Supla Device Name", Supla_name, 51,"required");
   WiFiManagerParameter custom_Supla_status("status", "Supla Last State", Supla_status, 51,"readonly");
   WiFiManagerParameter custom_Volt("Volt", "expectedVoltage", Volt, 8);
   WiFiManagerParameter custom_Wats("Wats", "expectedActivePower", Wats, 8);
   
   new (&custom_field) WiFiManagerParameter(custom_radio_str); // custom html input

   wifiManager.setBreakAfterConfig(true);
   wifiManager.setSaveConfigCallback(saveConfigCallback);
   wifiManager.setSaveParamsCallback(saveParamCallback);
  
   wifiManager.addParameter(&custom_Supla_server);
   wifiManager.addParameter(&custom_Email);
   wifiManager.addParameter(&custom_Supla_name);
   wifiManager.addParameter(&custom_Supla_status);
   wifiManager.addParameter(&custom_Volt);
   wifiManager.addParameter(&custom_Wats);
   wifiManager.addParameter(&custom_field);

   wifiManager.setCustomHeadElement("<style>html{ background-color: #01DF3A;}</style><div class='s'><svg version='1.1' id='l' x='0' y='0' viewBox='0 0 200 200' xml:space='preserve'><path d='M59.3,2.5c18.1,0.6,31.8,8,40.2,23.5c3.1,5.7,4.3,11.9,4.1,18.3c-0.1,3.6-0.7,7.1-1.9,10.6c-0.2,0.7-0.1,1.1,0.6,1.5c12.8,7.7,25.5,15.4,38.3,23c2.9,1.7,5.8,3.4,8.7,5.3c1,0.6,1.6,0.6,2.5-0.1c4.5-3.6,9.8-5.3,15.7-5.4c12.5-0.1,22.9,7.9,25.2,19c1.9,9.2-2.9,19.2-11.8,23.9c-8.4,4.5-16.9,4.5-25.5,0.2c-0.7-0.3-1-0.2-1.5,0.3c-4.8,4.9-9.7,9.8-14.5,14.6c-5.3,5.3-10.6,10.7-15.9,16c-1.8,1.8-3.6,3.7-5.4,5.4c-0.7,0.6-0.6,1,0,1.6c3.6,3.4,5.8,7.5,6.2,12.2c0.7,7.7-2.2,14-8.8,18.5c-12.3,8.6-30.3,3.5-35-10.4c-2.8-8.4,0.6-17.7,8.6-22.8c0.9-0.6,1.1-1,0.8-2c-2-6.2-4.4-12.4-6.6-18.6c-6.3-17.6-12.7-35.1-19-52.7c-0.2-0.7-0.5-1-1.4-0.9c-12.5,0.7-23.6-2.6-33-10.4c-8-6.6-12.9-15-14.2-25c-1.5-11.5,1.7-21.9,9.6-30.7C32.5,8.9,42.2,4.2,53.7,2.7c0.7-0.1,1.5-0.2,2.2-0.2C57,2.4,58.2,2.5,59.3,2.5z M76.5,81c0,0.1,0.1,0.3,0.1,0.6c1.6,6.3,3.2,12.6,4.7,18.9c4.5,17.7,8.9,35.5,13.3,53.2c0.2,0.9,0.6,1.1,1.6,0.9c5.4-1.2,10.7-0.8,15.7,1.6c0.8,0.4,1.2,0.3,1.7-0.4c11.2-12.9,22.5-25.7,33.4-38.7c0.5-0.6,0.4-1,0-1.6c-5.6-7.9-6.1-16.1-1.3-24.5c0.5-0.8,0.3-1.1-0.5-1.6c-9.1-4.7-18.1-9.3-27.2-14c-6.8-3.5-13.5-7-20.3-10.5c-0.7-0.4-1.1-0.3-1.6,0.4c-1.3,1.8-2.7,3.5-4.3,5.1c-4.2,4.2-9.1,7.4-14.7,9.7C76.9,80.3,76.4,80.3,76.5,81z M89,42.6c0.1-2.5-0.4-5.4-1.5-8.1C83,23.1,74.2,16.9,61.7,15.8c-10-0.9-18.6,2.4-25.3,9.7c-8.4,9-9.3,22.4-2.2,32.4c6.8,9.6,19.1,14.2,31.4,11.9C79.2,67.1,89,55.9,89,42.6z M102.1,188.6c0.6,0.1,1.5-0.1,2.4-0.2c9.5-1.4,15.3-10.9,11.6-19.2c-2.6-5.9-9.4-9.6-16.8-8.6c-8.3,1.2-14.1,8.9-12.4,16.6C88.2,183.9,94.4,188.6,102.1,188.6z M167.7,88.5c-1,0-2.1,0.1-3.1,0.3c-9,1.7-14.2,10.6-10.8,18.6c2.9,6.8,11.4,10.3,19,7.8c7.1-2.3,11.1-9.1,9.6-15.9C180.9,93,174.8,88.5,167.7,88.5z'/></svg>");
   wifiManager.setMinimumSignalQuality(8);
   //wifiManager.setShowStaticFields(true); // force show static ip fields
   //wifiManager.setShowDnsFields(true);    // force show dns field always
   wifiManager.setConfigPortalTimeout(180);

   if (!wifiManager.startConfigPortal("Gosund_SP111")) { Serial.println("Not connected to WiFi but continuing anyway.");} else { Serial.println("connected...yeey :)");}                
    strcpy(Supla_server, custom_Supla_server.getValue());
    strcpy(Email, custom_Email.getValue());
    strcpy(Supla_name, custom_Supla_name.getValue()); 
    strcpy(Volt, custom_Volt.getValue());
    strcpy(Wats, custom_Wats.getValue());
    if(strcmp(Supla_server, "get_new_guid_and_authkey") == 0){
      Serial.println("new guid & authkey.");
      EEPROM.write(300, 0);
      EEPROM.commit();
      ESP.reset(); 
    }
    if ((strlen(Volt) != 0) && (strlen(Wats) != 0)){
      calibrate_hj101();
    }
    WiFi.softAPdisconnect(true);   //  close AP
}
void status_func(int status, const char *msg) {    //    ------------------------ Status --------------------------

  if (s != status){
    s = status; 
      if (s != 10){
        strcpy(Supla_status, msg);
          Serial.print("Status: ");Serial.print(s);Serial.print(" ");Serial.println(Supla_status);
  }  }            
}
String getParam(String name){
  String value;
  if(wifiManager.server->hasArg(name)) {
    value = wifiManager.server->arg(name);
      if (value == "1"){
        float cler = 0.0; 
         EEPROM.put(460, cler);
          EEPROM.commit();
           Serial.println("clearStorage");
         }
  }
  return value;
}
void saveParamCallback(){
  Serial.println("[CALLBACK] saveParamCallback fired");
  Serial.println("PARAM customfieldid = " + getParam("customfieldid"));
}

void Eeprom_save(){
  if (digitalRead(relay_pin)!= EEPROM.read(431)){
    _mem_energy = (double)hjl01.getEnergy() + mem_energy;
    EEPROM.put(460, _mem_energy);
    EEPROM.write(431,digitalRead(relay_pin));
    EEPROM.commit();
    Serial.println("mem relay + energy");
  }
}
void guid_authkey(void) {
  if (EEPROM.read(300) != 60){
    int eep_gui = 301;

    ESP8266TrueRandom.uuid(uuidNumber);

    String uuidString = "";
    for (int i = 0; i < 16; i++) {
      int topDigit = uuidNumber[i] >> 4;
      int bottomDigit = uuidNumber[i] & 0x0f;
      uuidString += "0123456789abcdef"[topDigit];
      uuidString += "0123456789abcdef"[bottomDigit];
    }
    int length_uuid = uuidString.length();
    for (int i = 0; i < length_uuid; ++i) {
      EEPROM.put(eep_gui + i, uuidString[i]);
    }

    int eep_aut = 341;

    ESP8266TrueRandom.uuid(uuidNumber);

    String uuidString2 = "";
    for (int i = 0; i < 16; i++) {
      int topDigit = uuidNumber[i] >> 4;
      int bottomDigit = uuidNumber[i] & 0x0f;
      uuidString2 += "0123456789abcdef"[topDigit];
      uuidString2 += "0123456789abcdef"[bottomDigit];
    }
    int length_uuid2 = uuidString2.length();
    for (int i = 0; i < length_uuid2; ++i) {
      EEPROM.put(eep_aut + i, uuidString2[i]);
    }
    float cler = 0.0;
    EEPROM.put(460, cler);
    EEPROM.write(300, 60);
    EEPROM.commit();
  }
  read_guid();
  read_authkey();
  Serial.print("GUID : ");Serial.println(read_guid()); 
  Serial.print("AUTHKEY : ");Serial.println(read_authkey()); 
}

String read_guid(void) {
  String read_eeprom = "";
  int i, ii = 0;
  int eep_star = 301;
  int end_guid = eep_star + SUPLA_GUID_SIZE;
  String temp_read = "0x";
  for (i = eep_star; i < end_guid + 16;  i = i + 1) {
    temp_read += char(EEPROM.read(i));
    read_eeprom += char(EEPROM.read(i));
    if ( (i % 2) == 0) {
      char *_guid = strcpy((char*)malloc(temp_read.length() + 1), temp_read.c_str());
      GUID[ii] = strtoul( _guid, NULL, 16);
      temp_read = "0x";
      ii++;
    }
  }
  return read_eeprom;
}
String read_authkey(void) {
  String read_eeprom = "";
  int i, ii = 0;
  int eep_star = 341;
  int end_authkey = eep_star + SUPLA_AUTHKEY_SIZE;
  String temp_read = "0x";
  for (i = eep_star; i < end_authkey + 16;  i = i + 1) {
    temp_read += char(EEPROM.read(i));
    read_eeprom += char(EEPROM.read(i));
    if ( (i % 2) == 0) {
      char *_authkey = strcpy((char*)malloc(temp_read.length() + 1), temp_read.c_str());
      AUTHKEY[ii] = strtoul( _authkey, NULL, 16);
      temp_read = "0x";
      ii++;
    }
  }
  return read_eeprom;
}
void setup() {
  wifi_set_sleep_type(NONE_SLEEP_T);
  Serial.begin(115200);
  Serial.println();
  EEPROM.begin(1024);
  pinMode(wificonfig_pin, INPUT_PULLUP); 
  pinMode(status_led,OUTPUT); 
  digitalWrite(relay_pin, EEPROM.read(431));
  guid_authkey();
  ticker.attach(0.5, tick);
  
  if (WiFi.SSID()==""){ initialConfig = true;} 

  if (LittleFS.begin()) {  // ------------------------- wificonfig read -----------------
    Serial.println("mounted file system");
    if (LittleFS.exists("/config.json")) {
      Serial.println("reading config file");
       File configFile = LittleFS.open("/config.json", "r");
      if (configFile) {
        Serial.println("opened config file");
         size_t size = configFile.size();
         std::unique_ptr<char[]> buf(new char[size]);
         configFile.readBytes(buf.get(), size);
        DynamicJsonDocument json(1024);
        DeserializationError deserializeError = deserializeJson(json, buf.get());
        serializeJsonPretty(json, Serial);
        if (!deserializeError) {Serial.println("\nparsed json");         
          if (json.containsKey("Supla_server")) strcpy(Supla_server, json["Supla_server"]);
          if (json.containsKey("Email")) strcpy(Email, json["Email"]);
          if (json.containsKey("Supla_name")) strcpy(Supla_name, json["Supla_name"]);       
        } else {
          Serial.println("failed to load json config");
           initialConfig = true;
        }
        configFile.close(); 
      }
    }
   } else {
    Serial.println("failed to mount FS");
  } 
   wifi_station_set_hostname(Supla_name);
  
     hjl01.setCurrentMultiplier(HJL01_CURRENT_RATIO);
     hjl01.setVoltageMultiplier(HJL01_VOLTAGE_RATIO);
     hjl01.setPowerMultiplier(HJL01_POWER_RATIO);
    // void begin(unsigned char cf_pin, unsigned char cf1_pin, unsigned char sel_pin, unsigned char currentWhen = HIGH, bool use_interrupts = false, unsigned long pulse_timeout = PULSE_TIMEOUT);
    hjl01.begin(CF_PIN, CF1_PIN, SEL_PIN, CURRENT_MODE, true);
    get_hj101_config();
     
    attachInterrupt(CF1_PIN, hjl01_cf1_interrupt, FALLING);
    attachInterrupt(CF_PIN, hjl01_cf_interrupt, FALLING);
    EEPROM.get(460, mem_energy);
    _mem_energy = mem_energy;
    Serial.print("mem energy: ");
    Serial.println(mem_energy);

    relay1 = new Supla::Control::Relay(relay_pin);
    new Hj101(); 
            
    SuplaDevice.setName(Supla_name);
    SuplaDevice.setStatusFuncImpl(&status_func);
    wifi.enableSSL(false);  
    SuplaDevice.begin(GUID,Supla_server,Email,AUTHKEY);
                      
}
char buffer[50];
void loop() {
  
  if (initialConfig == true){ondemandwifiCallback();EEPROM.write(431, 0); EEPROM.commit();}

   int C_W_read = digitalRead(wificonfig_pin);{  
   if (C_W_read != last_C_W_state) {            
     time_last_C_W_change = millis();
   }
   if ((millis() - time_last_C_W_change) > C_W_delay2) {     
     if (C_W_read != C_W_state2) {     
       C_W_state2 = C_W_read; 
       if (C_W_state2 == LOW) { 
        Serial.println("short press");     
         if (!relay1->isOn()) {
          relay1->turnOn();
          yield();
          Serial.println("relayOn");
          Eeprom_save() ;
       }else{
         relay1->turnOff();
         yield();
         Serial.println("relayOff");
         Eeprom_save() ;
     }}}       
    }
   if ((millis() - time_last_C_W_change) > C_W_delay) {     
     if (C_W_read != C_W_state) {     
       Serial.println("long press");
       C_W_state = C_W_read;       
       if (C_W_state == LOW) {
        ondemandwifiCallback () ;
       }
     }
    }
   last_C_W_state = C_W_read;            
 }
  
  if (shouldSaveConfig == true) { // ------------------------ wificonfig save --------------
    Serial.println(" config...");  
    DynamicJsonDocument json(1024);
    json["Supla_server"] = Supla_server;
    json["Email"] = Email;
    json["Supla_name"] = Supla_name;
    File configFile = LittleFS.open("/config.json", "w");
    if (!configFile) {
      Serial.println("failed to open config file for writing");
    }
        serializeJsonPretty(json, Serial);
        serializeJson(json, configFile);
    configFile.close();
    Serial.println("Config written successfully");
    shouldSaveConfig = false;
    initialConfig = false; 
    WiFi.mode(WIFI_STA);   
    delay(5000);
    ESP.restart();     
  }
  
  if (s == 17){
    if ((Tik == true) && (WiFi.status() == WL_CONNECTED)){ticker.detach();Tik = false;}
    if(millis() > eep_milis){
     Eeprom_save() ;
     eep_milis = millis() + 3000 ; 
    }
    if (recover){
     Serial.println("ticker off");
      if (EEPROM.read(431) == true){
       relay1->turnOn();
        yield();
         Serial.println("relayOn");
          eep_milis = millis() + 3000 ;
       }
       recover = false; 
      }
    }
  if ((s != 17) && (Tik == false)) { ticker.attach(0.5, tick);Tik = true;Serial.println("ticker on  no 17"); }    
  //if ((WiFi.status() != WL_CONNECTED) && (Tik == false)){ticker.attach(0.5, tick);Tik = true;Serial.println("ticker on no wifi"); }         
  if (s == 10){recover = true;} 
     
   SuplaDevice.iterate();
   delay(50);
   
   if (WiFi.status() == WL_CONNECTED){
    if (starting){
      httpUpdater.setup(&httpServer, "/update", "admin", "pass");
      httpServer.begin(); 
      starting = false;         
     }
    httpServer.handleClient();
    if ((digitalRead(relay_pin) == digitalRead(status_led)) && (s ==17)){
    digitalWrite(status_led,!digitalRead(relay_pin));
   }
   }

   if(millis() > mem_energy_milis){
    if ((float(hjl01.getEnergy()) + mem_energy > _mem_energy) && (digitalRead(relay_pin) == HIGH)){
     Serial.println("save energy");
      _mem_energy = (float)hjl01.getEnergy() + mem_energy;
      EEPROM.put(460, _mem_energy);
      EEPROM.commit();
     mem_energy_milis = millis() + 600000 ;  
    }
   }

}
To access the Wi-Fi configuration, press button for at least 10 seconds, Led winks in wificonfig.
in the configuration page enter the data for "suplaServer, Email and Supla Device Name (name with which it will be seen in the cloud and DHCP)"

expectedVoltage = for calibration.

expectedActivePower = for calibration.

clear Storage = reset counter.

calibration process:
connect a resistive load with a known consumption, for example a 60W bulb.
access wificonfig (button pressed 10 seconds)
in the "expectedVoltage" field set the voltage of your line for example 227.
in the "expectedActivePower" field, set the consumption of the connected load, for example 60.
press save.
The procedure takes about 15 seconds, then the device restarts and the readings will be correct.
the calibration is only executed if there are data in both fields "expectedVoltage" and "expectedActivePower"
This allows for example to change the Wi-Fi network without recalibrating.

Gosund_SP111_DOUT_8Mbit.rar
Awsome. If I good understand it's a way of auto-calibration (instead of manually writings calibration factors)?
Really cool. I need find time to try it.

I've mentioned about my two Nous A1 sockets (I'll try this soft with them) which I'm using almost 2 years and I would like to keep numbers recorded till now - is this possible to set some initial state (ex. 66kWh) in script - maybe for variable "_mem_energy" or "mem_energy". Could you confirm?
------------------------------------------------------
MEW-01 | SRW-01 x2
elmaya
Posty: 1482
Rejestracja: śr cze 27, 2018 5:48 pm
Lokalizacja: El Saucejo - Sevilla

borbet7 pisze: wt lis 10, 2020 8:18 pm
Awsome. If I good understand it's a way of auto-calibration (instead of manually writings calibration factors)?
Really cool. I need find time to try it.

I've mentioned about my two Nous A1 sockets (I'll try this soft with them) which I'm using almost 2 years and I would like to keep numbers recorded till now - is this possible to set some initial state (ex. 66kWh) in script - maybe for variable "_mem_energy" or "mem_energy". Could you confirm? Then I need to learn how to compile code :)
the calibration is carried out with a known voltage and consumption which makes it have a good precision.

the initial reading will be 0, I have not added the possibility to define a certain initial value in the code.
Awatar użytkownika
lukfud
Posty: 2091
Rejestracja: czw lis 23, 2017 11:33 pm
Lokalizacja: Warszawa

elmaya pisze: wt lis 10, 2020 3:24 pm

Kod: Zaznacz cały

#define HJL01_CURRENT_RATIO             25740
#define HJL01_VOLTAGE_RATIO             313400
#define HJL01_POWER_RATIO               3414290
Why these values? Where did you get them?
https://www.facebook.com/groups/supladiy/
ODPOWIEDZ

Wróć do „Ogólna dyskusja”