From b6dcecba3e7fd8947e066fbbded456bb8da5d3f3 Mon Sep 17 00:00:00 2001 From: "Christian W. Zuckschwerdt" Date: Wed, 28 Nov 2018 16:12:03 +0100 Subject: [PATCH] Change flex to use keys for all values (#885) --- rtl_433.example.conf | 14 ++-- src/devices/flex.c | 154 +++++++++++++++++++++++++++++++++---------- src/pulse_detect.c | 8 +-- 3 files changed, 130 insertions(+), 46 deletions(-) diff --git a/rtl_433.example.conf b/rtl_433.example.conf index ae6b72aa..9ab31cec 100644 --- a/rtl_433.example.conf +++ b/rtl_433.example.conf @@ -300,7 +300,7 @@ stop_after_successful_events false # "rows" : [{"len" : 25, "data" : "ebeaaa8"}, {"len" : 25, "data" : "ebeaaa8"}, # {"len" : 25, "data" : "ebeaaa8"}, {"len" : 25, "data" : "ebeaaa8"}]} # -#decoder Elro_DB270:OOK_PWM:300:930:11000:1500,repeats>=4,bits=25 +#decoder n=Elro_DB270,m=OOK_PWM,s=300,l=930,r=11000,g=1500,repeats>=4,bits=25 # Euroster 3000TX - programmable room thermostat # @@ -311,7 +311,7 @@ stop_after_successful_events false # {"time" : "2018-02-14 19:20:20", "model" : "Euroster_3000TX", "count" : 1, "num_rows" : 1, # "rows" : [{"len" : 32, "data" : "41150515"}]} # -#decoder Euroster_3000TX:OOK_MC_ZEROBIT:1000:0:4800,bits=32 +#decoder n=Euroster_3000TX,m=OOK_MC_ZEROBIT,s=1000,r=4800,bits=32 # Byron BY series door bell # @@ -320,27 +320,27 @@ stop_after_successful_events false # # Output sample: # {"time" : "@1.572864s", "model" : "doorbell#1", "count" : 25, "num_rows" : 25, "rows" : [{"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}, {"len" : 21, "data" : "e768c8"}]} -#decoder Byron_BY_Doorbell:OOK_PWM:500:1000:3300:1200,repeats>=4,bits=21,match={2}0x3 +#decoder n=Byron_BY_Doorbell,m=OOK_PWM,s=500,l=1000,r=3300,g=1200,repeats>=4,bits=21,match={2}0x3 # Kerui alarm system (PIR and door sensors) # short is 333 us # long is 972 us # packet gap 11000 us -#decoder Kerui:OOK_PWM:333:972:11000:1100,bits=25,invert,get={20}:state,get=@20:{4}:event:[10:pir 14:open 7:close 11:tamper 15:battery_low] +#decoder n=Kerui,m=OOK_PWM,s=333,l=972,r=11000,g=1100,bits=25,invert,get={20}:state,get=@20:{4}:event:[10:pir 14:open 7:close 11:tamper 15:battery_low] # Golden Security GS-WDS07 door and window sensor # short is 476 us + 1344 us # long is 1364 us + 448 us # packet gap 13972 us -#decoder gswds07:OOK_PWM:476:1364:15000:1600,bits>=24,bits<=25,invert +#decoder n=gswds07,m=OOK_PWM,s=476,l=1364,r=15000,g=1600,bits>=24,bits<=25,invert # Generic SCV2260 4-button remote (see rtl_433_tests/tests/generic_remote/01) # short is 472 us + 1412 us # long is 1428 us + 472 us -#decoder generic_remote_01:OOK_PWM:472:1428:1420:1700,bits=25,invert,match=13cd,get=@16:{8}:event:[192:arm 12:disarm 3:home 48:sos] +#decoder n=generic_remote_01,m=OOK_PWM,s=472,l=1428,r=1800,g=1600,bits=25,invert,match=13cd,get=@16:{8}:event:[192:arm 12:disarm 3:home 48:sos] # Generic PT2260 PIR (see rtl_433_tests/tests/PT2262/01) # short is 440 us + 1536 us # long is 1428 us + 548 us # packet gap 15348 us -#decoder pt2260_pir:OOK_PWM:440:1428:16000:1700,bits=25,invert,match=755555,countonly +#decoder n=pt2260_pir,m=OOK_PWM,s=440,l=1428,r=16000,g=1700,bits=25,invert,match=755555,countonly diff --git a/src/devices/flex.c b/src/devices/flex.c index d47d3086..b05bbc4b 100644 --- a/src/devices/flex.c +++ b/src/devices/flex.c @@ -218,7 +218,16 @@ static void help() { fprintf(stderr, "Use -X to add a flexible general purpose decoder.\n\n" - " is \"name:modulation:short:long:reset[,key=value...]\"\n" + " is \"key=value[,key=value...]\"\n" + "Common keys are:\n" + "\tname= (or: n=)\n" + "\tmodulation= (or: m=)\n" + "\tshort= (or: s=)\n" + "\tlong= (or: l=)\n" + "\tsync= (or: y=)\n" + "\treset= (or: r=)\n" + "\tgap= (or: g=)\n" + "\ttolerance= (or: t=)\n" "where:\n" " can be any descriptive name tag you need in the output\n" " is one of:\n" @@ -233,7 +242,7 @@ static void help() "\tFSK_PCM : FSK Pulse Code Modulation\n" "\tFSK_PWM : FSK Pulse Width Modulation\n" "\tFSK_MC_ZEROBIT : Manchester Code with fixed leading zero bit\n" - ", , and are the timings for the decoder in µs\n" + ", , , and are the timings for the decoder in µs\n" "PCM short: Nominal width of pulse [us]\n" " long: Nominal width of bit period [us]\n" "PPM_RAW short: Threshold between short and long gap [us]\n" @@ -241,11 +250,10 @@ static void help() "PWM short: Nominal width of '1' pulse [us]\n" " long: Nominal width of '0' pulse [us]\n" " gap: Maximum gap size before new row of bits [us]\n" + " sync: Nominal width of sync pulse [us] (optional)\n" + " tolerance: Maximum pulse deviation [us] (optional)\n" "reset: Maximum gap size before End Of Message [us].\n" - "for PWM use short:long:reset:gap[:tolerance[:syncwidth]]\n" - "for DMC use short:long:reset:tolerance\n" "Available options are:\n" - "\tdemod= : the demod argument needed for some modulations\n" "\tbits= : only match if at least one row has bits\n" "\trows= : only match if there are rows\n" "\trepeats= : only match if some row is repeated times\n" @@ -255,10 +263,41 @@ static void help() "\tpreamble= : match and align at the preamble\n" "\t\t is a row spec of {}\n" "\tcountonly : suppress detailed row output\n\n" - "E.g. -X \"doorbell:OOK_PWM:400:800:7000:1000,match={24}0xa9878c,repeats>=3\"\n\n"); + "E.g. -X \"n=doorbell,m=OOK_PWM,s=400,l=800,r=7000,g=1000,match={24}0xa9878c,repeats>=3\"\n\n"); exit(0); } +static unsigned parse_modulation(char const *str) +{ + if (!strcasecmp(str, "OOK_MC_ZEROBIT")) + return OOK_PULSE_MANCHESTER_ZEROBIT; + else if (!strcasecmp(str, "OOK_PCM")) + return OOK_PULSE_PCM_RZ; + else if (!strcasecmp(str, "OOK_PPM_RAW")) + return OOK_PULSE_PPM_RAW; + else if (!strcasecmp(str, "OOK_PWM")) + return OOK_PULSE_PWM; + else if (!strcasecmp(str, "OOK_DMC")) + return OOK_PULSE_DMC; + else if (!strcasecmp(str, "OOK_PIWM_RAW")) + return OOK_PULSE_PIWM_RAW; + else if (!strcasecmp(str, "OOK_PIWM_DC")) + return OOK_PULSE_PIWM_DC; + else if (!strcasecmp(str, "OOK_MC_OSV1")) + return OOK_PULSE_PWM_OSV1; + else if (!strcasecmp(str, "FSK_PCM")) + return FSK_PULSE_PCM; + else if (!strcasecmp(str, "FSK_PWM")) + return FSK_PULSE_PWM; + else if (!strcasecmp(str, "FSK_MC_ZEROBIT")) + return FSK_PULSE_MANCHESTER_ZEROBIT; + else { + fprintf(stderr, "Bad flex spec, unknown modulation!\n"); + usage(); + } + return 0; +} + #define FLEX_SLOTS 8 static struct flex_params *params_slot[FLEX_SLOTS]; static int cb_slot0(r_device *decoder, bitbuffer_t *bitbuffer) { return flex_callback(decoder, bitbuffer, params_slot[0]); } @@ -383,42 +422,25 @@ r_device *flex_create_device(char *spec) fprintf(stderr, "Bad flex spec, missing name!\n"); usage(); } - params->name = strdup(c); + if (!strncasecmp(c, "n=", 2)) + c += 2; + if (!strncasecmp(c, "name=", 5)) + c += 5; + params->name = strdup(c); int name_size = strlen(c) + 27; dev->name = malloc(name_size); snprintf(dev->name, name_size, "General purpose decoder '%s'", c); c = strtok(NULL, ":"); + if (c != NULL) { + // old style spec, DEPRECATED + fprintf(stderr, "\nYou are using the deprecated positional flex spec, please read \"-X help\" and change your spec!\n\n"); + if (c == NULL) { fprintf(stderr, "Bad flex spec, missing modulation!\n"); usage(); } - if (!strcasecmp(c, "OOK_MC_ZEROBIT")) - dev->modulation = OOK_PULSE_MANCHESTER_ZEROBIT; - else if (!strcasecmp(c, "OOK_PCM")) - dev->modulation = OOK_PULSE_PCM_RZ; - else if (!strcasecmp(c, "OOK_PPM_RAW")) - dev->modulation = OOK_PULSE_PPM_RAW; - else if (!strcasecmp(c, "OOK_PWM")) - dev->modulation = OOK_PULSE_PWM; - else if (!strcasecmp(c, "OOK_DMC")) - dev->modulation = OOK_PULSE_DMC; - else if (!strcasecmp(c, "OOK_PIWM_RAW")) - dev->modulation = OOK_PULSE_PIWM_RAW; - else if (!strcasecmp(c, "OOK_PIWM_DC")) - dev->modulation = OOK_PULSE_PIWM_DC; - else if (!strcasecmp(c, "OOK_MC_OSV1")) - dev->modulation = OOK_PULSE_PWM_OSV1; - else if (!strcasecmp(c, "FSK_PCM")) - dev->modulation = FSK_PULSE_PCM; - else if (!strcasecmp(c, "FSK_PWM")) - dev->modulation = FSK_PULSE_PWM; - else if (!strcasecmp(c, "FSK_MC_ZEROBIT")) - dev->modulation = FSK_PULSE_MANCHESTER_ZEROBIT; - else { - fprintf(stderr, "Bad flex spec, unknown modulation!\n"); - usage(); - } + dev->modulation = parse_modulation(c); c = strtok(NULL, ":"); if (c == NULL) { @@ -473,12 +495,29 @@ r_device *flex_create_device(char *spec) dev->tolerance = atoi(c); } - dev->decode_fn = callback_slot[next_slot]; + } // DEPRECATED + + dev->decode_fn = callback_slot[next_slot]; dev->fields = output_fields; char *key, *val; while (getkwargs(&args, &key, &val)) { - if (!strcasecmp(key, "bits>")) + if (!strcasecmp(key, "m") || !strcasecmp(key, "modulation")) + dev->modulation = parse_modulation(val); + else if (!strcasecmp(key, "s") || !strcasecmp(key, "short")) + dev->short_limit = atoi(val); + else if (!strcasecmp(key, "l") || !strcasecmp(key, "long")) + dev->long_limit = atoi(val); + else if (!strcasecmp(key, "y") || !strcasecmp(key, "sync")) + dev->sync_width = atoi(val); + else if (!strcasecmp(key, "g") || !strcasecmp(key, "gap")) + dev->gap_limit = atoi(val); + else if (!strcasecmp(key, "r") || !strcasecmp(key, "reset")) + dev->reset_limit = atoi(val); + else if (!strcasecmp(key, "t") || !strcasecmp(key, "tolerance")) + dev->tolerance = atoi(val); + + else if (!strcasecmp(key, "bits>")) params->min_bits = val ? atoi(val) : 0; else if (!strcasecmp(key, "bits<")) params->max_bits = val ? atoi(val) : 0; @@ -531,6 +570,51 @@ r_device *flex_create_device(char *spec) if (params->min_bits > 0 && params->min_repeats < 1) params->min_repeats = 1; + // sanity checks + + if (!params->name || !*params->name) { + fprintf(stderr, "Bad flex spec, missing name!\n"); + usage(); + } + + if (!dev->modulation) { + fprintf(stderr, "Bad flex spec, missing modulation!\n"); + usage(); + } + + if (!dev->short_limit) { + fprintf(stderr, "Bad flex spec, missing short limit!\n"); + usage(); + } + + if (dev->modulation != OOK_PULSE_MANCHESTER_ZEROBIT) { + if (!dev->long_limit) { + fprintf(stderr, "Bad flex spec, missing long limit!\n"); + usage(); + } + } + + if (!dev->reset_limit) { + fprintf(stderr, "Bad flex spec, missing reset limit!\n"); + usage(); + } + + if (dev->modulation == OOK_PULSE_PWM) { + if (!dev->gap_limit) { + fprintf(stderr, "Bad flex spec, missing gap limit!\n"); + usage(); + } + } + + if (dev->modulation == OOK_PULSE_DMC + || dev->modulation == OOK_PULSE_PIWM_RAW + || dev->modulation == OOK_PULSE_PIWM_DC) { + if (!dev->tolerance) { + fprintf(stderr, "Bad flex spec, missing tolerance limit!\n"); + usage(); + } + } + /* if (decoder->verbose) { fprintf(stderr, "Adding flex decoder \"%s\"\n", params->name); diff --git a/src/pulse_detect.c b/src/pulse_detect.c index 19e52c0d..89ec8b49 100644 --- a/src/pulse_detect.c +++ b/src/pulse_detect.c @@ -682,25 +682,25 @@ void pulse_analyzer(pulse_data_t *data, uint32_t samp_rate) device.s_reset_limit*to_us, device.s_sync_width*to_us); switch(device.modulation) { case FSK_PULSE_PCM: - fprintf(stderr, "Use a flex decoder with -X name:FSK_PCM:%.0f:%.0f:%.0f\n", + fprintf(stderr, "Use a flex decoder with -X 'n=name,m=FSK_PCM,s=%.0f,l=%.0f,r=%.0f'\n", device.s_short_limit*to_us, device.s_long_limit*to_us, device.s_reset_limit*to_us); pulse_demod_pcm(data, &device); break; case OOK_PULSE_PPM_RAW: - fprintf(stderr, "Use a flex decoder with -X name:OOK_PPM_RAW:%.0f:%.0f:%.0f\n", + fprintf(stderr, "Use a flex decoder with -X 'n=name,m=OOK_PPM_RAW,s=%.0f,l=%.0f,r=%.0f'\n", device.s_short_limit*to_us, device.s_long_limit*to_us, device.s_reset_limit*to_us); data->gap[data->num_pulses-1] = device.s_reset_limit + 1; // Be sure to terminate package pulse_demod_ppm(data, &device); break; case OOK_PULSE_PWM: - fprintf(stderr, "Use a flex decoder with -X name:OOK_PWM:%.0f:%.0f:%.0f:%.0f:%.0f:%.0f\n", + fprintf(stderr, "Use a flex decoder with -X 'n=name,m=OOK_PWM,s=%.0f,l=%.0f,r=%.0f,g=%.0f,t=%.0f,y=%.0f'\n", device.s_short_limit*to_us, device.s_long_limit*to_us, device.s_reset_limit*to_us, device.s_gap_limit*to_us, device.s_tolerance*to_us, device.s_sync_width*to_us); data->gap[data->num_pulses-1] = device.s_reset_limit + 1; // Be sure to terminate package pulse_demod_pwm(data, &device); break; case OOK_PULSE_MANCHESTER_ZEROBIT: - fprintf(stderr, "Use a flex decoder with -X name:OOK_MC_ZEROBIT:%.0f:%.0f:%.0f\n", + fprintf(stderr, "Use a flex decoder with -X 'n=name,m=OOK_MC_ZEROBIT,s=%.0f,l=%.0f,r=%.0f'\n", device.s_short_limit*to_us, device.s_long_limit*to_us, device.s_reset_limit*to_us); data->gap[data->num_pulses-1] = device.s_reset_limit + 1; // Be sure to terminate package pulse_demod_manchester_zerobit(data, &device);