This is only the broadcaster side since the devices expected to reply are 3rd parties, but maybe enough to see where the problem is:
Mmm. I'm saw several potential problems (which all but one seem to be non-issues).
*) You are using port 1982 to broadcast a M-SEARCH discovery packet?
I thought these always needed to be on port 1900.
But according to this pdf it seems that you are dealing with non-standard SSDP protocol (which uses 1982 instead of 1900).
https://www.yeelight.com/download/Yeelight_Inter-Operation_Spec.pdf*) You bind to 0.0.0.0. I've never gotten listening on multiple interfaces for broadcast messages to work.
It's strange that it does work for you. I needed to change it to my local IP to receive anything.
Now for the possible reason of getting garbage and timeouts...
*) You have the SendString for BroadcastMessage inside the loop !!!
So you are sending the M-SEARCH every 1 second.
DON'T DO THAT.Only send once and let the devices have the opportunity to answer.
Now you are flooding the network with M-SEARCH messages, not waiting for an answer.
So your whole network ends up with answer over answer over answer.
Move the SendString outside the loop or wait at least 5 seconds before sending the string again.
You normally only need to send the string once and wait at least 3 second to get all the answers.
You can also add MX: 3 to ask the devices to answer within 3 seconds.
BTW. You can also increase the timeout in LConn.RecvPacket(ReceiveTimeoutMS);
If waiting is all you do in this code, you can just wait 5 seconds for a response.
If it times out then OK. If it receives a response you have a package.
But DON'T send the broadcast again until you are at least 5 seconds after the last one.
Also... In your code you do have the BroadcastIntervalMS. Even setting that to 5000 doesn't fix this issue.
When you have multiple light-bulbs... you only retrieve
one package at a time before waiting the 5 seconds.
Other (possible) packages build up in the buffer which come out in the next loop.
The whole flow is kinda messed up with all those sleep() intervals.
So it's better to build a separate loop which runs for 5 to 10 seconds in which you have the receive package.
The timeout for that recvpacket can be 3 (or even 5) seconds (because it doesn't matter if it waits that long at that point).
Sonething like:
WriteLn('Broadcasting...');
LConn.SendString(BroadcastMessage + #13#10);
while {check 5 seconds} do
begin
WriteLn('Waiting for response...');
LRawResponse := LConn.RecvPacket( {5 seconds} );
if Trim(LRawResponse) <> EmptyStr then begin
WriteLn(LRawResponse + LineEnding);
end;
end;
If the light-bulb is not found in the loop (note: you could find several) then you can loop that entire code (including sending the broadcast) again.