internal ushort BatchCommand(PayLoadBuilder payLoadBuilder, int index) { ushort byteLength = 0; if (!MonitorEvents || ValueChanged == null) { return(byteLength); // no need to poll data } switch (Mode) { case BatteryMode.All: return(UIReadMethods.GetBatteryValue_BatchCommand(payLoadBuilder, index)); case BatteryMode.Level: { DataType type = UIReadMethods.GetBatteryLevel_BatchCommand(payLoadBuilder, index); return(type.ByteLength()); } } return(byteLength); }
public void StartEventMonitor(Brick brick) { Dictionary <int, InputPort> inputPorts = brick.IOPort.Input.Ports; Buttons buttons = brick.Buttons; Battery battery = brick.Battery; BrickConsole console = brick.Console; int INTERVAL = Brick.Options.EventMonitor.Interval; Task task = Task.Factory.StartNew(async() => { while (!_socket.CancellationToken.IsCancellationRequested) { try { //do not overload event message pump if (_socket.EventBuffer.Count == 0) { byte[] batch = null; ushort index = 0; ushort buttonByteLength = 0; ushort batteryByteLength = 0; ushort warningByteLength = 0; Dictionary <InputPort, DataType> triggeredPorts = new Dictionary <InputPort, DataType>(); using (PayLoadBuilder cb = new PayLoadBuilder()) { foreach (int key in inputPorts.Keys) { InputPort port = inputPorts[key]; if (port.Status != PortStatus.OK) { continue; // no device connected so continue } InputDevice device = (InputDevice)port.Device; if (!device.MonitorEvents) { continue; // device will get value on manual poll } DataType type = device.BatchCommand(cb, index); // get batchcommand if (type == DataType.NONE) { continue; } index += type.ByteLength(); triggeredPorts.Add(port, type); } buttonByteLength = buttons.BatchCommand(cb, index); index += buttonByteLength; batteryByteLength = battery.BatchCommand(cb, index); index += batteryByteLength; warningByteLength = console.BatchCommand(cb, index); index += warningByteLength; batch = cb.ToBytes(); } //no need to send batch, it has no content. if (batch.Length == 0) { try { await Task.Delay(INTERVAL, _socket.CancellationToken); } catch (TaskCanceledException) { } continue; } Command cmd = null; using (CommandBuilder cb = new CommandBuilder(CommandType.DIRECT_COMMAND_REPLY, index, 0, useEventId: true)) { cb.Raw(batch); cmd = cb.ToCommand(); } Response response = await Brick.Socket.Execute(cmd, true); if (response.Type == ResponseType.ERROR) { continue; } byte[] data = response.PayLoad; if (data.Length != index) { if (!_socket.CancellationToken.IsCancellationRequested) { throw new FirmwareException(response); } else { continue; } } index = 0; foreach (InputPort port in triggeredPorts.Keys) { InputDevice device = (InputDevice)port.Device; bool hasChanged = false; DataType type = triggeredPorts[port]; switch (type) { case DataType.DATA8: { hasChanged = device.SetDeviceValue(data[index]); break; } case DataType.DATAF: { hasChanged = device.SetDeviceValue(BitConverter.ToSingle(data, index)); break; } case DataType.DATA32: { hasChanged = device.SetDeviceValue(BitConverter.ToInt32(data, index)); break; } case DataType.DATA16: { hasChanged = device.SetDeviceValue(BitConverter.ToInt16(data, index)); break; } case DataType.DATA_A4: { byte[] values = new byte[4]; Array.Copy(data, index, values, 0, 4); hasChanged = device.SetDeviceValue(values); break; } } index += type.ByteLength(); } if (buttonByteLength > 0) { byte[] buttonData = new byte[buttonByteLength]; Array.Copy(data, index, buttonData, 0, buttonByteLength); buttons.BatchCommandReturn(buttonData); index += buttonByteLength; } if (batteryByteLength > 0) { byte[] batteryData = new byte[batteryByteLength]; Array.Copy(data, index, batteryData, 0, batteryByteLength); battery.SetValue(batteryData); index += batteryByteLength; } if (warningByteLength > 0) { console.SetValue(data[index]); index += warningByteLength; } } } catch (Exception e) { Brick.Logger.LogError(e, e.Message); } try { await Task.Delay(INTERVAL, _socket.CancellationToken); } catch (TaskCanceledException) { } } }, _socket.CancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current); }