Skip to content

Commit 0ede3a3

Browse files
committed
feat(proto): ✨ improve message disambiguation logic
Enhances message parsing by adding context parameters for better error reporting and thread-safe handling. Improves disambiguation of similar messages by comparing message names and provides detailed diagnostics when ambiguity remains.
1 parent 1e12733 commit 0ede3a3

1 file changed

Lines changed: 30 additions & 4 deletions

File tree

src/EcoFlow.Mqtt.Api/Extensions/ProtobufExtensions.cs

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ public string ToStringWithTitle()
2626

2727
extension(ByteString byteString)
2828
{
29-
public IMessage AsEcoFlowMessage()
29+
public IMessage AsEcoFlowMessage(int cmdFunc, int cmdId)
3030
{
3131
var sizes = new Dictionary<IMessage, int>();
3232
var messages = ProtobufMessages.Parsers
33+
.AsParallel()
3334
.Select(parser =>
3435
{
3536
IMessage? message = null;
@@ -44,12 +45,21 @@ public IMessage AsEcoFlowMessage()
4445
}
4546

4647
if (message is not null)
47-
sizes[message] = message.UnknownFields.CalculateSize();
48+
{
49+
var unknownFieldsSize = message.UnknownFields?.CalculateSize() ?? 0;
50+
51+
lock (sizes)
52+
sizes[message] = unknownFieldsSize;
53+
}
4854

4955
return message;
5056
})
5157
.WhereNotNull()
52-
.OrderBy(message => sizes[message]);
58+
.OrderBy(message =>
59+
{
60+
lock (sizes)
61+
return sizes[message];
62+
});
5363

5464
var candidates = messages.Take(2).ToArray();
5565

@@ -60,8 +70,24 @@ public IMessage AsEcoFlowMessage()
6070
return candidates[0];
6171

6272
if (sizes[candidates[0]] * 2 >= sizes[candidates[1]])
73+
{
74+
var size = sizes[candidates[0]];
75+
var sameSizeMessages = messages.TakeWhile(messages => sizes[messages] == size);
76+
var messageNames = sameSizeMessages.Select(message => message.GetType().Name.Split('.').Last());
77+
78+
/*
79+
0 => Ecoflow.Common.Proto.DevAplComm.DisplayPropertyUpload
80+
0 => Ecoflow.Common.Proto.DeviceSys.DisplayPropertyUpload
81+
0 => Ecoflow.EnergyStorageModule.Proto.Pd335Sys.DisplayPropertyUpload
82+
0 => Ecoflow.EnergyStorageModule.Proto.Pr705.DisplayPropertyUpload
83+
*/
84+
85+
if (messageNames.Distinct().Count() is 1)
86+
return candidates[0];
87+
6388
throw new InvalidOperationException($"Multiple messages could be parsed from the payload, and the best match is not significantly better than the second best match:\n" +
64-
$"{string.Join("\n", messages.Take(15).Select(message => $"{sizes[message]} => {message.GetType()}"))}");
89+
$"{string.Join("\n", messages.Take(15).Select(message => $"{sizes[message]} => {message.GetType()}"))}\ncmdFunc: {cmdFunc}, cmdId:{cmdId}\n{Convert.ToHexString(byteString.Span)}");
90+
}
6591

6692
return candidates[0];
6793
}

0 commit comments

Comments
 (0)