/*
  RS485_HalfDuplex.pde - example using ModbusMaster library to communicate
  with EPSolar LS2024B controller using a half-duplex RS485 transceiver.
  This example is tested against an EPSolar LS2024B solar charge controller.
  See here for protocol specs:
  http://www.solar-elektro.cz/data/dokumenty/1733_modbus_protocol.pdf
  Library:: ModbusMaster
  Author:: Marius Kintel <marius at kintel dot net>
  Copyright:: 2009-2016 Doc Walker
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
      http://www.apache.org/licenses/LICENSE-2.0
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/
#include <ModbusMaster.h>
#include <ESP8266WiFi.h>
const char* ssid     = "************"; // název wifi sítě
const char* password = "************";  // heslo wifi sítě
unsigned long  data_zmena = 0;      // bude ukládat poslední případ aktualizace data
unsigned long  data_interval = 1000;        //interval stažení
unsigned long  vyroba_zmena = 0;      // bude ukládat poslední případ aktualizace data
unsigned long  vyroba_interval = 1000;        //interval stažení
unsigned long  export_zmena = 0;      // bude ukládat poslední export
unsigned long  export_interval = 1*60*1000;        //interval exportu 1 minuta
unsigned long  cas=0; //cas_mereni double  
unsigned long  cas_export=0; //cas_exportu
double pn=0;
double pp=0;
double pv=0;
double bn=0;
double bp=0;
double bv=0;
double bmax=0;
double bmin=0;
double btemp=0;
double dtemp=0;
double bsoc=0;
double ednes=0;
double emesic=0;
double erok=0;
double etotal=0;
double cassecmin=0;
double cashodden=0;
double casmesrok=0;
double bstatus=0;
double cstatus=0;
double dstatus=0;

const char* host = "*****************"; //jmeno serveru
const int httpPort = 80; //port serveru
char* apiKey ="VYROBA_1"; 
int kolikaty=0;
#define MAX485_DE      D2
#define MAX485_RE_NEG  D2

// ModBus Register Locations
//
#define LIVE_DATA       0x3100     // start of live-data 
#define LIVE_DATA_CNT   16         // 16 regs

// just for reference, not used in code
#define PANEL_VOLTS     0x00       
#define PANEL_AMPS      0x01
#define PANEL_POWER_L   0x02
#define PANEL_POWER_H   0x03

#define BATT_VOLTS      0x04
#define BATT_AMPS       0x05
#define BATT_POWER_L    0x06
#define BATT_POWER_H    0x07

// instantiate ModbusMaster object
ModbusMaster node;
void preTransmission()
{
  digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);
}
void postTransmission()
{
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
}
void setup()
{
  WiFi.begin(ssid, password);
  int timeout = millis()+10000;
  while ((WiFi.status() != WL_CONNECTED) && (timeout > millis())) {
    delay(1000);
  }
  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  // Init in receive mode
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
  // Modbus communication runs at 115200 baud
  Serial.begin(115200);
  // Modbus slave ID 1
  node.begin(1, Serial);
  // Callbacks allow us to configure the RS485 transceiver correctly
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);

}
bool state = true;

void loop()
{
    unsigned long currentMillis = millis();

    if(currentMillis - data_zmena > data_interval) {
  uint8_t result;
  uint16_t data[6];
  kolikaty=kolikaty+1;  
  // Read 16 registers starting at 0x3100)
if (kolikaty%6==0) {

  result = node.readInputRegisters(0x3100, 16);
  if (result == node.ku8MBSuccess)
  {
    Serial.println(" - - - - - - - - - - - - - - ");
    Serial.println("MAIN DETAILS:");
    Serial.print("Panely Napětí: ");
    pn=node.getResponseBuffer(0x00)/ 100.0f;
    Serial.println(pn);
    pp=node.getResponseBuffer(0x01)/ 100.0f;
    Serial.print("Panely Proud: ");
    Serial.println(pp);
    pv=(node.getResponseBuffer(0x02) | node.getResponseBuffer(0x03) << 16)/ 100.0f;
    Serial.print("Panely Výkon: ");
    Serial.println(pv);
    Serial.print("Baterie Napětí: ");
    bn=node.getResponseBuffer(0x04)/ 100.0f;
    Serial.println(bn);
    bp=node.getResponseBuffer(0x05)/ 100.0f;
    Serial.print("Baterie Proud: ");
    Serial.println(bp);
    bv=(node.getResponseBuffer(0x06) | node.getResponseBuffer(0x07) << 16)/ 100.0f;
    Serial.print("Baterie Výkon: ");
    Serial.println(bv);
  }
  else {
    Serial.print("err: ");
    Serial.print(result);
    Serial.print("--");
    Serial.println(node.ku8MBSuccess);
  }
  Serial.print("A:");
  Serial.println(kolikaty);

}
else if (kolikaty%6==1) { 
  result = node.readInputRegisters(0x3300, 4);
  if (result == node.ku8MBSuccess)
  {
    Serial.println(" - - - - - - - - - - - - - - ");
    Serial.println("MAIN DETAILS:");
    Serial.print("Baterie max: ");
    bmax=node.getResponseBuffer(0x02)/ 100.0f;
    Serial.println(bmax);
    Serial.print("Baterie min: ");
    bmin=node.getResponseBuffer(0x03)/ 100.0f;
    Serial.println(bmin);
  }
  else {
    Serial.print("err: ");
    Serial.print(result);
    Serial.print("--");
    Serial.println(node.ku8MBSuccess);
  }
  Serial.print("B:");
  Serial.println(kolikaty);
}
else if (kolikaty%6==2) {
  result = node.readInputRegisters(0x330c, 8);
  if (result == node.ku8MBSuccess)
  {
    Serial.println(" - - - - - - - - - - - - - - ");  
    Serial.println("MAIN DETAILS:");
    Serial.print("BEnergie dnes: ");
    ednes=(node.getResponseBuffer(0x00) | node.getResponseBuffer(0x01) << 16)/ 100.0f;
    Serial.println(ednes);
    Serial.print("BEnergie mesic: ");
    emesic=(node.getResponseBuffer(0x02) | node.getResponseBuffer(0x03) << 16)/ 100.0f;
    Serial.println(emesic);
    Serial.print("BEnergie rok: ");
    erok=(node.getResponseBuffer(0x04) | node.getResponseBuffer(0x05) << 16)/ 100.0f;
    Serial.println(erok);
    Serial.print("BEnergie celkem: ");
    etotal=(node.getResponseBuffer(0x06) | node.getResponseBuffer(0x07) << 16)/ 100.0f;
    Serial.println(etotal);
  }
  else {
    Serial.print("err: ");
    Serial.print(result);
    Serial.print("--");
    Serial.println(node.ku8MBSuccess);
  }
  Serial.print("C:");
  Serial.println(kolikaty);
}
else if (kolikaty%6==3) {
//  result = node.readInputRegisters(0x9013, 3);
  result = node.readInputRegisters(0x3200, 3);
  if (result == node.ku8MBSuccess)
  {
    Serial.println(" - - - - - - - - - - - - - - ");
    Serial.println("MAIN DETAILS:");
    Serial.print("Batery status: ");
    bstatus=node.getResponseBuffer(0x00);
    Serial.println(bstatus);
    Serial.print("Charging status: ");
    cstatus=node.getResponseBuffer(0x01);
    Serial.println(cstatus);
    Serial.print("Device status: ");
    dstatus=node.getResponseBuffer(0x02);
    Serial.println(dstatus);
  }
  else {
    Serial.print("err: ");
    Serial.print(result);
    Serial.print("--");
    Serial.println(node.ku8MBSuccess);
  }
  Serial.print("D:");
  Serial.println(kolikaty);
}
else if (kolikaty%6==4) { 
  result = node.readInputRegisters(0x3110, 10);
  if (result == node.ku8MBSuccess)
  {
    Serial.println(" - - - - - - - - - - - - - - ");
    Serial.println("MAIN DETAILS:");
    Serial.print("Baterie temp: ");
    btemp=node.getResponseBuffer(0x0)/ 100.0f;
    Serial.println(dtemp);
    Serial.print("Device temp: ");
    dtemp=node.getResponseBuffer(0x1)/ 100.0f;
    Serial.println(btemp);
    Serial.print("Baterie soc: ");
    bsoc=node.getResponseBuffer(0xa)/ 100.0f;
    Serial.println(bsoc);
  }
  else {
    Serial.print("err: ");
    Serial.print(result);
    Serial.print("--");
    Serial.println(node.ku8MBSuccess);
  }
  Serial.print("E:");
  Serial.println(kolikaty);
}
else if (kolikaty%6==5) { 
  result = node.readInputRegisters(0x311A, 1);
  if (result == node.ku8MBSuccess)
  {
    Serial.println(" - - - - - - - - - - - - - - ");
    Serial.println("MAIN DETAILS:");
    Serial.print("Baterie soc: ");
    bsoc=node.getResponseBuffer(0xa)/ 100.0f;
    Serial.println(bsoc);
  }
  else {
    Serial.print("err: ");
    Serial.print(result);
    Serial.print("--");
    Serial.println(node.ku8MBSuccess);
  }
  Serial.print("E:");
  Serial.println(kolikaty);
}

      data_zmena = currentMillis;
    }

    if(currentMillis - export_zmena > export_interval) {
      kolikaty=0;
      cas_export=currentMillis-export_zmena;
      data_zmena = currentMillis;
      export_zmena = currentMillis;
      WiFiClient client;
      if(client.connect(host, httpPort)){
        delay(100);
        String url = "/arduino/fveupdate.php?api_key=";
        url += apiKey;
        url += "&panely_napeti=";
        url += (pn);
        url += "&panely_proud=";
        url += (pp);
        url += "&panely_vykon=";
        url += (pv);
        url += "&baterie_napeti=";
        url += (bn);
        url += "&baterie_proud=";
        url += (bp);
        url += "&baterie_vykon=";
        url += (bv);
        url += "&baterie_max=";
        url += (bmax);
        url += "&baterie_min=";
        url += (bmin);
        url += "&baterie_temp=";
        url += (btemp);
        url += "&baterie_soc=";
        url += (bsoc);
        url += "&device_temp=";
        url += (dtemp);
        url += "&energie_dnes=";
        url += (ednes);
        url += "&energie_mes=";
        url += (emesic);
        url += "&energie_rok=";
        url += (erok);
        url += "&energie_total=";
        url += (etotal);
        url += "&c_status=";
        url += (cstatus);
        url += "&b_status=";
        url += (bstatus);
        url += "&d_status=";
        url += (dstatus);
        url += "&ssid=";
        url += (ssid);
        url += "&cas_export=";
        url += (cas);
        client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" + 
               "Connection: close\r\n\r\n");
        delay(10);
        while(client.available()){
          String line = client.readStringUntil('\r');
        }  
       }    



  
}
}
