private CompiledBooleanSignal booleanSignal(NodeSignal signal, SignalTable signalTable) { var signalAddress = signalTable.GetBooleanSignalAddress(signal); var compiledSignal = new CompiledBooleanSignal(false, signalAddress, signalTable.BooleanAddressBits); return(compiledSignal); }
private CompiledBooleanSignal booleanSignal(NodeSignalIn signalIn, SignalTable signalTable) { if (signalIn.SignalId != null) { var signalAddress = signalTable.GetBooleanSignalAddress(signalIn); var compiledSignal = new CompiledBooleanSignal(true, signalAddress, signalTable.BooleanAddressBits); return(compiledSignal); } else if (signalIn.Literal != null) { var literal = signalIn.Literal; if (literal.DataType != FieldDataType.DataTypeEnum.BOOL) { throw new Exception("Signal should be a BOOL."); } var literalValue = (bool)(literal.Value); return(new CompiledBooleanSignal(literalValue)); } else { throw new Exception("Expecting one of SignalIn.SignalId or SignalIn.Literal to be non-null"); } }
private void driveSignalWithCoilToConstantValue( Int16 address, bool value, SignalTable signalTable, List <CompiledInstruction> compiledInstructions) { if (!value) // if value is TRUE, only need the coil, otherwise need a NO contact { var compiledContactSignal = new CompiledBooleanSignal(false); var contact = new CompiledInstruction( 0x01, // NO contact 3, compiledContactSignal); compiledInstructions.Add(contact); } var compiledDiscreteInputSignal = new CompiledBooleanSignal(false, address, signalTable.BooleanAddressBits); var coil = new CompiledInstruction( 0x00, // coil 3, compiledDiscreteInputSignal); compiledInstructions.Add(coil); compiledInstructions.Add(new CompiledInstruction(0x03, 3)); // series instruction end (end of rung) }
public CompiledProgram Compile(NodeRuntimeApplication rta, SignalTable signalTable) { if (rta == null) { throw new ArgumentNullException("rta"); } if (signalTable == null) { throw new ArgumentNullException("signalTable"); } var runtimeId = Guid.Parse(rta.RuntimeId.ToString()); var versionId = Guid.Parse(rta.ID.ToString()); var logic = rta.Logic; var compiledInstructions = new List <CompiledInstruction>(); var discreteInputs = rta.DeviceConfiguration.GetChildrenRecursive() .Select(x => x.Value) .OfType <NodeDiscreteInput>(); foreach (var discreteInput in discreteInputs) { if (discreteInput.Forced.BoolValue) { var address = Int16.Parse(discreteInput.Address.ToString()); this.driveSignalWithCoilToConstantValue( address, discreteInput.ForcedValue.BoolValue, signalTable, compiledInstructions); } } var analogInputs = rta.DeviceConfiguration.GetChildrenRecursive() .Select(x => x.Value) .OfType <NodeAnalogInput>(); foreach (var analogInput in analogInputs) { if (analogInput.Forced.BoolValue) { if (analogInput.ForcedValue.DataType != FieldDataType.DataTypeEnum.NUMBER) { throw new Exception("Data type of forced value must be NUMBER."); } var address = byte.Parse(analogInput.Address.ToString()); this.setNumericAddressToValueWithAddInstruction( address, (decimal)(analogInput.ForcedValue.Value), signalTable, compiledInstructions); } } compiledInstructions.AddRange(compilePageCollection(logic, signalTable)); // discrete output literals var discreteOutputs = rta.DeviceConfiguration.GetChildrenRecursive() .Select(x => x.Value) .OfType <NodeDiscreteOutput>(); foreach (var discreteOutput in discreteOutputs) { var literal = discreteOutput.SignalIn.Literal; var address = Int16.Parse(discreteOutput.Address.ToString()); if (literal != null) { // insert a new rung to set the literal value if (literal.DataType != FieldDataType.DataTypeEnum.BOOL) { throw new Exception("Data type must be BOOL."); } var literalValue = (bool)(literal.Value); this.driveSignalWithCoilToConstantValue( address, literalValue, signalTable, compiledInstructions); } } // boolean jumpers (from internal signals to outputs) foreach (var booleanJumper in signalTable.BooleanJumpers) { var compiledContactSignal = new CompiledBooleanSignal(true, booleanJumper.Item1, signalTable.BooleanAddressBits); var contact = new CompiledInstruction( 0x01, // NO contact 3, compiledContactSignal); compiledInstructions.Add(contact); var compiledDiscreteOutputSignal = new CompiledBooleanSignal(false, booleanJumper.Item2, signalTable.BooleanAddressBits); var coil = new CompiledInstruction( 0x00, // coil 3, compiledDiscreteOutputSignal); compiledInstructions.Add(coil); compiledInstructions.Add(new CompiledInstruction(0x03, 3)); // series instruction end (end of rung) } // boolean forces foreach (var discreteOutput in discreteOutputs) { var address = Int16.Parse(discreteOutput.Address.ToString()); if (discreteOutput.Forced.BoolValue) { this.driveSignalWithCoilToConstantValue( address, discreteOutput.ForcedValue.BoolValue, signalTable, compiledInstructions); } } // analog output literals var analogOutputs = rta.DeviceConfiguration.GetChildrenRecursive() .Select(x => x.Value) .OfType <NodeAnalogOutput>(); foreach (var analogOutput in analogOutputs) { var literal = analogOutput.SignalIn.Literal; var address = Byte.Parse(analogOutput.Address.ToString()); if (literal != null) { // insert a new rung to set the literal value if (literal.DataType != FieldDataType.DataTypeEnum.NUMBER) { throw new Exception("Data type of literal must be NUMBER."); } this.setNumericAddressToValueWithAddInstruction( address, (decimal)(literal.Value), signalTable, compiledInstructions); } } // analog jumpers (from internal signals to outputs) foreach (var numericJumper in signalTable.NumericJumpers) { var sourceAddress = numericJumper.Item1; var destinationAddress = numericJumper.Item2; var compiledOperand1Signal = new CompiledNumericSignal(true, sourceAddress, signalTable.NumericAddressBits); var operand2SignalIn = NodeSignalIn.BuildWith( new FieldDataType(FieldDataType.DataTypeEnum.NUMBER), new FieldConstant(FieldDataType.DataTypeEnum.NUMBER, 0M)); var compiledOperand2Signal = numericSignal(operand2SignalIn, signalTable); var compiledResultSignal = new CompiledNumericSignal(false, destinationAddress, signalTable.NumericAddressBits); var add = new CompiledInstruction( 0x78, // add 7, compiledOperand1Signal, compiledOperand2Signal, compiledResultSignal); compiledInstructions.Add(add); compiledInstructions.Add(new CompiledInstruction(0x03, 3)); // series instruction end (end of rung) } // analog forces foreach (var analogOutput in analogOutputs) { var address = Byte.Parse(analogOutput.Address.ToString()); if (analogOutput.Forced.BoolValue) { if (analogOutput.ForcedValue.DataType != FieldDataType.DataTypeEnum.NUMBER) { throw new Exception("Data type of forced value must be NUMBER."); } this.setNumericAddressToValueWithAddInstruction( address, (decimal)(analogOutput.ForcedValue.Value), signalTable, compiledInstructions); } } // end of program compiledInstructions.Add(new CompiledInstruction(PROGRAM_END, 8)); var packedInstructions = bitPackInstructions(compiledInstructions); return(new CompiledProgram( runtimeId, versionId, signalTable.BooleanAddressBits, signalTable.NumericAddressBits, packedInstructions)); }