// (S)tuder <-> (A)rduino -> (L)oxone

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <LiquidCrystal_PCF8574.h>  // LCD displej pres I2C 
#include <Wire.h>

LiquidCrystal_PCF8574 lcd(0x27);     // nastavení adresy I2C (0x27 v mém případě) a dále počtu znaků a řádků LCD, zde 20x4

byte mac[] = { 0xA8, 0x61, 0x0A, 0xAE, 0xA8, 0xCE };  // MAC adresa Arduino Ethernetu
IPAddress ip(192, 168, 1, 37);                       // IP adresa  
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress RecipientIP(192, 168, 1, 77);  // Recipient IP - Loxone

unsigned int RecipientPort = 52736;    // Recipient UDP Port 
unsigned int localPort = 2736;      // local port to listen on

EthernetUDP Udp;    // An EthernetUDP instance to let us send and receive packets over UDP


char inByte[30];
int pB = 26;    // počet bytů
int pB2 = 30;   // počet bytů
int pp = 2;

int j = 1;
int del = 50;   // doba čekání
byte A, B, C, D;
float a000, Ubat, Ibat;

byte p1[26] = {0xAA,0x00,0x01,0x00,0x00,0x00,0x59,0x02,0x00,0x00,0x0A,0x00,0x65,0x33,0x00,0x01,0x01,0x00,0x58,0x1B,0x00,0x00,0x01,0x00,0x75,0xA0 }; //1  Proud baterie BSP (7001)
byte p2[26] = {0xAA,0x00,0x01,0x00,0x00,0x00,0x59,0x02,0x00,0x00,0x0A,0x00,0x65,0x33,0x00,0x01,0x01,0x00,0x59,0x1B,0x00,0x00,0x01,0x00,0x76,0xA6 }; //2  Napeti baterie BSP (7000)


void setup() {
  Wire.begin();
  Wire.beginTransmission(0x27);
  // inicializace LCD
  lcd.begin(20,4);
  // zapnutí podsvícení
  lcd.setBacklight(255);
  // vytisknutí hlášku na první řádek
  lcd.print("cas behu:");
  // start the Ethernet and UDP:
  Ethernet.begin(mac,ip);
  Udp.begin(localPort);
  Serial.begin(38400, SERIAL_8E1) ; //nastav komunikacni parametry Serial do Studeru
     
}

void loop() {
  // nastavení kurzoru 
  lcd.setCursor(10, 0);
  // vytisknutí počtu sekund od začátku programu
  lcd.print(millis() / 1000);
  lcd.print(" s ");
  
  for(int i=0;i<(pB);i++) { Serial.write(p1[i]); }    // 7001
  Ibat = odpoved_RS232(); delay(del); Serial.write("1234567890123"); 
  delay(20);

  for(int i=0;i<(pB);i++) { Serial.write(p2[i]); }    // 7000
  Ubat = odpoved_RS232(); delay(del); Serial.write("***trinact***"); 
  delay(20);

  tisk_vysledku_na_LCD();
   
  poslatUDP("7000", Ubat);
  poslatUDP("7001", Ibat);
  
  
  
}   // *********************************** KONEC HLAVNÍHO PROGRAMU  **********************************************************


float odpoved_RS232()   //priklad podprogramu pro vycitani jedne hodnoty ze studeru
  {

  a000 = 0;
   if (Serial.available() > 0) {    
    for(int i=0;i<(pB2);i++)
      inByte[i] = Serial.read();  
    A = inByte[27];     
    B = inByte[26];    
    C = inByte[25];     
    D = inByte[24];                                         
    byte array[4] = { A, B, C, D };
    a000 = (convert(array));
    }
  return a000;
}

typedef union {
  byte array[4];
  float value;
} ByteToFloat;

float convert(byte* data) {
  ByteToFloat converter;
  for (byte i = 0; i < 4; i++){
    converter.array[3-i] = data[i]; 
  }
  return converter.value;
}

void tisk_vysledku_na_LCD()
{
  lcd.setCursor(0, 2); lcd.print("Ubat: "); lcd.print(Ubat); lcd.print(" V   ");
  lcd.setCursor(0, 3); lcd.print("Ibat: "); lcd.print(Ibat); lcd.print(" A   ");
}



void poslatUDP(char dotazID[5], float odpHod)   // Funkce pro odeslání čísla dotazu a hodnoty odpovědi
{
  Udp.beginPacket(RecipientIP, RecipientPort);
  Udp.print(dotazID);
  Udp.print(odpHod);
 
  Udp.endPacket();
  delay(10);
}



