/// <summary> /// Sends a message from / to the given devices. /// </summary> /// <param name="fromNode">The ID of the Node sending the message.</param> /// <param name="fromDevice">The ID of the device sending the message.</param> /// <param name="toNode">The ID of the Node to send to.</param> /// <param name="toDevice">The ID of the Device on that Node to send to.</param> /// <param name="command">The Command to send.</param> /// <param name="data">The optional parameters for the command.</param> public static C4UFX.CANMessage SendMessage(byte fromNode, byte fromDevice, byte toNode, byte toDevice, Commands command, byte[] data = null) { if (fromNode > MAX_ID || fromDevice > MAX_ID || toNode > MAX_ID || toDevice > MAX_ID) { throw new Exception("Node / Device IDs cannot be higher than 127."); } if (data?.Length > MAX_DATA_BYTES - 1) { throw new Exception("Messages cannot carry more than 8 bytes of data, including the Command byte."); } C4UFX.CANMessage message = new C4UFX.CANMessage(); FndTnd fndtnd = GetFndTnd(fromNode, fromDevice, toNode, toDevice); message.DLC = (data != null) ? (byte)(data.Length + 1) : (byte)1; message.ID = FndTndToId(fndtnd); message.Data[0] = (byte)command; if (data != null) { for (int i = 0; i < data.Length; i++) { message.Data[i + 1] = data[i]; } } messageQueue.Enqueue(message); return(message); }
private static void DevicePoll_Received(List <C4UFX.CANMessage> responses) { StatusUpdate?.Invoke("Querying names (1/3)..."); foreach (C4UFX.CANMessage response in responses) { FndTnd address = CANInterface.IdToFndTnd(response.ID); if (address.FromDevice > 0) { Node currentNode = allResponses.First(x => x.NodeId == address.FromNode); byte fromNode = CANInterface.IdToFndTnd(response.ID).FromNode; byte fromDevice = CANInterface.IdToFndTnd(response.ID).FromDevice; Device newDevice; switch ((Signatures)response.Data[2]) { case Signatures.MechanicalSwitch: newDevice = new MechanicalSwitch(fromNode, fromDevice); break; case Signatures.StatusLED: newDevice = new StatusLED(fromNode, fromDevice); break; case Signatures.InfraredInput: newDevice = new InfraredInput(fromNode, fromDevice); break; case Signatures.DimmerOut: newDevice = new DimmerOut(fromNode, fromDevice); break; case Signatures.LatLong: newDevice = new LatLong(fromNode, fromDevice); break; case Signatures.TimerEvent: newDevice = new TimerEvent(fromNode, fromDevice); break; case Signatures.Scene: newDevice = new Scene(fromNode, fromDevice); break; case Signatures.RealTimeClock: newDevice = new RealTimeClock(fromNode, fromDevice); break; default: newDevice = new UnknownDevice(fromNode, fromDevice); break; } currentNode.Devices.Add(newDevice); } } Dictionary <byte, List <byte> > sendList = new Dictionary <byte, List <byte> >(); foreach (Node node in allResponses) { if (sendList.Keys.Contains(node.NodeId)) { break; } sendList.Add(node.NodeId, new List <byte>()); for (byte i = 1; i < 127; i++) { sendList[node.NodeId].Add(i); } } CANPing poll = new CANPing(Commands.CmdSysEName1, sendList); poll.ResponseReceived += Name1Poll_Received; PongsReceived?.Invoke(allResponses, false); }
/// <summary> /// Creates a FndTnd instance with the given ID values. /// </summary> /// <param name="fromNode">The ID of the From Node.</param> /// <param name="fromDevice">The ID of the From Device</param> /// <param name="toNode">The ID of the To Node.</param> /// <param name="toDevice">The ID of the To Device.</param> /// <returns>A FndTnd with the given values.</returns> private static FndTnd GetFndTnd(byte fromNode, byte fromDevice, byte toNode, byte toDevice) { FndTnd FndTnd = new FndTnd(); FndTnd.FromNode = fromNode; FndTnd.FromDevice = fromDevice; FndTnd.ToNode = toNode; FndTnd.ToDevice = toDevice; return(FndTnd); }
/// <summary> /// Convert from FndTnd to an ID. /// </summary> /// <param name="fndtnd">The FndTnd.</param> /// <returns>The ID.</returns> public static long FndTndToId(FndTnd fndtnd) { long id; id = (long)fndtnd.FromNode << 21; id += (long)fndtnd.FromDevice << 14; id += (long)fndtnd.ToNode << 7; id += (long)fndtnd.ToDevice; return(id); }
/// <summary> /// Convert from an ID to a FndTnd. /// </summary> /// <param name="ID">The ID.</param> /// <returns>The FndTnd.</returns> public static FndTnd IdToFndTnd(long ID) { FndTnd fndtnd = new FndTnd(); // 01111111000000000000000000000 7 bits for From Node fndtnd.FromNode = (byte)((ID >> 21) & 0x7F); // 00000000111111100000000000000 7 bits for From Device fndtnd.FromDevice = (byte)((ID >> 14) & 0x7F); // 00000000000000011111110000000 7 bits for To Node fndtnd.ToNode = (byte)((ID >> 7) & 0x7F); // 00000000000000000000001111111 7 bits for To Device fndtnd.ToDevice = (byte)(ID & 0x7F); return(fndtnd); }
private static void Name1Poll_Received(List <C4UFX.CANMessage> responses) { StatusUpdate?.Invoke("Querying names (2/3)..."); foreach (C4UFX.CANMessage response in responses) { FndTnd address = CANInterface.IdToFndTnd(response.ID); string namePart = string.Empty; for (int i = 1; i < response.Data.Length; i++) { namePart += (char)response.Data[i]; } Node thisNode = allResponses.Find(x => x.NodeId == address.FromNode); //if (thisNode == null) // allResponses.Add(new UnknownNode(address.FromNode)); if (address.FromDevice == 0) { allResponses.Find(x => x.NodeId == address.FromNode).SetNamePart(namePart, 1); } else { allResponses.Find(x => x.NodeId == address.FromNode).Devices.Find(x => x.DeviceId == address.FromDevice).SetNamePart(namePart, 1); } //If the node/device isn't found, add it to the list } Dictionary <byte, List <byte> > sendList = new Dictionary <byte, List <byte> >(); foreach (Node node in allResponses) { if (sendList.Keys.Contains(node.NodeId)) { break; } sendList.Add(node.NodeId, new List <byte>()); foreach (Device device in node.Devices) { sendList[node.NodeId].Add(device.DeviceId); } } CANPing poll = new CANPing(Commands.CmdSysEName2, sendList); poll.ResponseReceived += Name2Poll_Received; PongsReceived?.Invoke(allResponses, false); }
private static void Name3Poll_Received(List <C4UFX.CANMessage> responses) { StatusUpdate?.Invoke("Querying parameters (1/2)..."); foreach (C4UFX.CANMessage response in responses) { FndTnd address = CANInterface.IdToFndTnd(response.ID); string namePart = string.Empty; for (int i = 1; i < response.Data.Length; i++) { namePart += (char)response.Data[i]; } if (address.FromDevice == 0) { allResponses.First(x => x.NodeId == address.FromNode).SetNamePart(namePart, 3); } else { allResponses.First(x => x.NodeId == address.FromNode).Devices.First(x => x.DeviceId == address.FromDevice).SetNamePart(namePart, 3); } } Dictionary <byte, List <byte> > sendList = new Dictionary <byte, List <byte> >(); foreach (Node node in allResponses) { if (sendList.Keys.Contains(node.NodeId)) { break; } sendList.Add(node.NodeId, new List <byte>()); foreach (Device device in node.Devices) { sendList[node.NodeId].Add(device.DeviceId); } } CANPing poll = new CANPing(Commands.CmdSysEPar, sendList); poll.ResponseReceived += Parameters1_Received; PongsReceived?.Invoke(allResponses, false); }
private static void Parameters1_Received(List <C4UFX.CANMessage> responses) { StatusUpdate?.Invoke("Querying parameters (2/2)..."); foreach (C4UFX.CANMessage response in responses) { FndTnd address = CANInterface.IdToFndTnd(response.ID); for (int i = 0; i < response.DLC - 1; i++) { if (address.FromDevice == 0) { allResponses.First(x => x.NodeId == address.FromNode).Parameters1[i] = response.Data[i + 1]; } else { allResponses.First(x => x.NodeId == address.FromNode).Devices.First(x => x.DeviceId == address.FromDevice).Parameters1[i] = response.Data[i + 1]; } } } Dictionary <byte, List <byte> > sendList = new Dictionary <byte, List <byte> >(); foreach (Node node in allResponses) { if (sendList.Keys.Contains(node.NodeId)) { break; } sendList.Add(node.NodeId, new List <byte>()); foreach (Device device in node.Devices) { sendList[node.NodeId].Add(device.DeviceId); } } CANPing poll = new CANPing(Commands.CmdSysEPar2, sendList); poll.ResponseReceived += Parameters2_Received; PongsReceived?.Invoke(allResponses, false); }
private static void Parameters2_Received(List <C4UFX.CANMessage> responses) { StatusUpdate?.Invoke("Poll Complete!"); foreach (C4UFX.CANMessage response in responses) { FndTnd address = CANInterface.IdToFndTnd(response.ID); for (int i = 0; i < response.DLC - 1; i++) { if (address.FromDevice == 0) { allResponses.First(x => x.NodeId == address.FromNode).Parameters2[i] = response.Data[i + 1]; } else { allResponses.First(x => x.NodeId == address.FromNode).Devices.First(x => x.DeviceId == address.FromDevice).Parameters2[i] = response.Data[i + 1]; } } } Dictionary <byte, List <byte> > sendList = new Dictionary <byte, List <byte> >(); foreach (Node node in allResponses) { if (sendList.Keys.Contains(node.NodeId)) { break; } sendList.Add(node.NodeId, new List <byte>()); foreach (Device device in node.Devices) { sendList[node.NodeId].Add(device.DeviceId); } } PongsReceived?.Invoke(allResponses, true); }