diff --git a/client/client_shared.c b/client/client_shared.c index 852fb7c0..2988b0d1 100644 --- a/client/client_shared.c +++ b/client/client_shared.c @@ -140,6 +140,12 @@ static int check_format(const char *str) #endif }else if(str[i+1] == 'x' || str[i+1] == 'X'){ /* payload in hex */ + }else if(str[i+1] == 'f' || str[i+1] == 'd'){ + /* payload in float */ +#ifndef __STDC_IEC_559__ + fprintf(stderr, "Error: Can't print float, missing __STDC_IEC_559__ standard support.\n"); + return 1; +#endif }else{ fprintf(stderr, "Error: Invalid format specifier '%c'.\n", str[i+1]); return 1; diff --git a/client/sub_client_output.c b/client/sub_client_output.c index ecda4236..a749caaf 100644 --- a/client/sub_client_output.c +++ b/client/sub_client_output.c @@ -422,6 +422,42 @@ static void formatted_print_blank(char pad, int field_width) } +#ifdef __STDC_IEC_559__ +static int formatted_print_float(const unsigned char *payload, int payloadlen, char format, char align, char pad, int field_width, int precision) +{ + float float_value; + double value; + if (format == 'f'){ + if (sizeof(float_value) != payloadlen) { + return -1; + } + memcpy(&float_value, payload, sizeof(float_value)); + value = float_value; + }else if(format == 'd'){ + if (sizeof(value) != payloadlen) { + return -1; + } + memcpy(&value, payload, sizeof(value)); + } + + if(field_width == 0) { + printf("%.*f", precision, value); + }else{ + if(align == '-'){ + printf("%-*.*f", field_width, precision, value); + }else{ + if(pad == '0'){ + printf("%0*.*f", field_width, precision, value); + }else{ + printf("%*.*f", field_width, precision, value); + } + } + } + return 0; +} +#endif + + static void formatted_print_int(int value, char align, char pad, int field_width) { if(field_width == 0){ @@ -651,6 +687,20 @@ static void formatted_print_percent(const struct mosq_config *lcfg, const struct case 'X': write_payload(message->payload, message->payloadlen, 2, align, pad, field_width, precision); break; + +#ifdef __STDC_IEC_559__ + case 'f': + if(formatted_print_float(message->payload, message->payloadlen, 'f', align, pad, field_width, precision)) { + err_printf(lcfg, "requested float printing, but non-float data received"); + } + break; + + case 'd': + if(formatted_print_float(message->payload, message->payloadlen, 'd', align, pad, field_width, precision)) { + err_printf(lcfg, "requested double printing, but non-double data received"); + } + break; +#endif } } diff --git a/man/mosquitto_sub.1.xml b/man/mosquitto_sub.1.xml index b4fd2260..4ce52123 100644 --- a/man/mosquitto_sub.1.xml +++ b/man/mosquitto_sub.1.xml @@ -927,12 +927,12 @@ mosquitto_sub -t 'bbc/#' -T bbc/bbc1 --remove-retained Flag characters - The parameters %A, %C, %E, %F, %I, %l, %m, %p, %R, %S, %t, %x, and %X can have optional flags immediately after the % character. + The parameters %A, %C, %E, %F, %I, %l, %m, %p, %R, %S, %t, %f, %d, %x, and %X can have optional flags immediately after the % character. The value should be zero padded. - This applies to the parameters %A, %E, %F, %l, %m, %S, %X, and %x. + This applies to the parameters %A, %E, %F, %l, %m, %S, %f, %d, %X, and %x. It will be ignored for other parameters. If used with the flag, the flag will be ignored. @@ -954,7 +954,7 @@ mosquitto_sub -t 'bbc/#' -T bbc/bbc1 --remove-retained option to set their field width in a similar way to regular printf style formats, i.e. this sets the minimum width when printing this parameter. This applies to the options %A, %C, - %E, %F, %I, %l, %m, %p, %R, %S, %t, %x, %X. + %E, %F, %I, %l, %m, %p, %R, %S, %t, %f, %d, %x, %X. For example would set the minimum topic @@ -977,6 +977,28 @@ mosquitto_sub -t 'bbc/#' -T bbc/bbc1 --remove-retained + + Floating point number printing consideration + + Mosquitto supports only IEEE754 floating point standard as + described in Annex F of ISO/IEC 9899:1999. Don't try to + use %f or %d if publisher's platform uses different + floating point representation standard than IEEE754 or you + will get invalid data. If you are unsure what floating + representation your platform is using, then it's most + likely IEEE754. If you get malformed and unexpected values, + check if float number in payload from publisher is encoded + in IEEE754. + + + If want to print floats, make sure you subscribe only + to topics that send only IEEE754 formatted floats. + Mosquitto is very strict about floats and if anything + that is not float is received, an error message will + be printed. + + + MQTT related parameters @@ -1000,6 +1022,8 @@ mosquitto_sub -t 'bbc/#' -T bbc/bbc1 --remove-retained the message topic. the payload with each byte as a hexadecimal number (lower case). the payload with each byte as a hexadecimal number (upper case). + the payload is treated as 4byte IEEE754 float. + the payload is treated as 8byte IEEE754 float (double).