/// <summary> /// Tells the command station to operate an accessory decoder /// </summary> /// <param name="address">Address of the accessory decoder</param> /// <param name="state">Activate or Deactivate the output</param> /// <param name="output">Output of the selected turnout</param> public AccDecoderOperationsReqMessage(ushort address, AccessoryState state, AccessoryOutput output) : base(PacketHeaderType.AccessoryDecoderOperation) { //TODO: Test this function as Accessory Decoders are the least understood! byte[] data = new byte[2]; if (address >= XpressNetConstants.MIN_ACC_DECODER_ADDRESS && address <= XpressNetConstants.MAX_ACC_DECODER_ADDRESS) { data[0] = (byte)((address - 1) / 4); data[1] = (byte)(((address - 1) - data[0] * 4) << 1); //This is this a Modulo optimisation //Modulo optimisation [was (address - 1) % 4;] with a bitshift to move it into the right part of the byte } else { throw new XpressNetProtocolViolationException("Number out of bounds"); } data[1] |= 0x8C; //Set the MSB to high if (state == AccessoryState.Deactivate) { data[1] |= 0x01; //Set the 4th nibble to high } if (output == AccessoryOutput.Two) { data[1] |= 0x01; //Set the LSB to high } Payload.AddRange(data); }
/// <summary> /// Tells the command station to operate an accessory decoder /// </summary> /// <param name="address">Address of the accessory decoder</param> /// <param name="state">Activate or Deactivate the output</param> /// <param name="output">Output of the selected turnout</param> public AccDecoderOperationsReqMessage(ushort address, AccessoryState state, AccessoryOutput output) : base(PacketHeaderType.AccessoryDecoderOperation) { //TODO: Test this function as Accessory Decoders are the least understood! byte[] data = new byte[2]; if (address >= XpressNetConstants.MIN_ACC_DECODER_ADDRESS && address <= XpressNetConstants.MAX_ACC_DECODER_ADDRESS) { data[0] = (byte)((address - 1) / 4); data[1] = (byte)(((address - 1) - data[0] * 4) << 1); //This is this a Modulo optimisation //Modulo optimisation [was (address - 1) % 4;] with a bitshift to move it into the right part of the byte } else throw new XpressNetProtocolViolationException("Number out of bounds"); data[1] |= 0x80; //Set the MSB to high if (state == AccessoryState.Deactivate) data[1] |= 0x08; //Set the 4th nibble to high if (output == AccessoryOutput.Two) data[1] |= 0x01; //Set the LSB to high Payload.AddRange(data); }
public void SetSignal(ISignal signal) { AccessoryState state = AccessoryState.Activate; ushort address = signal.Functions.EAddress; switch (signal.State) { case SignalColour.Green: state = AccessoryState.Deactivate; break; case SignalColour.Yellow: address++; break; case SignalColour.DoubleYellow: state = AccessoryState.Deactivate; address++; break; } try { var msgSetup = new AccDecoderOperationsReqMessage(address, state, AccessoryOutput.One); msgSetup.Write(serialPort.BaseStream); } catch (InvalidOperationException e) { //TODO return the exception information to the client IsConnected = false; } }
public void AccessoryTest(string accessoryInput, AccessoryState expectedAccessoryFlags) { var line = $"<Hold|WPos:-2.500,0.000,11.000|FS:0.0,0|{accessoryInput}|WCO:0.000,1.551,5.664>"; var msg = GrblMessage.Parse(line); Assert.IsNotNull(msg); Assert.IsInstanceOfType(msg, typeof(StatusReportMessage)); var statusMsg = msg as StatusReportMessage; Assert.AreEqual(statusMsg.AccessoryState, expectedAccessoryFlags); }