static int thermopro_tp12_sensor_callback(bitbuffer_t *bitbuffer) {
    int iTemp1, iTemp2, good = -1;
    float fTemp1, fTemp2;
    uint8_t *bytes;
    unsigned int device, value;
    char time_str[LOCAL_TIME_BUFLEN];
    data_t *data;

    // The device transmits 16 rows, let's check for 3 matching.
    // (Really 17 rows, but the last one doesn't match because it's missing a trailing 1.)
    good = bitbuffer_find_repeated_row(bitbuffer, 5, 40);
    if (good < 0) {
        return 0;
    }

    bytes = bitbuffer->bb[good];
    if (!bytes[0] && !bytes[1] && !bytes[2] && !bytes[3]) {
        return 0; // reduce false positives
    }

    // Note: the device ID changes randomly each time you replace the battery, so we can't early out based on it.
    // This is probably to allow multiple devices to be used at once.  When you replace the receiver batteries
    // or long-press its power button, it pairs with the first device ID it hears.
    device = bytes[0];

    if(debug_output) {
        // There is a mysterious checksum in bytes[4].  It may be the same as the checksum used by the TP-11,
        // which consisted of a lookup table containing, for each bit in the message, a byte to be xor-ed into
        // the checksum if the message bit was 1.  It should be possible to solve for that table using Gaussian
        // elimination, so dump some data so we can try this.

        // This format is easily usable by bruteforce-crc, after piping through | grep raw_data | cut -d':' -f2 
        // bruteforce-crc didn't find anything, though - this may not be a CRC algorithm specifically.
        fprintf(stderr,"thermopro_tp12_raw_data:");
        for(int bit_index = 0; bit_index < 40; ++bit_index){
            fputc(bitrow_get_bit(bytes, bit_index) + '0', stderr);
        }
        fputc('\n', stderr);
    }

    iTemp1 = ((bytes[2] & 0xf0) << 4) | bytes[1];
    iTemp2 = ((bytes[2] & 0x0f) << 8) | bytes[3];

    fTemp1 = (iTemp1 - 200) / 10.;
    fTemp2 = (iTemp2 - 200) / 10.;

    local_time_str(0, time_str);
    data = data_make("time",          "",            DATA_STRING, time_str,
                     "model",         "",            DATA_STRING, MODEL,
                     "id",            "Id",          DATA_FORMAT, "\t %d",   DATA_INT,    device,
                     "temperature_1_C", "Temperature 1 (Food)", DATA_FORMAT, "%.01f C", DATA_DOUBLE, fTemp1,
                     "temperature_2_C", "Temperature 2 (Barbecue)", DATA_FORMAT, "%.01f C", DATA_DOUBLE, fTemp2,
                     NULL);
    data_acquired_handler(data);
    return 1;
}
Example #2
0
static int lightwave_rf_callback(bitbuffer_t *bitbuffer) {
	bitrow_t *bb = bitbuffer->bb;

	// Validate package
	// Transmitted pulses are always 72
	// Pulse 72 (delimiting "1" is not demodulated, as gap becomes End-Of-Message - thus expected length is 71
	if ((bitbuffer->bits_per_row[0] == 71)
		&& (bitbuffer->num_rows == 1))		// There should be only one message (and we use the rest...)
	{
		// Polarity is inverted
		bitbuffer_invert(bitbuffer);

		// Expand all "0" to "10" (bit stuffing)
		// row_in = 0, row_out = 1
		bitbuffer_add_row(bitbuffer);
		for (unsigned n=0; n < bitbuffer->bits_per_row[0]; ++n) {
			if (bitrow_get_bit(bb[0], n)) {
				bitbuffer_add_bit(bitbuffer, 1);
			} else {
				bitbuffer_add_bit(bitbuffer, 1);
				bitbuffer_add_bit(bitbuffer, 0);
			}
		}

		// Check length is correct
		// Due to encoding there will be two "0"s per byte, thus message grows to 91 bits
		if (bitbuffer->bits_per_row[1] != 91)	return 0;

		// Check initial delimiter bit is "1"
		unsigned bit_idx = 0;
		uint8_t delimiter_bit = bitrow_get_bit(bb[1], bit_idx++);
		if (delimiter_bit == 0)	return 0;	// Decode error

		// Strip delimiter bits
		// row_in = 1, row_out = 2
		bitbuffer_add_row(bitbuffer);
		for(unsigned n=0; n<10; ++n) {		// We have 10 bytes
			delimiter_bit = bitrow_get_bit(bb[1], bit_idx++);
			if (delimiter_bit == 0)	return 0;	// Decode error

			for(unsigned m=0; m<8; ++m) {
				bitbuffer_add_bit(bitbuffer, bitrow_get_bit(bb[1], bit_idx++));
			}
		}
		// Final delimiter bit will be missing - so do not check...

		// Decode bytes to nibbles
		// row_in = 2, row_out = 3
		bitbuffer_add_row(bitbuffer);
		for(unsigned n=0; n<10; ++n) {		// We have 10 bytes/nibbles
			int nibble = lightwave_rf_nibble_from_byte(bb[2][n]);
			if (nibble < 0) {
				if (debug_output) {
					fprintf(stderr, "LightwaveRF. Nibble decode error %X, idx: %u\n", bb[2][n], n);
					bitbuffer_print(bitbuffer);
				}
				return 0;	// Decode error
			}
			for (unsigned m=0; m<4; ++m) {	// Add nibble one bit at a time...
				bitbuffer_add_bit(bitbuffer, (nibble & (8 >> m)) >> (3-m));
			}
		}

		// Print out generic decode
		// Decoded nibbles are in row 3
		fprintf(stdout, "LightwaveRF:\n");
		fprintf(stdout, "ID = 0x%X%X%X\n", bb[3][2], bb[3][3], bb[3][4]);
		fprintf(stdout, "Subunit = %u\n", (bb[3][1] & 0xF0) >> 4);
		fprintf(stdout, "Command = %u\n", bb[3][1] & 0x0F);
		fprintf(stdout, "Parameter = %u\n", bb[3][0]);

		if (debug_output) {
			bitbuffer_print(bitbuffer);
			fprintf(stderr, "  Row 0 = Input, Row 1 = Zero bit stuffing, Row 2 = Stripped delimiters, Row 3 = Decoded nibbles\n");
		}


		return 1;
	}