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); } } }
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)); }
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())); }