I have a “Paladin” solar hot water diverter which diverts excess solar production into my hot water cylinder. It has a serial interface which I am trying to use to get the values like solar divert watts, hot water cylinder temp etc…
In basic language I’ve been told if a send “R” to the Paladin it will respond with;
Mains Watts Now (-ve = Grid In)
Transfer Watts Now
Hot Water Temp
Solar Watts Now
Inverter Active Flag
Charger Active Flag
Force Export Flag
I have a basic ESPHome configuration up and running that gives me a button to send the “R” character.
I have very little experience with serial, ascii, hex and all that so I’m hoping someone can help me work with the following data that I get back.
[15:37:34][D][uart_debug:114]: <<< FE:00:FC:00:00:00:F8:00:80:00:00:00:FD:00:C0:00:00:00:FE:00:00:00:00:00:FC:00:C0:00:00:FF:00:FC:00:C0:00:00:FF:00:FE:00:00:00:FF:00:FE:00:00:00:FF:00:FE:00:00:00:FE:00:F8:00:00:00:D8:00:FE:00:00:00:C0:00:FE:00:00:00:FB:00:FE:00:00:00:FD:00:80:00:00:FF:00:FC:00:C0:00:00:FE:00:FF:00:FC:00:00:FF:00:FE:00:FA:00:00:00:FF:00:00:00:FF:00:C8:00:00:00:EC:00:C0:00:00:00:D2:00:FF:00:00:00:FE:00:D0:00:00:00:FE:00:E4:00:00:FF:00:FE:00:F8:00:00:00:FF:00:FA:00
I’ve been in contact with the manufacturer and they have given me some example C++ code that might hopefully give someone with the experience the information needed to help me out?
===================================
declare a global String PalData
Then you need to bring in the data from the serial stream byte by byte as a char and accumulate into PalData.
LastPalData holds the previous record - so declare that as global also.
void checkPalData()
{
uint8_t ch;
while (Serial.available())
{
ch = Serial.read();
if (ch >= 9 && ch <= 128)
{
if (ch == '\n')
{
PalDataDone = true;
LastPalData = PalData;
break;
}
else
{
PalData += (char)ch;
}
}
}
}
PalDataDone is a Boolean flag so I only hit this routine when needed.
You can then do this…
void getPalData() // Matches Pal6 string off serial
{
Pal6.MainsWatts = returnValue(0).toInt();
Pal6.TransWatts = returnValue(1).toInt();
Pal6.SolarWatts = returnValue(2).toInt();
Pal6.HotWater = returnValue(3).toFloat();
Pal6.DeltaT = returnValue(4).toFloat();
Pal6.MinTemp = returnValue(5).toInt();
if (Pal6.MinTemp == 0) Pal6.MinTemp = 1;
P6V.mint = Pal6.MinTemp;
Pal6.MaxTemp = returnValue(6).toInt();
Pal6.MainsWattsIn = returnValue(7).toInt(); // There are 720 of these per hour and each gia unit = 1W per hour
Pal6.MainsWattsOut = returnValue(😎.toInt();
Pal6.TransWattsOut = returnValue(9).toInt();
Pal6.TransWattsIn = returnValue(10).toInt();
Pal6.SolarWattsOut = returnValue(11).toInt();
Pal6.HoursToMHT = returnValue(12).toInt();
Pal6.GWActive = returnValue(13).toInt();
Inverter.Active = Pal6.GWActive;
Pal6.GWCharging = returnValue(14).toInt();
Charger.Active = Pal6.GWCharging;
Pal6.SolarExport = returnValue(15).toInt();
Solar.Active = Pal6.SolarExport; //Export Solar ?
Pal6.ExportActive = returnValue(16).toInt();
Pal6.ImportActive = returnValue(17).toInt();
Pal6.OverFlow = returnValue(18).toInt();
espTime = returnValue(19);
unsigned long palLongTime = makeLong(espTime);
int diff = palLongTime - now();
if (abs(diff) > 120)
{
if (LastTimeHack < now())
{
pme("Clock Diff ", diff);
// getInternetTime();
sendPaladinT();
LastTimeHack = now() + 120; // wait 60 seconds at least between time hacks
}
}
Using the returnValue(num) routine
String returnValue(int index) // Return value @pos from comma delimited string
{
int found = 0;
int strIndex[] = { 0, -1 };
int maxIndex = PalData.length() - 1;
for (int i = 0; i <= maxIndex && found <= index; i++)
{
if (PalData.charAt(i) == ',' || i == maxIndex)
{
found++;
strIndex[0] = strIndex[1] + 1;
strIndex[1] = (i == maxIndex) ? i + 1 : i;
}
}
return (found > index) ? PalData.substring(strIndex[0], strIndex[1]) : "";
}