public void TestEnumToByte() { Assert.AreEqual(0x0, PLCCommandResponseExpectationConversionHelper.ConvertToByte(PLCCommandResponseExpectationEnum.UNDEFINED)); Assert.AreEqual(0x1, PLCCommandResponseExpectationConversionHelper.ConvertToByte(PLCCommandResponseExpectationEnum.MINOR_RESPONSE)); Assert.AreEqual(0x2, PLCCommandResponseExpectationConversionHelper.ConvertToByte(PLCCommandResponseExpectationEnum.FULL_RESPONSE)); }
public byte[] RequestMessageSend(PLCCommandAndQueryTypeEnum MessageType, params object[] MessageParameters) { byte[] NetOutgoingMessage = { 0x13, 0x0, PLCCommandAndQueryTypeConversionHelper.ConvertToByte(MessageType), 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; PLCCommandResponseExpectationEnum ResponseExpectationValue; switch (MessageType) { case PLCCommandAndQueryTypeEnum.TEST_CONNECTION: case PLCCommandAndQueryTypeEnum.GET_CURRENT_AZEL_POSITIONS: case PLCCommandAndQueryTypeEnum.GET_CURRENT_LIMIT_SWITCH_STATUSES: case PLCCommandAndQueryTypeEnum.GET_CURRENT_SAFETY_INTERLOCK_STATUS: { ResponseExpectationValue = PLCCommandResponseExpectationEnum.FULL_RESPONSE; break; } case PLCCommandAndQueryTypeEnum.CANCEL_ACTIVE_OBJECTIVE_AZEL_POSITION: case PLCCommandAndQueryTypeEnum.SHUTDOWN: case PLCCommandAndQueryTypeEnum.CALIBRATE: case PLCCommandAndQueryTypeEnum.CONTROLLED_STOP: case PLCCommandAndQueryTypeEnum.IMMEDIATE_STOP: { ResponseExpectationValue = PLCCommandResponseExpectationEnum.MINOR_RESPONSE; break; } case PLCCommandAndQueryTypeEnum.SET_CONFIGURATION: { ResponseExpectationValue = PLCCommandResponseExpectationEnum.MINOR_RESPONSE; int StartSpeedAzimuth = (int)MessageParameters[0]; int StartSpeedElevation = (int)MessageParameters[1]; int HomeTimeoutAzimuth = (int)MessageParameters[2]; int HomeTimeoutElevation = (int)MessageParameters[3]; NetOutgoingMessage[3] = 0x84; NetOutgoingMessage[4] = 0x00; NetOutgoingMessage[5] = 0x00; NetOutgoingMessage[6] = 0x00; NetOutgoingMessage[7] = 0x0; NetOutgoingMessage[8] = (byte)(StartSpeedAzimuth / 0xFFFF); NetOutgoingMessage[9] = (byte)((StartSpeedAzimuth >> 8) & 0xFF); NetOutgoingMessage[10] = (byte)(StartSpeedAzimuth & 0xFF); NetOutgoingMessage[11] = 0x0; NetOutgoingMessage[12] = (byte)(StartSpeedElevation / 0xFFFF); NetOutgoingMessage[13] = (byte)((StartSpeedElevation >> 8) & 0xFF); NetOutgoingMessage[14] = (byte)(StartSpeedElevation & 0xFF); NetOutgoingMessage[15] = (byte)(HomeTimeoutAzimuth >> 8); NetOutgoingMessage[16] = (byte)(HomeTimeoutAzimuth & 0xFF); NetOutgoingMessage[17] = (byte)(HomeTimeoutElevation >> 8); NetOutgoingMessage[18] = (byte)(HomeTimeoutElevation & 0xFF); break; } case PLCCommandAndQueryTypeEnum.SET_OBJECTIVE_AZEL_POSITION: { ResponseExpectationValue = PLCCommandResponseExpectationEnum.MINOR_RESPONSE; Orientation ObjectiveOrientation = (Orientation)MessageParameters[0]; Array.Copy(BitConverter.GetBytes(ObjectiveOrientation.Azimuth), 0, NetOutgoingMessage, 3, 8); Array.Copy(BitConverter.GetBytes(ObjectiveOrientation.Elevation), 0, NetOutgoingMessage, 11, 8); break; } case PLCCommandAndQueryTypeEnum.START_JOG_MOVEMENT: { ResponseExpectationValue = PLCCommandResponseExpectationEnum.MINOR_RESPONSE; RadioTelescopeAxisEnum AxisEnum = (RadioTelescopeAxisEnum)MessageParameters[0]; int AxisJogSpeed = (int)MessageParameters[1]; bool JogClockwise = (bool)MessageParameters[2]; switch (AxisEnum) { case RadioTelescopeAxisEnum.AZIMUTH: { NetOutgoingMessage[3] = 0x1; break; } case RadioTelescopeAxisEnum.ELEVATION: { NetOutgoingMessage[3] = 0x2; break; } default: { throw new ArgumentException("Invalid RadioTelescopeAxisEnum value seen while preparing jog movement bytes: " + AxisEnum.ToString()); } } NetOutgoingMessage[4] = 0x0; NetOutgoingMessage[5] = (byte)(AxisJogSpeed / 0xFFFF); NetOutgoingMessage[6] = (byte)((AxisJogSpeed >> 8) & 0xFF); NetOutgoingMessage[7] = (byte)(AxisJogSpeed & 0xFF); NetOutgoingMessage[8] = (byte)(JogClockwise ? 0x1 : 0x2); break; } case PLCCommandAndQueryTypeEnum.TRANSLATE_AZEL_POSITION: { ResponseExpectationValue = PLCCommandResponseExpectationEnum.MINOR_RESPONSE; RadioTelescopeAxisEnum AxisEnum = (RadioTelescopeAxisEnum)MessageParameters[0]; int AxisJogSpeed = (int)MessageParameters[1]; int position = (int)MessageParameters[2]; switch (AxisEnum) { case RadioTelescopeAxisEnum.AZIMUTH: { NetOutgoingMessage[3] = 0x1; break; } case RadioTelescopeAxisEnum.ELEVATION: { NetOutgoingMessage[3] = 0x2; break; } default: { throw new ArgumentException("Invalid RadioTelescopeAxisEnum value seen while preparing relative movement bytes: " + AxisEnum.ToString()); } } NetOutgoingMessage[4] = 0x0; NetOutgoingMessage[5] = (byte)(AxisJogSpeed / 0xFFFF); NetOutgoingMessage[6] = (byte)((AxisJogSpeed >> 8) & 0xFF); NetOutgoingMessage[7] = (byte)(AxisJogSpeed & 0xFF); if (position > 0) { NetOutgoingMessage[8] = 0x0; NetOutgoingMessage[9] = (byte)(position / 0xFFFF); NetOutgoingMessage[10] = (byte)((position >> 8) & 0xFF); NetOutgoingMessage[11] = (byte)(position & 0xFF); } else { NetOutgoingMessage[8] = 0xFF; NetOutgoingMessage[9] = (byte)((position / 0xFFFF) - 1); NetOutgoingMessage[10] = (byte)((position >> 8) & 0xFF); NetOutgoingMessage[11] = (byte)(position & 0xFF); } break; } default: { throw new ArgumentException("Illegal PLCCommandAndQueryTypeEnum value: " + MessageType.ToString()); } } NetOutgoingMessage[2] += (byte)(PLCCommandResponseExpectationConversionHelper.ConvertToByte(ResponseExpectationValue) * 0x40); // This is the expected response size of anything from the PLC (simulated or real), minor or full response. // See the TCP/IP packet contents google sheets file describing this under Wiki Documentation -> Control Room in the shared GDrive byte ExpectedResponseSize = (ResponseExpectationValue == PLCCommandResponseExpectationEnum.FULL_RESPONSE) ? (byte)0x13 : (byte)0x3; return(SendMessageWithResponse(NetOutgoingMessage, ExpectedResponseSize)); }