1
0
mirror of https://github.com/seahu/rflink.git synced 2025-12-10 16:07:23 +01:00
Files
rflink_rPi/Plugins/Plugin_031.c
Ondrej Lycka 406093e31d first commit
2017-04-29 03:27:02 +02:00

182 lines
9.0 KiB
C

//#######################################################################################################
//## This Plugin is only for use with the RFLink software package ##
//## Plugin-31 AlectoV3 ##
//#######################################################################################################
/*********************************************************************************************\
* Dit protocol zorgt voor ontvangst van Alecto weerstation buitensensoren
* WS1100, WS1200, WSD-19
*
* 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
*********************************************************************************************
* Technische informatie:
* Decodes signals from Alecto Weatherstation outdoor unit, type 3 (94/126 pulses, 47/63 bits, 433 MHz).
* WS1100 Message Format: (7 bits preamble, 5 Bytes, 40 bits):
* AAAAAAA AAAABBBB BBBB__CC CCCCCCCC DDDDDDDD EEEEEEEE
* Temperature Humidity Checksum
* A = start/unknown, first 8 bits are always 11111111
* B = Rolling code
* C = Temperature (10 bit value with -400 base)
* D = Checksum
* E = Humidity
*
* WS1200 Message Format: (7 bits preamble, 7 Bytes, 56 bits):
* AAAAAAA AAAABBBB BBBB__CC CCCCCCCC DDDDDDDD DDDDDDDD EEEEEEEE FFFFFFFF
* Temperature Rain LSB Rain MSB ???????? Checksum
* A = start/unknown, first 8 bits are always 11111111
* B = Rolling code
* C = Temperature (10 bit value with -400 base)
* D = Rain ( * 0.3 mm)
* E = ?
* F = Checksum
AAAAAAA AAAABBBB BBBBCCCC CCCCCCCC DDDDDDDD DDDDDDDD EEEEEEEE FFFFFFFF
1111111 00111010 01010010 10000010 00000000 00000000 11111111 10111010 1 24,2 gr 0 mm
1111111 00111010 01010010 10000010 00000001 00000000 11111111 11111100 0 24,2 gr 0,3 mm
1111111 00111010 01010010 10000010 00000010 00000000 11111111 00110110 0 24,2 gr 0,6 mm
1111111 00111010 01010010 10000010 00001000 00000000 11111111 11101000 1 24,2 gr 2,4 mm
1111111 00111010 01010010 10000010 00001101 00000000 11111111 10000111 0 24,2 gr 3.9 mm
1111111 00111010 01010010 01110001 00001101 00000000 11111111 01000010 0 22,5 gr 3,9 mm
1111111 00111010 01010010 01010111 00001101 00000000 11111111 00111011 1 19,9 gr 3,9 mm
1111111 00111010 01010010 00111110 00010010 00000000 11111111 00111001 1 17,4 gr 5,4 mm
1111111 00111010 01010010 00101000 00010010 00000000 11111111 00001000 0 15,2 gr 5,4 mm
1111111 00111010 01010001 00101011 10011010 00000001 11111111 10100011 -10,1 gr/123,0 mm
WS1200 temp:-101
WS1200 rain LSB:154
WS1200 rain MSB:1
WS1200 rain:1230
1111111 00111010 01010001 10101101 10011111 00000001 11111111 00110100 2,9 gr/124,5mm
WS1200 temp:29
WS1200 rain LSB:159
WS1200 rain MSB:1
WS1200 rain:1245
* 20;AE;DEBUG;Pulses=126;Pulses(uSec)=900,950,825,450,325,450,325,950,325,450,325,450,825,950,825,450,325,950,825,450,350,950,325,450,825,950,825,450,325,450,325,950,825,925,350,450,825,950,825,925,350,450,825,450,350,925,825,450,350,450,325,950,350,450,825,950,325,450,350,450,325,450,825,450,325,450,325,450,325,450,325,950,825,950,325,450,825,950,325,450,825,450,325,950,325,450,325,450,825,925,350,450,350,450,825,950,825,925,350,425,350,450,350,450,350,450,350,450,825,950,825,950,325,450,350,450,825,950,825,950,825,950,325,450,325;
* 20;AF;Alecto V3;ID=009a;TEMP=ffe7;RAIN=7a;
\*********************************************************************************************/
#define WS1100_PULSECOUNT 94
#define WS1200_PULSECOUNT 126
#define ALECTOV3_PULSEMID 300/RAWSIGNAL_SAMPLE_RATE
#ifdef PLUGIN_031
uint8_t Plugin_031_ProtocolAlectoCRC8( uint8_t *addr, uint8_t len);
unsigned int Plugin_031_ProtocolAlectoRainBase=0;
boolean Plugin_031(byte function, char *string) {
if ((RawSignal.Number != WS1100_PULSECOUNT) && (RawSignal.Number != WS1200_PULSECOUNT)) return false;
unsigned long bitstream1=0L;
unsigned long bitstream2=0L;
byte rc=0;
int temperature=0;
byte humidity=0;
unsigned int rain=0;
byte checksum=0;
byte checksumcalc=0;
byte data[6];
//==================================================================================
for (byte x=15; x<=77; x=x+2) { // get first 32 relevant bits
if (RawSignal.Pulses[x] < ALECTOV3_PULSEMID) {
bitstream1 = (bitstream1 << 1) | 0x1;
} else {
bitstream1 = (bitstream1 << 1);
}
}
for (byte x=79; x<=141; x=x+2) { // get second 32 relevant bits
if (RawSignal.Pulses[x] < ALECTOV3_PULSEMID) {
bitstream2 = (bitstream2 << 1) | 0x1;
} else {
bitstream2 = (bitstream2 << 1);
}
}
//==================================================================================
if (bitstream1 == 0) return false; // Sanity check
data[0] = (bitstream1 >> 24) & 0xff; // Sort data
data[1] = (bitstream1 >> 16) & 0xff;
data[2] = (bitstream1 >> 8) & 0xff;
data[3] = (bitstream1 >> 0) & 0xff;
data[4] = (bitstream2 >> 24) & 0xff;
data[5] = (bitstream2 >> 16) & 0xff;
// ----------------------------------
if (RawSignal.Number == WS1200_PULSECOUNT) { // verify checksum
checksum = (bitstream2 >> 8) & 0xff;
checksumcalc = Plugin_031_ProtocolAlectoCRC8(data, 6);
} else {
checksum = (bitstream2 >> 24) & 0xff;
checksumcalc = Plugin_031_ProtocolAlectoCRC8(data, 4);
}
if (checksum != checksumcalc) return false;
// ----------------------------------
rc = (bitstream1 >> 20) & 0xff;
temperature = ((bitstream1 >> 8) & 0x3ff); // 299=12b -400 (0x190) = FF9b
//temperature = ((bitstream1 >> 8) & 0x3ff) - 400; // 299=12b -400 (0x190) = FF9b
if (temperature < 400) { // negative temperature value
temperature = 400 - temperature;
temperature=temperature | 0x8000; // turn highest bit on for minus values
} else {
if (temperature > 0x258) return false; // temperature out of range ( > 60.0 degrees)
}
//==================================================================================
// Output
// ----------------------------------
sprintf(pbuffer, "20;%02X;", PKSequenceNumber++); // Node and packet number
Serial.print( pbuffer );
// ----------------------------------
Serial.print(F("Alecto V3;")); // Label
sprintf(pbuffer, "ID=00%02x;", rc); // ID
Serial.print( pbuffer );
sprintf(pbuffer, "TEMP=%04x;", temperature);
Serial.print( pbuffer );
if (RawSignal.Number == WS1100_PULSECOUNT) {
humidity = bitstream1 & 0xff; // alleen op WS1100?
sprintf(pbuffer, "HUM=%02x;", humidity);
Serial.print( pbuffer );
} else {
rain = (((bitstream2 >> 24) & 0xff) * 256) + ((bitstream1 >> 0) & 0xff);
// check if rain unit has been reset!
if (rain < Plugin_031_ProtocolAlectoRainBase) Plugin_031_ProtocolAlectoRainBase=rain;
if (Plugin_031_ProtocolAlectoRainBase > 0) {
//UserVar[basevar+1 -1] += ((float)rain - Plugin_031_ProtocolAlectoRainBase) * 0.30;
sprintf(pbuffer, "RAIN=%02x;", (rain)&0xff);
Serial.print( pbuffer );
}
Plugin_031_ProtocolAlectoRainBase = rain;
}
Serial.println();
//==================================================================================
RawSignal.Repeats=true; // suppress repeats of the same RF packet
RawSignal.Number=0; // do not process the packet any further
return true;
}
/*********************************************************************************************\
* Calculates CRC-8 checksum
* reference http://lucsmall.com/2012/04/29/weather-station-hacking-part-2/
* http://lucsmall.com/2012/04/30/weather-station-hacking-part-3/
* https://github.com/lucsmall/WH2-Weather-Sensor-Library-for-Arduino/blob/master/WeatherSensorWH2.cpp
\*********************************************************************************************/
uint8_t Plugin_031_ProtocolAlectoCRC8( uint8_t *addr, uint8_t len)
{
uint8_t crc = 0;
// Indicated changes are from reference CRC-8 function in OneWire library
while (len--) {
uint8_t inbyte = *addr++;
for (uint8_t i = 8; i; i--) {
uint8_t mix = (crc ^ inbyte) & 0x80; // changed from & 0x01
crc <<= 1; // changed from right shift
if (mix) crc ^= 0x31;// changed from 0x8C;
inbyte <<= 1; // changed from right shift
}
}
return crc;
}
#endif // PLUGIN_031