So I have several lists of type Tag. Tag has several properties: .Epc , .AntennaPortNumber, and .LastTimeSeen. I want to take all of the Tags from the main list, and sort them into 5 smaller lists, but only keep one copy of each .Epc and it must be the most recent .LastTimeSeen. I am not really sure where to even begin. I was thinking I must need to do something with .GroupBy nested a couple times? right now the code is split into two main parts: where I add new tags to the lists they belong in, and where I remove a tag that has not been seen for 500ms. I attempted to prevent duplicate tags from being added to the 5 sublists with .Contains, but because they have different LastTimeSeen properties this is not having the desired effect.
Thanks for any guidance anyone might be able to provide!
List<Tag> tags = new List<Tag>();
List<Tag> listMed1 = new List<Tag>();
List<Tag> listMed2 = new List<Tag>();
List<Tag> listMed3 = new List<Tag>();
List<Tag> listMed4 = new List<Tag>();
List<Tag> listMed5 = new List<Tag>();
void OnTagsReported(ImpinjReader sender, TagReport report)
{
// This event handler is called asynchronously
// when tag reports are available.
// Loop through each tag in the report
// and print the data.
//List<Tag> tags = new List<Tag>();
foreach (Tag tag in report)
{
ushort AntennaNum = tag.AntennaPortNumber;
Impinj.OctaneSdk.TagData first = tag.Epc;
string epcCheck = first.ToString().ToUpper();
Impinj.OctaneSdk.ImpinjTimestamp tim = tag.LastSeenTime;
if (epcCheck.IndexOf("A") != -1)
{
if (listMed1.Contains(tag) == false)
{
listMed1.Add(tag);
System. Diagnostics.Debug.WriteLine(epcCheck);
System.Diagnostics.Debug.WriteLine(tim);
}
}
else if (epcCheck.IndexOf("B") != -1)
{
if (listMed2.Contains(tag) == false)
{
listMed2.Add(tag);
}
}
else if (epcCheck.IndexOf("C") != -1)
{
if (listMed3.Contains(tag) == false)
{
listMed3.Add(tag);
}
}
else if (epcCheck.IndexOf("D") != -1)
{
if (listMed1.Contains(tag) == false)
{
listMed4.Add(tag);
}
}
else if (epcCheck.IndexOf("E") != -1)
{
if (listMed5.Contains(tag) == false)
{
listMed5.Add(tag);
}
}
int Med1num = listMed1.Count();
int Med2num = listMed2.Count();
int Med3num = listMed3.Count();
int Med4num = listMed4.Count();
int Med5num = listMed5.Count();
for (int loopr = 0; loopr < Med1num; loopr++)
{
Impinj.OctaneSdk.ImpinjTimestamp second = listMed1[loopr].LastSeenTime;
string milisecondsUTC = second.ToString();
long lastseen = Convert.ToInt64(milisecondsUTC);
TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1);
long secondsSinceEpoch = (long)t.TotalMilliseconds;
if (secondsSinceEpoch - lastseen > 500 )
{
listMed1.RemoveAt(loopr);
loopr = -1;
}
}
for (int loopr = 0; loopr < Med2num; loopr++)
{
Impinj.OctaneSdk.ImpinjTimestamp second = listMed2[loopr].LastSeenTime;
string milisecondsUTC = second.ToString();
long lastseen = Convert.ToInt64(milisecondsUTC);
TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1);
long secondsSinceEpoch = (long)t.TotalMilliseconds;
if (secondsSinceEpoch - lastseen > 500)
{
listMed2.RemoveAt(loopr);
loopr = -1;
}
}
for (int loopr = 0; loopr < Med3num; loopr++)
{
Impinj.OctaneSdk.ImpinjTimestamp second = listMed3[loopr].LastSeenTime;
string milisecondsUTC = second.ToString();
long lastseen = Convert.ToInt64(milisecondsUTC);
TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1);
long secondsSinceEpoch = (long)t.TotalMilliseconds;
if (secondsSinceEpoch - lastseen > 500)
{
listMed3.RemoveAt(loopr);
loopr = -1;
}
}
for (int loopr = 0; loopr < Med4num; loopr++)
{
Impinj.OctaneSdk.ImpinjTimestamp second = listMed4[loopr].LastSeenTime;
string milisecondsUTC = second.ToString();
long lastseen = Convert.ToInt64(milisecondsUTC);
TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1);
long secondsSinceEpoch = (long)t.TotalMilliseconds;
if (secondsSinceEpoch - lastseen > 500)
{
listMed4.RemoveAt(loopr);
loopr = -1;
}
}
for (int loopr = 0; loopr < Med5num; loopr++)
{
Impinj.OctaneSdk.ImpinjTimestamp second = listMed5[loopr].LastSeenTime;
string milisecondsUTC = second.ToString();
long lastseen = Convert.ToInt64(milisecondsUTC);
TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1);
long secondsSinceEpoch = (long)t.TotalMilliseconds;
if (secondsSinceEpoch - lastseen > 500)
{
listMed5.RemoveAt(loopr);
loopr = -1;
}
}
Med1num = listMed1.Count();
Med2num = listMed2.Count();
Med3num = listMed3.Count();
Med4num = listMed4.Count();
Med5num = listMed5.Count();
SetText(Med1num, Med2num, Med3num, Med4num, Med5num);
}
}
Like this:
/// <summary>The group</summary>
enum eGroup : byte
{
A, B, C, D, E
};
static IEnumerable<eGroup> allGroups()
{
return Enum.GetValues( typeof( eGroup ) ).Cast<eGroup>();
}
/// <summary>Classify tag to the group, returns null if failed.</summary>
static eGroup? classify( Tag tag )
{
string str = tag.Epc.ToString().ToUpper();
foreach( eGroup e in allGroups() )
if( str.Contains( e.ToString ) )
return e;
return null;
}
/// <summary>Add tag to list unless it's already there.</summary>
static void addToList( List<Tag> list, Tag t )
{
int ind = list.IndexOf( t );
if( ind < 0 )
list.Add( t ); // Not on the list
else if( list[ ind ].LastSeenTime.Utc < t.LastSeenTime.Utc )
list[ ind ] = t; // Only replace if newer then the existing one
}
/// <summary>The collection to hold all that groups.</summary>
readonly Dictionary<eGroup, List<Tag>> med = allGroups().ToDictionary( e => e, e => new List<Tag>() );
/// <summary>True if that tag is too old.</summary>
static bool isTooOld( Tag t )
{
ImpinjTimestamp ts = t.LastSeenTime;
DateTime utc = new DateTime( 1970, 1, 1, 0, 0, 0, DateTimeKind.Utc ).AddTicks( (long)ts.Utc * 10L );
return ( DateTime.UtcNow - utc ).TotalMilliseconds > 500;
}
void OnTagsReported( ImpinjReader sender, TagReport report )
{
// Classify and add to the correct group
foreach( Tag tag in report )
{
eGroup? group = classify( tag );
if( !group.HasValue ) continue;
addToList( med[ group.Value ], tag );
}
// Remove too old tags
foreach( var list in med.Values )
list.RemoveAll( isTooOld );
// Show counts
int[] c = allGroups().Select( e => med[ e ].Count ).ToArray();
SetText( c[ 0 ], c[ 1 ], c[ 2 ], c[ 3 ], c[ 4 ] );
}