Exemple #1
0
        private CompiledBooleanSignal booleanSignal(NodeSignal signal, SignalTable signalTable)
        {
            var signalAddress  = signalTable.GetBooleanSignalAddress(signal);
            var compiledSignal = new CompiledBooleanSignal(false, signalAddress, signalTable.BooleanAddressBits);

            return(compiledSignal);
        }
Exemple #2
0
 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");
     }
 }
Exemple #3
0
        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)
        }
Exemple #4
0
        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));
        }