Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix home assistant discovery error for unique id "teddyCloud_Server_encode-stream_max_size" #272

Open
mraction opened this issue Dec 13, 2024 · 4 comments
Labels
bug Something isn't working fixed in develop

Comments

@mraction
Copy link

In my home assistant logs, I found this message:

2024-12-13 14:39:45.220 ERROR (MainThread) [homeassistant.components.mqtt.entity] Error ''max' must be > 'min'' when processing MQTT discovery message topic: 'homeassistant/number/teddyCloud_Server/encode-stream_max_size/config', message: '{'command_topic': 'teddyCloud/encode-stream_max_size/command', 'max': -2147483648, 'device': {'hw_version': 'linux x86_64', 'model': 'teddyCloud', 'configuration_url': 'http://localhost', 'sw_version': 'v0.6.2 (203f12d)', 'manufacturer': 'Team RevvoX', 'name': 'teddyCloud - Server', 'identifiers': 'teddyCloud_Server'}, 'unique_id': 'teddyCloud_Server_encode-stream_max_size', 'min': 1048575, 'name': "encode.stream_max_size - The box may create an empty file this length for each stream. So if you have 10 streaming tonies you use, the box may block 10*240MB. The only downside is, that the box will stop after the file is full and you'll need to replace the tag onto the box. Must not be a multiply of 4096, Default: 251.658.239, so 240MB, which means around 6h.", 'availability_topic': 'teddyCloud/status', 'state_topic': 'teddyCloud/encode-stream_max_size/status'}'

Here is the formated json content:

{
   "command_topic":"teddyCloud/encode-stream_max_size/command",
   "max":-2147483648,
   "device":{
      "hw_version":"linux x86_64",
      "model":"teddyCloud",
      "configuration_url":"http://localhost",
      "sw_version":"v0.6.2 (203f12d)",
      "manufacturer":"Team RevvoX",
      "name":"teddyCloud - Server",
      "identifiers":"teddyCloud_Server"
   },
   "unique_id":"teddyCloud_Server_encode-stream_max_size",
   "min":1048575,
   "name":"encode.stream_max_size - The box may create an empty file this length for each stream. So if you have 10 streaming tonies you use, the box may block 10*240MB. The only downside is, that the box will stop after the file is full and you'll need to replace the tag onto the box. Must not be a multiply of 4096, Default: 251.658.239, so 240MB, which means around 6h.",
   "availability_topic":"teddyCloud/status",
   "state_topic":"teddyCloud/encode-stream_max_size/status"
}

As we can see, the error is correct, becaus max is a greate negative number. :-(

I searched a bit in the code, but I'm not sure which is the best solution, so I decided to create an issue in the hope that someone can fix it fast based on my research. ;-)

The bacis values are set here:

OPTION_UNSIGNED("encode.stream_max_size", &settings->encode.stream_max_size, 1024 * 1024 * 40 * 6 - 1, 1024 * 1024 - 1, INT32_MAX, "Max stream filesize", "The box may create an empty file this length for each stream. So if you have 10 streaming tonies you use, the box may block 10*240MB. The only downside is, that the box will stop after the file is full and you'll need to replace the tag onto the box. Must not be a multiply of 4096, Default: 251.658.239, so 240MB, which means around 6h.", LEVEL_EXPERT)

It's stored an a uint64_t type variable by that macro.
After that it's copied into a float variable here:
entity.max = s->max.unsigned_value;

While sending it via mqtt, it's converted to int:
ha_addint(json_obj, "max", ha_info->entities[pos].max);

And then into double by the following cJSON_AddNumberToObject call.

The problem is the conversion step from float to int as you can see by this small example code:

#include <stdio.h>
#include <stdint.h>

int main() {
    uint64_t start = INT32_MAX;
    float step1 = start;
    int step2 = step1;

    printf("UINT64 => %lu\n", start);
    printf("FLOAT => %f\n", step1);
    printf("INT => %d\n", step2);

    return 0;
}

Output:

UINT64 => 2147483647
FLOAT => 2147483648.000000
INT => -2147483648

I would suggest to use ha_addfloat and not ha_addint here (and also for min in the line above):

ha_addint(json_obj, "max", ha_info->entities[pos].max);

But I'm not sure if it's ok for every entity!

I hope my investigation is helpfull. ;-)

@henryk86 henryk86 added bug Something isn't working fixed in develop labels Dec 23, 2024
@henryk86
Copy link
Collaborator

henryk86 commented Dec 23, 2024

Should be fixed by @g3gg0 : f095ee7

@mraction
Copy link
Author

mraction commented Dec 23, 2024

@henryk86 I think, it's not a fix - it's a new potentially bug. I will describe it in a second issue. ;-)

There is a new min/max check added - that's basically ok, but would not fix this bug, because the value is used as float and will pass the check but it's still casted into int after that.

I tested it with my small example code above and it comfirmes that:

#include <stdio.h>
#include <stdint.h>

static int32_t coerce_int32(float value, int32_t min, int32_t max)
{
    if (value >= max)
    {
        return max;
    }
    if (value <= min)
    {
        return min;
    }
    return value;
}

int main() {
    uint64_t start = INT32_MAX;
    float step1 = start;
    int32_t step1a = coerce_int32(step1, INT32_MIN, INT32_MAX);
    int step2 = step1;

    printf("UINT64 => %lu\n", start);
    printf("FLOAT => %f\n", step1);
    printf("RANGE CHECK => %d\n", step1a);
    printf("INT => %d\n", step2);

    return 0;
}

Output:

UINT64 => 2147483647
FLOAT => 2147483648.000000
RANGE CHECK => 2147483647
INT => -2147483648

@henryk86
Copy link
Collaborator

@g3gg0 see above

@mraction
Copy link
Author

@henryk86 You are faster then I - I linked him also in #277 . But that's only a potentially bug for future changes. :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working fixed in develop
Projects
None yet
Development

No branches or pull requests

2 participants