Change flex to use keys for all values (#885)

This commit is contained in:
Christian W. Zuckschwerdt
2018-11-28 16:12:03 +01:00
committed by GitHub
parent 8551696cc9
commit b6dcecba3e
3 changed files with 130 additions and 46 deletions

View File

@@ -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

View File

@@ -218,7 +218,16 @@ static void help()
{
fprintf(stderr,
"Use -X <spec> to add a flexible general purpose decoder.\n\n"
"<spec> is \"name:modulation:short:long:reset[,key=value...]\"\n"
"<spec> is \"key=value[,key=value...]\"\n"
"Common keys are:\n"
"\tname=<name> (or: n=<name>)\n"
"\tmodulation=<modulation> (or: m=<modulation>)\n"
"\tshort=<short> (or: s=<short>)\n"
"\tlong=<long> (or: l=<long>)\n"
"\tsync=<sync> (or: y=<sync>)\n"
"\treset=<reset> (or: r=<reset>)\n"
"\tgap=<gap> (or: g=<gap>)\n"
"\ttolerance=<tolerance> (or: t=<tolerance>)\n"
"where:\n"
"<name> can be any descriptive name tag you need in the output\n"
"<modulation> 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"
"<short>, <long>, and <reset> are the timings for the decoder in µs\n"
"<short>, <long>, <sync>, and <reset> 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=<n> : the demod argument needed for some modulations\n"
"\tbits=<n> : only match if at least one row has <n> bits\n"
"\trows=<n> : only match if there are <n> rows\n"
"\trepeats=<n> : only match if some row is repeated <n> times\n"
@@ -255,10 +263,41 @@ static void help()
"\tpreamble=<bits> : match and align at the <bits> preamble\n"
"\t\t<bits> is a row spec of {<bit count>}<bits as hex number>\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);

View File

@@ -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);