Reputation: 463
I'm searching a way to create a dictionary that accepte multiple classe as value.
I'm getting value from Xiaomi gateway and foreach kind of equipment, I've got class for each kind of equipement.
For example my magnet sensor :
[XiaomiEquipement("magnet")]
public class Magnet
{
public string Model { get; set; } = "magnet";
public string Sid { get; set; }
public string Battery { get; set; } = "CR1632";
public int BatteryLevel { get; set; }
public MagnetReport Report { get; set; }
}
[XiaomiEquipement("magnet_report")]
public class MagnetReport
{
public int Voltage { get; set; }
public status { get; set; }
}
And my wallplug :
[XiaomiEquipement("plug")]
public class Plug
{
public string Model { get; set; } = "plug";
public string Sid { get; set; }
public string Battery { get; set; } = "CR2450";
public int BatteryLevel { get; set; }
public PlugReport Report { get; set; }
}
[XiaomiEquipement("plug_report")]
public class PlugReport
{
public int Voltage { get; set; }
public string Status { get; set; }
}
Xiaomi gateway send two kind of data, report when something happen and heartbeat every x minutes.
{"cmd":"heartbeat","model":"plug","sid":"158d000123f0c9","short_id":11119,"data":"{\"voltage\":3600,\"status\":\"off\",\"inuse\":\"0\",\"power_consumed\":\"7\",\"load_power\":\"0.00\"}"}
{"cmd":"report","model":"plug","sid":"158d000123f0c9","short_id":11119,"data":"{\"status\":\"on\"}"}
As you can see, the two lines haven't the same data. So I want to init the plug class and after fill the missing data when heartbeat or report arrive.
I use Activator.CreateInstance with the sensor type to create the right class.
modelType = Assembly.GetExecutingAssembly().GetTypes().SingleOrDefault(t => t.GetCustomAttribute<Response.XiaomiEquipementAttribute>()?.Model == read.Model);
modelReportType = Assembly.GetExecutingAssembly().GetTypes().SingleOrDefault(t => t.GetCustomAttribute<Response.XiaomiEquipementAttribute>()?.Model == read.Model + "_report");
I try to use dictionary to store my sensor data then edit after en heartbeat but it doesn't work as every sensor has a different class.
I try to add an interface, it work but it doesn't work for report class.
How to include these classes to my dictionary and access to it ?
Basically I want to search into the dictionary by key, get value and change a part of it.
Upvotes: 0
Views: 2302
Reputation: 27009
You may use a Dictionary<string, object>
to store them.
var items = new Dictionary<string, object>();
var mag = new Magnet() { Sid = "1" };
var mot = new Motion() { Sid = "2" };
items.Add(mag.Sid, new Magnet());
items.Add(mot.Sid, new Motion());
Then you can determine the type using Object.GetType()
like this:
foreach (var thisItem in items)
{
// or use thisItem.Value is Magnet
if (thisItem.Value.GetType().Name == "Magnet")
{
Console.WriteLine("Magnet");
}
else
{
Console.WriteLine("Motion");
}
}
You can also put the common properties into a base class and inherit the two classes from the base class.
Upvotes: 2