rflink_old/Plugins/Plugin_090.c

218 lines
14 KiB
C

//#######################################################################################################
//## This Plugin is only for use with Nodo 3.7 Slave Devices (variablesend support) ##
//## Plugin-090 Nodo Slave ##
//#######################################################################################################
// *********************************************************************************************
// * This Plugin takes care of reception of Nodo 3.7 Slave Devices
// *
// * Author : StuntTeam
// * Support : http://sourceforge.net/projects/rflink/
// * License : This code is free for use in any open source project when this header is included.
// * Usage of any parts of this code in a commercial application is prohibited!
// *********************************************************************************************
// * Changelog: v1.0 initial release
// *********************************************************************************************
// ----------------------------------
// Nodo Slave Unit 1, 2 and 4 till 9: // Individual sensor data
//
// Variabele 5 : Temperature
// Variabele 6 : Humidity 0 - 100
// Variabele 7 : Rain fall
// Variabele 8 : Wind speed
// Variabele 9 : Wind direction 0 - 15
// Variabele 10 : Wind gust
// Variabele 11, 12 en 13 : Temperature
// Variabele 14 : Humidity 0 - 100
// Variabele 15 : UV meter 0 - 1024
// Variabele 16 : Barometric pressure
//
// ----------------------------------
// Nodo Slave Unit 10 till 16: // Combined sensor data
//
// Variabele 5 : Temperature
// Variabele 6 : Humidity 0 - 100
// Variabele 7 : Rain fall
// Variabele 8 : Wind speed
// Variabele 9 : Wind direction 0 - 15
// Variabele 10 : Wind gust
// Variabele 11, 12 en 13 : Temperature
// Variabele 14 : Humidity 0 - 100
// Variabele 15 : UV meter 0 - 1024
// Variabele 16 : Barometric pressure
//
// ----------------------------------
// Nodo Slave Unit 3: // Pulse Meters
//
// Variabele 1 till 16 : Pulse value 1 till 16
//
// You can use a Nodo slave device with ID 03 to send variabel numbers 1 til 16
// which will be passed to Domoticz as pulse meter values (electricity/water/gas etc.)
// ----------------------------------
//
// * Sample:
// * 20;9E;DEBUG;Pulses=194;Pulses(uSec)=3100,900,500,350,1475,375,525,300,1475,375,500,350,450,375,575,250,525,300,1475,375,1450,400,1450,400,425,425,425,425,1425,425,425,425,425,400,425,400,425,400,425,400,425,400,450,400,425,400,450,400,450,400,450,400,425,400,425,425,425,425,425,425,400,425,425,425,400,425,1425,425,400,425,400,425,400,425,400,425,400,425,425,425,400,425,425,425,425,425,1450,425,425,425,425,425,425,425,425,425,400,425,1425,425,1425,425,400,425,400,425,400,425,400,425,400,425,400,425,400,425,425,425,425,425,400,425,400,425,400,425,400,425,400,425,400,425,400,450,400,450,400,450,400,450,400,450,400,450,1400,450,400,450,400,450,400,425,400,450,400,425,1425,425,400,425,1425,425,1425,450,400,450,400,450,375,450,375,450,400,450,1425,450,400,450,1425,425,1425,450,400,450,400,425,400,450,400,450,400,450,400;
// * 20;9F;Slave;ID=0307;DEBUG=0014;
// * slave nodo 7, var 3 value 14
// 3100,900,
/*( 194-2=192/2 = 96
500,350,1475,375,525,300,1475,375,500,350,450,375,575,250,525,300,1475,375,1450,400,1450,400,425,425,425,425,1425,425,425,425,425,400,425,400,425,400,425,400,425,400,450,400,
425,400,450,400,450,400,450,400,425,400,425,425,425,425,425,425,400,425,425,425,400,425,1425,425,400,425,400,425,400,425,400,425,400,425,425,425,400,425,425,425,425,425,1450,
425,425,425,425,425,425,425,425,425,400,425,1425,425,1425,425,400,425,400,425,400,425,400,425,400,425,400,425,400,425,425,425,425,425,400,425,400,425,400,425,400,425,400,425,
400,425,400,450,400,450,400,450,400,450,400,450,400,450,1400,450,400,450,400,450,400,425,400,450,400,425,1425,425,400,425,1425,425,1425,450,400,450,400,450,375,450,375,450,
400,450,1425,450,400,450,1425,425,1425,450,400,450,400,425,400,450,400,450,400,450,400;
01010000 11100100 00000000 00000000 10000000 00100000 11000000 00000000 00000001 00000101 10000010 11000000
00001010 00100111 00000000 00000000 00000001 00000100 00000011 00000000 10000000 10100000 01000001 00000011
50E400008020C0010582C0
A270000104030080A04103
*/
// *********************************************************************************************
#define NODO_PULSE_MID 1000/RAWSIGNAL_SAMPLE_RATE // PWM: Pulsen langer zijn '1'
#define NodoSlave_PULSECOUNT 194
#ifdef PLUGIN_090
struct DataBlockStruct { // 16*sizeof(struct DataBlockStruct)+2 = 194 eg. 16*12+2
byte Version;
byte SourceUnit; // event->SourceUnit=DataBlock.SourceUnit&0x1F; // Maskeer de bits van het Home adres.
byte DestinationUnit; // event->DestinationUnit=DataBlock.DestinationUnit; // destination nodo
byte Flags;
byte Type; // event->Type=DataBlock.Type;
byte Command; // event->Command=DataBlock.Command;
byte Par1; // event->Par1=DataBlock.Par1;
unsigned long Par2; // event->Par2=DataBlock.Par2;
byte Checksum;
};
boolean Plugin_090(byte function, char *string) {
if (RawSignal.Number!=NodoSlave_PULSECOUNT ) return false; // Per byte twee posities + startbit.
byte b,x,y,z;
unsigned long varvalue=0L;
struct DataBlockStruct DataBlock;
byte *B=(byte*)&DataBlock; // B wijst naar de eerste byte van de struct
z=3; // RawSignal pulse teller: 0=niet gebruiktaantal, 1=startpuls, 2=space na startpuls, 3=1e pulslengte. Dus start loop met drie.
for(x=0;x<sizeof(struct DataBlockStruct);x++) { // vul alle bytes van de struct
b=0;
for(y=0;y<=7;y++) { // vul alle bits binnen een byte
if((RawSignal.Pulses[z]) > NODO_PULSE_MID)
b|=1<<y; // LSB in signaal wordt als eerste verzonden
z+=2;
}
*(B+x)=b;
}
// xor all bytes to check the checksum value?
DataBlock.SourceUnit=DataBlock.SourceUnit &0x1f;
//==================================================================================
// Er zijn een aantal type Nodo events die op verschillende wijze worden behandeld:
//#define NODO_TYPE_EVENT 1
//#define NODO_TYPE_PLUGIN_EVENT 4
//#define NODO_TYPE_PLUGIN_COMMAND 5
if ((DataBlock.Command == 4) && (DataBlock.Type == 1)){ // event->command = DataBlock.Command = 4 = EVENT_VARIABLE
// ----------------------------------
// Output
// ----------------------------------
sprintf(pbuffer, "20;%02X;", PKSequenceNumber++); // Node and packet number
Serial.print( pbuffer );
// ----------------------------------
Serial.print(F("Slave;")); // Label
//==================================================================================
// slave id 03 aka source nodo id 03 => variable 1..6 will be pulse meter data
//==================================================================================
if (DataBlock.SourceUnit == 3 ) { // Pulse Meter variables
sprintf(pbuffer, "ID=%02x%02x%02x;", DataBlock.DestinationUnit, DataBlock.SourceUnit, DataBlock.Par1); // ID
Serial.print( pbuffer );
varvalue = ul2float(DataBlock.Par2); // convert
if ((DataBlock.Par1 < 1) || (DataBlock.Par1 > 16)) { // Unsupported (for now) variable, just show the contents
sprintf(pbuffer, "DEBUG=%08lx;", varvalue); // value
} else {
sprintf(pbuffer, "METER=%08lx;", varvalue); // value
}
Serial.print( pbuffer );
Serial.println();
} else
//==================================================================================
// slave id > 09 aka source nodo id > 09 => Combined variables
// slave id < 10 aka source nodo id < 10 => Regular variables
//==================================================================================
if ((DataBlock.SourceUnit > 0) && (DataBlock.SourceUnit < 17)) {
if (DataBlock.SourceUnit > 9 ) {
sprintf(pbuffer, "ID=%02x%02x;",DataBlock.SourceUnit , DataBlock.DestinationUnit); // ID
} else {
sprintf(pbuffer, "ID=%02x%02x%02x;", DataBlock.DestinationUnit, DataBlock.SourceUnit, DataBlock.Par1); // ID
}
Serial.print( pbuffer );
if ((DataBlock.Par1 < 5) || (DataBlock.Par1 > 16)) { // Unsupported (for now) variable, just show the contents
int varvalue = ul2float(DataBlock.Par2); // convert
sprintf(pbuffer, "DEBUG=%04x;", varvalue); // value
} else
if (DataBlock.Par1 == 5){ // Variable 5 : temperature
int temperature = 10 * ul2float(DataBlock.Par2); // convert
if (temperature <= 0) temperature=-temperature | 0x8000; // set high bit for negative temperatures
sprintf(pbuffer, "TEMP=%04x;", temperature); // value
} else
if (DataBlock.Par1 == 6){ // Variable 6 : humidity
int humidity = ul2float(DataBlock.Par2) + 0.5; // add 0.5 to make sure it's rounded the way it should and assign as integer to remove decimal value
sprintf(pbuffer, "HUM=%02d;", humidity); // value
} else
if (DataBlock.Par1 == 7){ // Variable 7 : Rain in mm.
int rain = ul2float(DataBlock.Par2); // convert
sprintf(pbuffer, "RAIN=%04x;", rain); // value
} else
if (DataBlock.Par1 == 8){ // Variable 8 : Wind speed
int winsp = ul2float(DataBlock.Par2); // convert
sprintf(pbuffer, "WINSP=%04x;", winsp); // value
} else
if (DataBlock.Par1 == 9){ // Variable 9 : Wind Direction
int windir = ul2float(DataBlock.Par2); // convert
sprintf(pbuffer, "WINDIR=%04d;", windir); // value
} else
if (DataBlock.Par1 == 10){ // Variable 10: Wind Gust
int wings = ul2float(DataBlock.Par2); // convert
sprintf(pbuffer, "WINGS=%04x;", wings); // value
}
if ((DataBlock.Par1 > 10) && (DataBlock.Par1 < 14)) { // Variable 11 12 or 13 : emulate temperature sensor
int temperature = 10 * ul2float(DataBlock.Par2); // convert
if (temperature <= 0) temperature=-temperature | 0x8000; // set high bit for negative temperatures
sprintf(pbuffer, "TEMP=%04x;", temperature); // value
} else
if (DataBlock.Par1 == 14){ // Variable 14 : emulate humidity sensor
int humidity = ul2float(DataBlock.Par2) + 0.5; // add 0.5 to make sure it's rounded the way it should and assign as integer to remove decimal value
sprintf(pbuffer, "HUM=%02d;", humidity); // value
} else
if (DataBlock.Par1 == 15){ // Variable 15 : UV sensor
int light = ul2float(DataBlock.Par2); // supplied is value between 0 and 1024
light = map(light, 0,1024,1,100); // Map value to 1 - 100
sprintf(pbuffer, "UV=%04x;", light); // value
} else
if (DataBlock.Par1 == 16){ // Variable 16 : Barometric pressure sensor
int baro = ul2float(DataBlock.Par2); // convert
sprintf(pbuffer, "BARO=%04x;", baro); // value
}
Serial.print( pbuffer );
Serial.println();
}
//==================================================================================
} else { // Not a variable event
if ((DataBlock.Command == 0) && (DataBlock.Type==0)) return false;
// ----------------------------------
// Output
// ----------------------------------
sprintf(pbuffer, "20;%02X;", PKSequenceNumber++); // Node and packet number
Serial.print( pbuffer );
// ----------------------------------
Serial.print(F("Slave;Debug=")); // Label
sprintf(pbuffer, "%02x %02x %02x %02x %02x ", DataBlock.DestinationUnit, DataBlock.SourceUnit, DataBlock.Command, DataBlock.Type, DataBlock.Par1);
Serial.print( pbuffer );
sprintf(pbuffer, "%d;", DataBlock.Par2); // ID
Serial.print( pbuffer );
Serial.println();
}
//==================================================================================
RawSignal.Repeats=true; // suppress repeats of the same RF packet
RawSignal.Number=0;
return true;
}
#endif // PLUGIN_090