From your explanation I understand you are able to map a clientID to a property. It still feels like magic and it's possible that I'm missing something but let's assume you can do the translation.
Your idea about building a dictionary is correct. It should be a dictionary of setters:
public Dictionary<object, Action<machine,object>> setters = new Dictionary<object, Action<machine,object>>
{
{1, (m,v) => m.SensorA = (double)v},
{2, (m,v) => m.SensorB = (double)v},
{3, (m,v) => m.System1 = (string)v},
};
The key is the clientId. The value is a the setter - an action which takes the POCO and the item value and does the assignment.
This might seem as an overkill but will make things it a lot easier in the event handler:
public void OnNewlyReadValues(ItemValue[] itemValues)
{
var machine = new Machine();
foreach(var itemValue in itemValues)
{
var setter = setters[itemValue.clientID];
setter(machine, itemValue.value);
}
}
Based on the clientID you retrieve the setter and apply it on your POCO and item value.
Edit - multiple machines
If I understand you correctly then you want to use the same Machine instance trough the life of the client class.
Create a class that will encapsulate client ID. In your third party library the clientID is an object so you can put whatever you want there:
public class ClientId
{
public Machine Machine { get; set; }
public int SetterKey { get; set; }
}
The SetterKey is the key in the dictionary. Actually you can change that into simple array and SetterKey will then become SetterIndex. You initialization will look something like this:
Machines = new List<Machine>
{
new Machine(),
new Machine()
};
MachineItems = new List<Item>
{
new Item { clientID = new ClientId { Machine = Machines[0], SetterKey = 1 }},
new Item { clientID = new ClientId { Machine = Machines[0], SetterKey = 2 }},
new Item { clientID = new ClientId { Machine = Machines[0], SetterKey = 3 }},
new Item { clientID = new ClientId { Machine = Machines[1], SetterKey = 1 }},
new Item { clientID = new ClientId { Machine = Machines[1], SetterKey = 2 }},
new Item { clientID = new ClientId { Machine = Machines[1], SetterKey = 3 }},
};
Again all this is will make the code in the event handler much easier. You have the Machine instance embedded directly in the clientID.
public void OnNewlyReadValues(ItemValue[] itemValues)
{
foreach(var itemValue in itemValues)
{
var clientId = (ClientId) itemValue.clientID;
var setter = setters[clientId.SetterKey];
setter(clientId.Machine, itemValue.value);
}
}