Example #1
0
        internal string CreateIdentifier(IModuleBoardBridge bridge)
        {
            string myIdentifier = null;

            switch ((Module)eventConfig[0])
            {
            case SWITCH:
                myIdentifier = "switch";
                break;

            case ACCELEROMETER: {
                var module = bridge.GetModule <IAccelerometer>();
                if (module is AccelerometerMma8452q)
                {
                    myIdentifier = AccelerometerMma8452q.createIdentifier(this);
                }
                else if (module is AccelerometerBmi160)
                {
                    myIdentifier = AccelerometerBmi160.createIdentifier(this);
                }
                else if (module is AccelerometerBma255)
                {
                    myIdentifier = AccelerometerBosch.createIdentifier(this);
                }
                else
                {
                    myIdentifier = null;
                }
                break;
            }

            case TEMPERATURE:
                myIdentifier = string.Format("temperature[{0}]", eventConfig[2]);
                break;

            case GPIO:
                myIdentifier = Gpio.createIdentifier(this);
                break;

            case DATA_PROCESSOR:
                myIdentifier = DataProcessor.createIdentifier(this, bridge.GetModule <IDataProcessor>() as DataProcessor, bridge.getFirmware());
                break;

            case SERIAL_PASSTHROUGH:
                myIdentifier = SerialPassthrough.createIdentifier(this);
                break;

            case SETTINGS:
                myIdentifier = Settings.createIdentifier(this);
                break;

            case BAROMETER:
                myIdentifier = BarometerBosch.createIdentifier(this);
                break;

            case GYRO:
                myIdentifier = attributes.length() > 2 ? "angular-velocity" : string.Format("angular-velocity[{0}]", (attributes.offset >> 1));
                break;

            case AMBIENT_LIGHT:
                myIdentifier = "illuminance";
                break;

            case MAGNETOMETER:
                myIdentifier = attributes.length() > 2 ? "magnetic-field" : string.Format("magnetic-field[{0}]", (attributes.offset >> 1));
                break;

            case HUMIDITY:
                myIdentifier = "relative-humidity";
                break;

            case COLOR_DETECTOR:
                myIdentifier = attributes.length() > 2 ? "color" : string.Format("color[{0}]", (attributes.offset >> 1));
                break;

            case PROXIMITY:
                myIdentifier = "proximity";
                break;

            case SENSOR_FUSION:
                myIdentifier = SensorFusionBosch.createIdentifier(this);
                break;
            }

            if (myIdentifier == null)
            {
                throw new InvalidOperationException("Cannot create identifier string for data type: " + Util.arrayToHexString(eventConfig));
            }

            return((input != null && !input.eventConfig.SequenceEqual(eventConfig) ? input.CreateIdentifier(bridge) + ":" : "") + myIdentifier);
        }
        private async Task createRouteAsync(bool ready)
        {
            if (pendingRoutes.Count != 0 && (ready || pendingRoutes.Count == 1))
            {
                var top = pendingRoutes.Peek();

                try
                {
                    top.Item1(top.Item2);
                    foreach (var entry in top.Item2.state.namedProcessors)
                    {
                        if (persistent.namedProducers.ContainsKey(entry.Key))
                        {
                            throw new IllegalRouteOperationException(string.Format("Duplicate producer name present: '{0}'", entry.Key));
                        }
                        persistent.namedProducers.Add(entry.Key, entry.Value.Item2.source);
                    }

                    Queue <byte> dataProcIds = null;
                    if (persistent.modules.TryGetValue(typeof(IDataProcessor).FullName, out var module))
                    {
                        DataProcessor dataProc = module as DataProcessor;
                        dataProcIds = await dataProc.queueDataProcessors(top.Item2.state.dataProcessors);

                        foreach (var entry in top.Item2.state.namedProcessors)
                        {
                            if (entry.Value.Item2.source.eventConfig[0] == (byte)DATA_PROCESSOR)
                            {
                                dataProc.nameToId.Add(entry.Key, entry.Value.Item2.source.eventConfig[2]);
                            }
                        }
                    }

                    Queue <LoggedDataConsumer> logConsumers = null;
                    if (persistent.modules.TryGetValue(typeof(ILogging).FullName, out module))
                    {
                        logConsumers = await(module as Logging).CreateLoggersAsync(top.Item2.state.subscribedProducers
                                                                                   .FindAll(p => p.Item3)
                                                                                   .Aggregate(new Queue <DataTypeBase>(), (acc, e) =>
                        {
                            acc.Enqueue(e.Item1);
                            return(acc);
                        })
                                                                                   );
                    }

                    Queue <byte> eventIds = null;
                    if (persistent.modules.TryGetValue(typeof(Event).FullName, out module))
                    {
                        Event eventModule = module as Event;

                        var eventCodeBlocks = top.Item2.state.feedback.Aggregate(new Queue <Tuple <DataTypeBase, Action> >(), (acc, e) =>
                        {
                            if (!persistent.namedProducers.ContainsKey(e.Item1))
                            {
                                throw new IllegalRouteOperationException("\'" + e.Item1 + "\' is not associated with any data producer or named component");
                            }
                            var source = persistent.namedProducers[e.Item1];
                            acc.Enqueue(Tuple.Create <DataTypeBase, Action>(source, () => bridge.sendCommand(e.Item3, source, DATA_PROCESSOR, DataProcessor.PARAMETER, e.Item2.eventConfig[2], e.Item4)));

                            return(acc);
                        });
                        top.Item2.state.reactions.ForEach(e => eventCodeBlocks.Enqueue(Tuple.Create <DataTypeBase, Action>(e.Item1, () => e.Item2(e.Item1))));

                        eventIds = await eventModule.queueEvents(eventCodeBlocks);
                    }

                    List <DeviceDataConsumer> consumers = new List <DeviceDataConsumer>();
                    top.Item2.state.subscribedProducers.ForEach(producer =>
                    {
                        if (logConsumers != null && producer.Item3)
                        {
                            var logger        = logConsumers.Dequeue();
                            logger.subscriber = producer.Item2;
                            consumers.Add(logger);
                        }
                        else
                        {
                            StreamedDataConsumer newConsumer = new StreamedDataConsumer(producer.Item1, producer.Item2);
                            newConsumer.enableStream(bridge);
                            consumers.Add(newConsumer);
                        }
                    });

                    pendingRoutes.Dequeue();

                    Route newRoute = new Route(persistent.id, consumers, dataProcIds, eventIds,
                                               top.Item2.state.namedProcessors.Count != 0 ? new List <string>(top.Item2.state.namedProcessors.Keys) : null, bridge);
                    persistent.activeRoutes.Add(persistent.id, newRoute);
                    persistent.id++;

                    top.Item3.SetResult(newRoute);
                }
                catch (Exception e)
                {
                    pendingRoutes.Dequeue();
                    top.Item3.SetException(e);
                }
                finally
                {
                    await createRouteAsync(true);
                }
            }
        }
