Exemple #1
0
static int elro_db286a_callback(r_device *decoder, bitbuffer_t *bitbuffer)
{
    data_t *data;
    uint8_t *b;
    char id_str[4*2+1];

    // 33 bits expected, 5 minimum packet repetitions (14 expected)
    int row = bitbuffer_find_repeated_row(bitbuffer, 5, 33);

    if (row < 0 || bitbuffer->bits_per_row[row] != 33)
        return 0;

    b = bitbuffer->bb[row];

    // 32 bits, trailing bit is dropped
    sprintf(id_str, "%02x%02x%02x%02x", b[0], b[1], b[2], b[3]);

    data = data_make(
            "model",    "",        DATA_STRING, "Elro-DB286A",
            "id",       "ID",      DATA_STRING, id_str,
            NULL);

    decoder_output_data(decoder, data);

    return 1;

}
Exemple #2
0
static int thermopro_tp11_sensor_callback(r_device *decoder, bitbuffer_t *bitbuffer) {
    int temp_raw, row;
    float temp_c;
    bitrow_t *bb = bitbuffer->bb;
    unsigned int device, value;
    data_t *data;

    // Compare first four bytes of rows that have 32 or 33 bits.
    row = bitbuffer_find_repeated_row(bitbuffer, 2, 32);
    if (row < 0)
        return 0;

    if (bitbuffer->bits_per_row[row] > 33)
        return 0;

    value = (bb[row][0] << 16) + (bb[row][1] << 8) + bb[row][2];
    device = value >> 12;

    // Validate code for known devices.
    if ((device == 0xb34 || device == 0xdb4 ) && !valid(value, bb[row][3]))
        return 0;

    temp_raw = value & 0xfff;
    temp_c = (temp_raw - 200) / 10.;

    data = data_make(
            "model",         "",            DATA_STRING, _X("Thermopro-TP11","Thermopro TP11 Thermometer"),
            "id",            "Id",          DATA_INT,    device,
            "temperature_C", "Temperature", DATA_FORMAT, "%.01f C", DATA_DOUBLE, temp_c,
            NULL);
    decoder_output_data(decoder, data);
    return 1;
}
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;
}
Exemple #4
0
static int maverick_et73_sensor_callback(r_device *decoder, bitbuffer_t *bitbuffer) {
    int temp1_raw, temp2_raw, row;
    float temp1_c, temp2_c;
    uint8_t *bytes;
    unsigned int device;
    data_t *data;

    // The device transmits many rows, let's check for 3 matching.
    row = bitbuffer_find_repeated_row(bitbuffer, 3, 48);
    if (row < 0) {
        return 0;
    }

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

    if (bitbuffer->bits_per_row[row] != 48)
        return 0;

    device = bytes[0];

    if (decoder->verbose) {
        fprintf(stderr,"maverick_et73_raw_data:");
        bitrow_print(bytes, 48);
    }

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

    temp1_c = temp1_raw * 0.1;
    temp2_c = temp2_raw * 0.1;

    data = data_make(
            "model",            "",                 DATA_STRING, "Maverick ET73",
            "rid",              "Random Id",        DATA_INT, device,
            "temperature_1_C",  "Temperature 1",    DATA_FORMAT, "%.01f C", DATA_DOUBLE, temp1_c,
            "temperature_2_C",  "Temperature 2",    DATA_FORMAT, "%.01f C", DATA_DOUBLE, temp2_c,
            NULL);
    decoder_output_data(decoder, data);
    return 1;
}
Exemple #5
0
static int nexus_callback(bitbuffer_t *bitbuffer) {
    bitrow_t *bb = bitbuffer->bb;
    data_t *data;

    char time_str[LOCAL_TIME_BUFLEN];

    if (debug_output > 1) {
       fprintf(stderr,"Possible Nexus: ");
       bitbuffer_print(bitbuffer);
    }

    uint8_t id;
    uint8_t channel;
    int16_t temp;
    uint8_t humidity;
    int r = bitbuffer_find_repeated_row(bitbuffer, 3, 36);

    /** The nexus protocol will trigger on rubicson data, so calculate the rubicson crc and make sure
      * it doesn't match. By guesstimate it should generate a correct crc 1/255% of the times.
      * So less then 0.5% which should be acceptable.
      */
    if (!rubicson_crc_check(bb) &&
        r >= 0 &&
        bitbuffer->bits_per_row[r] <= 37 && // we expect 36 bits but there might be a trailing 0 bit
        bb[r][0] != 0 &&
        bb[r][1] != 0 &&
        bb[r][2] != 0 &&
        bb[r][3] != 0) {

        /* Get time now */
        local_time_str(0, time_str);

        /* Nibble 0,1 contains id */
        id = bb[r][0];

        channel = (bb[r][1]&0x03) + 1;

        /* Nible 3,4,5 contains 12 bits of temperature
         * The temerature is signed and scaled by 10 */
        temp = (int16_t)((uint16_t)(bb[r][1] << 12) | (bb[r][2] << 4));
        temp = temp >> 4;
        humidity = (uint8_t)(((bb[r][3]&0x0F)<<4)|(bb[r][4]>>4));

        // Thermo
        if (bb[r][3] == 0xF0) {
        data = data_make("time",          "",            DATA_STRING, time_str,
                         "model",         "",            DATA_STRING, "Nexus Temperature",
                         "id",            "House Code",  DATA_INT, id,
                         "channel",       "Channel",     DATA_INT, channel,
                         "temperature_C", "Temperature", DATA_FORMAT, "%.02f C", DATA_DOUBLE, temp/10.0,
                         NULL);
        data_acquired_handler(data);
        }
        // Thermo/Hygro
        else {
        data = data_make("time",          "",            DATA_STRING, time_str,
                         "model",         "",            DATA_STRING, "Nexus Temperature/Humidity",
                         "id",            "House Code",  DATA_INT, id,
                         "channel",       "Channel",     DATA_INT, channel,
                         "temperature_C", "Temperature", DATA_FORMAT, "%.02f C", DATA_DOUBLE, temp/10.0,
                         "humidity",      "Humidity",    DATA_FORMAT, "%u %%", DATA_INT, humidity,
                         NULL);
        data_acquired_handler(data);
        }
        return 1;
    }