Example #3
0
            internal override Tuple <DataTypeBase, DataTypeBase> transform(DataProcessorConfig config, DataProcessor dpModule)
            {
                switch (config.id)
                {
                case DataProcessorConfig.CombinerConfig.ID: {
                    DataAttributes attributes = new DataAttributes(new byte[] { this.attributes.sizes[0] }, 1, 0, false);
                    return(Tuple.Create <DataTypeBase, DataTypeBase>(new IntegralDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, attributes), null));
                }
                }

                return(base.transform(config, dpModule));
            }
Example #4
0
        internal virtual Tuple <DataTypeBase, DataTypeBase> transform(DataProcessorConfig config, DataProcessor dpModule)
        {
            switch (config.id)
            {
            case DataProcessorConfig.BufferConfig.ID:
                return(Tuple.Create(
                           new IntegralDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, new DataAttributes(new byte[] { }, 0, 0, false)) as DataTypeBase,
                           dataProcessorStateCopy(this, this.attributes)
                           ));

            case DataProcessorConfig.AccumulatorConfig.ID: {
                DataProcessorConfig.AccumulatorConfig casted = (DataProcessorConfig.AccumulatorConfig)config;
                DataAttributes attributes = new DataAttributes(new byte[] { casted.output }, 1, 0, !casted.counter && this.attributes.signed);

                return(Tuple.Create(
                           casted.counter ? new IntegralDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, attributes) : dataProcessorCopy(this, attributes),
                           casted.counter ? new IntegralDataType(null, DATA_PROCESSOR, Util.setRead(DataProcessor.STATE), NO_ID, attributes) :
                           dataProcessorStateCopy(this, attributes)
                           ));
            }

            case DataProcessorConfig.AverageConfig.ID:
            case DataProcessorConfig.DelayConfig.ID:
            case DataProcessorConfig.TimeConfig.ID:
                return(Tuple.Create <DataTypeBase, DataTypeBase>(dataProcessorCopy(this, this.attributes.dataProcessorCopy()), null));

            case DataProcessorConfig.PassthroughConfig.ID:
                return(Tuple.Create(
                           dataProcessorCopy(this, this.attributes.dataProcessorCopy()),
                           new IntegralDataType(DATA_PROCESSOR, Util.setRead(DataProcessor.STATE), NO_ID, new DataAttributes(new byte[] { 2 }, 1, 0, false)) as DataTypeBase
                           ));

            case DataProcessorConfig.MathConfig.ID: {
                DataProcessorConfig.MathConfig casted = (DataProcessorConfig.MathConfig)config;
                DataTypeBase processor = null;
                switch (casted.op)
                {
                case Add:
                    processor = dataProcessorCopy(this, this.attributes.dataProcessorCopySize(4));
                    break;

                case Multiply:
                    processor = dataProcessorCopy(this, this.attributes.dataProcessorCopySize(Math.Abs(casted.rhs) < 1 ? this.attributes.sizes[0] : (byte)4));
                    break;

                case Divide:
                    processor = dataProcessorCopy(this, this.attributes.dataProcessorCopySize(Math.Abs(casted.rhs) < 1 ? (byte)4 : this.attributes.sizes[0]));
                    break;

                case Subtract:
                    processor = dataProcessorCopy(this, this.attributes.dataProcessorCopySigned(true));
                    break;

                case AbsValue:
                    processor = dataProcessorCopy(this, this.attributes.dataProcessorCopySigned(false));
                    break;

                case Modulus:
                    processor = dataProcessorCopy(this, this.attributes.dataProcessorCopy());
                    break;

                case Exponent:
                    processor = new ByteArrayDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, this.attributes.dataProcessorCopySize(4));
                    break;

                case LeftShift:
                    processor = new ByteArrayDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY,
                                                      this.attributes.dataProcessorCopySize((byte)Math.Min(this.attributes.sizes[0] + (casted.rhs / 8), 4)));
                    break;

                case RightShift:
                    processor = new ByteArrayDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY,
                                                      this.attributes.dataProcessorCopySize((byte)Math.Max(this.attributes.sizes[0] - (casted.rhs / 8), 1)));
                    break;

                case Sqrt:
                    processor = new ByteArrayDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, this.attributes.dataProcessorCopySigned(false));
                    break;

                case Constant:
                    DataAttributes attributes = new DataAttributes(new byte[] { 4 }, (byte)1, (byte)0, casted.rhs >= 0);
                    processor = new IntegralDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, attributes);
                    break;
                }
                if (processor != null)
                {
                    return(Tuple.Create <DataTypeBase, DataTypeBase>(processor, null));
                }
                break;
            }

            case DataProcessorConfig.PulseConfig.ID: {
                DataProcessorConfig.PulseConfig casted = (DataProcessorConfig.PulseConfig)config;
                DataTypeBase processor = null;
                switch (casted.mode)
                {
                case Width:
                    processor = new IntegralDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, new DataAttributes(new byte[] { 2 }, 1, 0, false));
                    break;

                case Area:
                    processor = dataProcessorCopy(this, attributes.dataProcessorCopySize(4));
                    break;

                case Peak:
                    processor = dataProcessorCopy(this, attributes.dataProcessorCopy());
                    break;

                case OnDetect:
                    processor = new IntegralDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, new DataAttributes(new byte[] { 1 }, 1, 0, false));
                    break;
                }
                if (processor != null)
                {
                    return(Tuple.Create <DataTypeBase, DataTypeBase>(processor, null));
                }
                break;
            }

            case DataProcessorConfig.ComparisonConfig.ID: {
                DataTypeBase processor = null;
                if (config is DataProcessorConfig.SingleValueComparisonConfig)
                {
                    processor = dataProcessorCopy(this, attributes.dataProcessorCopy());
                }
                else if (config is DataProcessorConfig.MultiValueComparisonConfig)
                {
                    DataProcessorConfig.MultiValueComparisonConfig casted = (DataProcessorConfig.MultiValueComparisonConfig)config;
                    if (casted.mode == ComparisonOutput.PassFail || casted.mode == ComparisonOutput.Zone)
                    {
                        processor = new IntegralDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, new DataAttributes(new byte[] { 1 }, 1, 0, false));
                    }
                    else
                    {
                        processor = dataProcessorCopy(this, attributes.dataProcessorCopy());
                    }
                }
                if (processor != null)
                {
                    return(Tuple.Create <DataTypeBase, DataTypeBase>(processor, null));
                }
                break;
            }

            case DataProcessorConfig.ThresholdConfig.ID: {
                DataProcessorConfig.ThresholdConfig casted = (DataProcessorConfig.ThresholdConfig)config;
                switch (casted.mode)
                {
                case Threshold.Absolute:
                    return(Tuple.Create <DataTypeBase, DataTypeBase>(dataProcessorCopy(this, attributes.dataProcessorCopy()), null));

                case Threshold.Binary:
                    return(Tuple.Create <DataTypeBase, DataTypeBase>(new IntegralDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY,
                                                                                          new DataAttributes(new byte[] { 1 }, 1, 0, true)), null));
                }
                break;
            }

            case DataProcessorConfig.DifferentialConfig.ID: {
                DataProcessorConfig.DifferentialConfig casted = (DataProcessorConfig.DifferentialConfig)config;
                switch (casted.mode)
                {
                case Differential.Absolute:
                    return(Tuple.Create <DataTypeBase, DataTypeBase>(dataProcessorCopy(this, attributes.dataProcessorCopy()), null));

                case Differential.Differential:
                    throw new InvalidOperationException("Differential processor in 'difference' mode must be handled by subclasses");

                case Differential.Binary:
                    return(Tuple.Create <DataTypeBase, DataTypeBase>(new IntegralDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, new DataAttributes(new byte[] { 1 }, 1, 0, true)), null));
                }
                break;
            }

            case DataProcessorConfig.PackerConfig.ID: {
                DataProcessorConfig.PackerConfig casted = (DataProcessorConfig.PackerConfig)config;
                return(Tuple.Create <DataTypeBase, DataTypeBase>(dataProcessorCopy(this, attributes.dataProcessorCopyCopies(casted.count)), null));
            }

            case DataProcessorConfig.AccounterConfig.ID: {
                DataProcessorConfig.AccounterConfig casted = (DataProcessorConfig.AccounterConfig)config;
                return(Tuple.Create <DataTypeBase, DataTypeBase>(dataProcessorCopy(this, new DataAttributes(new byte[] { casted.length, attributes.length() }, 1, 0, attributes.signed)), null));
            }

            case DataProcessorConfig.FuserConfig.ID: {
                byte fusedLength = attributes.length();
                var  casted      = config as DataProcessorConfig.FuserConfig;

                foreach (var _ in casted.filterIds)
                {
                    fusedLength += dpModule.activeProcessors[_].Item1.attributes.length();
                }

                return(Tuple.Create <DataTypeBase, DataTypeBase>(new FusedDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, new DataAttributes(new byte[] { fusedLength }, 1, 0, attributes.signed)), null));
            }
            }
            throw new InvalidOperationException("Unable to determine the DataTypeBase object for config: " + Util.ArrayToHexString(config.Build()));
        }