Add Send/Recv gauges, fix tick loop to consume without BLE
- Four gauges: Send A/B (commanded) and Recv A/B (device-reported) - State.LastSentA/B tracks what would be sent after limiting - ConsumeTick always runs; only SendB0 gated on IsConnected - Stream queues drain correctly in dev mode (no box) - Tray icon hot state works without BLE connected - Removed strength text label, widened form to 420x360
This commit is contained in:
+73
-46
@@ -14,7 +14,6 @@ public class MainForm : Form
|
||||
readonly NotifyIcon _tray;
|
||||
readonly Label _lblBle;
|
||||
readonly Label _lblWs;
|
||||
readonly Label _lblStrength;
|
||||
readonly Label _lblDeviceName;
|
||||
readonly TextBox _txtDeviceName;
|
||||
readonly Button _btnConnect;
|
||||
@@ -25,10 +24,14 @@ public class MainForm : Form
|
||||
|
||||
bool _closingFromTray;
|
||||
|
||||
readonly ProgressBar _gaugeA;
|
||||
readonly ProgressBar _gaugeB;
|
||||
readonly Label _lblGaugeA;
|
||||
readonly Label _lblGaugeB;
|
||||
readonly ProgressBar _gaugeSendA;
|
||||
readonly ProgressBar _gaugeSendB;
|
||||
readonly ProgressBar _gaugeRecvA;
|
||||
readonly ProgressBar _gaugeRecvB;
|
||||
readonly Label _lblSendA;
|
||||
readonly Label _lblSendB;
|
||||
readonly Label _lblRecvA;
|
||||
readonly Label _lblRecvB;
|
||||
readonly TrackBar _limitBar;
|
||||
readonly Label _lblLimit;
|
||||
readonly CheckBox _chkScale;
|
||||
@@ -52,7 +55,7 @@ public class MainForm : Form
|
||||
_loopCts = new CancellationTokenSource();
|
||||
|
||||
Text = "Substation";
|
||||
ClientSize = new Size(360, 340);
|
||||
ClientSize = new Size(420, 360);
|
||||
FormBorderStyle = FormBorderStyle.FixedSingle;
|
||||
MaximizeBox = false;
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
@@ -62,7 +65,7 @@ public class MainForm : Form
|
||||
{
|
||||
Text = "BLE: searching...",
|
||||
Location = new Point(16, 16),
|
||||
Size = new Size(328, 20),
|
||||
Size = new Size(388, 20),
|
||||
Font = new Font(Font.FontFamily, 9, FontStyle.Bold)
|
||||
};
|
||||
|
||||
@@ -70,34 +73,27 @@ public class MainForm : Form
|
||||
{
|
||||
Text = "WS: idle",
|
||||
Location = new Point(16, 40),
|
||||
Size = new Size(328, 20),
|
||||
Size = new Size(388, 20),
|
||||
Font = new Font(Font.FontFamily, 9, FontStyle.Bold)
|
||||
};
|
||||
|
||||
_lblStrength = new Label
|
||||
{
|
||||
Text = "Strength: A=0 B=0",
|
||||
Location = new Point(16, 64),
|
||||
Size = new Size(328, 20)
|
||||
};
|
||||
|
||||
_lblDeviceName = new Label
|
||||
{
|
||||
Text = "Device:",
|
||||
Location = new Point(16, 90),
|
||||
Location = new Point(16, 66),
|
||||
Size = new Size(48, 20)
|
||||
};
|
||||
_txtDeviceName = new TextBox
|
||||
{
|
||||
Text = "47L121000",
|
||||
Location = new Point(68, 88),
|
||||
Location = new Point(68, 64),
|
||||
Size = new Size(160, 20)
|
||||
};
|
||||
|
||||
_btnConnect = new Button
|
||||
{
|
||||
Text = "Connect",
|
||||
Location = new Point(236, 88),
|
||||
Location = new Point(296, 64),
|
||||
Size = new Size(108, 24)
|
||||
};
|
||||
_btnConnect.Click += OnConnect;
|
||||
@@ -105,7 +101,7 @@ public class MainForm : Form
|
||||
_btnTest = new Button
|
||||
{
|
||||
Text = "Test",
|
||||
Location = new Point(16, 120),
|
||||
Location = new Point(16, 96),
|
||||
Size = new Size(100, 32)
|
||||
};
|
||||
_btnTest.Click += OnTest;
|
||||
@@ -113,7 +109,7 @@ public class MainForm : Form
|
||||
_btnMusic = new Button
|
||||
{
|
||||
Text = "Music",
|
||||
Location = new Point(130, 120),
|
||||
Location = new Point(130, 96),
|
||||
Size = new Size(100, 32)
|
||||
};
|
||||
_btnMusic.Click += OnMusic;
|
||||
@@ -121,7 +117,7 @@ public class MainForm : Form
|
||||
_btnStop = new Button
|
||||
{
|
||||
Text = "Stop All",
|
||||
Location = new Point(244, 120),
|
||||
Location = new Point(244, 96),
|
||||
Size = new Size(100, 32)
|
||||
};
|
||||
_btnStop.Click += OnStop;
|
||||
@@ -129,37 +125,67 @@ public class MainForm : Form
|
||||
_lblTrack = new Label
|
||||
{
|
||||
Text = "",
|
||||
Location = new Point(16, 158),
|
||||
Size = new Size(328, 16),
|
||||
Location = new Point(16, 134),
|
||||
Size = new Size(388, 16),
|
||||
ForeColor = Color.DimGray
|
||||
};
|
||||
|
||||
_lblGaugeA = new Label
|
||||
_lblSendA = new Label
|
||||
{
|
||||
Text = "A",
|
||||
Location = new Point(16, 180),
|
||||
Size = new Size(16, 20),
|
||||
Text = "Send A",
|
||||
Location = new Point(16, 160),
|
||||
Size = new Size(48, 20),
|
||||
Font = new Font(Font.FontFamily, 9, FontStyle.Bold)
|
||||
};
|
||||
_gaugeA = new ProgressBar
|
||||
_gaugeSendA = new ProgressBar
|
||||
{
|
||||
Location = new Point(40, 180),
|
||||
Size = new Size(304, 20),
|
||||
Location = new Point(72, 160),
|
||||
Size = new Size(332, 20),
|
||||
Minimum = 0,
|
||||
Maximum = 200,
|
||||
Style = ProgressBarStyle.Continuous
|
||||
};
|
||||
_lblGaugeB = new Label
|
||||
_lblSendB = new Label
|
||||
{
|
||||
Text = "B",
|
||||
Location = new Point(16, 208),
|
||||
Size = new Size(16, 20),
|
||||
Text = "Send B",
|
||||
Location = new Point(16, 184),
|
||||
Size = new Size(48, 20),
|
||||
Font = new Font(Font.FontFamily, 9, FontStyle.Bold)
|
||||
};
|
||||
_gaugeB = new ProgressBar
|
||||
_gaugeSendB = new ProgressBar
|
||||
{
|
||||
Location = new Point(40, 208),
|
||||
Size = new Size(304, 20),
|
||||
Location = new Point(72, 184),
|
||||
Size = new Size(332, 20),
|
||||
Minimum = 0,
|
||||
Maximum = 200,
|
||||
Style = ProgressBarStyle.Continuous
|
||||
};
|
||||
_lblRecvA = new Label
|
||||
{
|
||||
Text = "Recv A",
|
||||
Location = new Point(16, 212),
|
||||
Size = new Size(48, 20),
|
||||
Font = new Font(Font.FontFamily, 9, FontStyle.Bold)
|
||||
};
|
||||
_gaugeRecvA = new ProgressBar
|
||||
{
|
||||
Location = new Point(72, 212),
|
||||
Size = new Size(332, 20),
|
||||
Minimum = 0,
|
||||
Maximum = 200,
|
||||
Style = ProgressBarStyle.Continuous
|
||||
};
|
||||
_lblRecvB = new Label
|
||||
{
|
||||
Text = "Recv B",
|
||||
Location = new Point(16, 236),
|
||||
Size = new Size(48, 20),
|
||||
Font = new Font(Font.FontFamily, 9, FontStyle.Bold)
|
||||
};
|
||||
_gaugeRecvB = new ProgressBar
|
||||
{
|
||||
Location = new Point(72, 236),
|
||||
Size = new Size(332, 20),
|
||||
Minimum = 0,
|
||||
Maximum = 200,
|
||||
Style = ProgressBarStyle.Continuous
|
||||
@@ -168,14 +194,14 @@ public class MainForm : Form
|
||||
_lblLimit = new Label
|
||||
{
|
||||
Text = "Limit: 30",
|
||||
Location = new Point(16, 248),
|
||||
Location = new Point(16, 272),
|
||||
Size = new Size(64, 20),
|
||||
Font = new Font(Font.FontFamily, 9, FontStyle.Bold)
|
||||
};
|
||||
_limitBar = new TrackBar
|
||||
{
|
||||
Location = new Point(80, 244),
|
||||
Size = new Size(180, 45),
|
||||
Location = new Point(80, 268),
|
||||
Size = new Size(240, 45),
|
||||
Minimum = 0,
|
||||
Maximum = 200,
|
||||
TickFrequency = 50,
|
||||
@@ -185,14 +211,14 @@ public class MainForm : Form
|
||||
_chkScale = new CheckBox
|
||||
{
|
||||
Text = "Scale",
|
||||
Location = new Point(268, 248),
|
||||
Location = new Point(328, 272),
|
||||
Size = new Size(76, 24),
|
||||
Checked = false
|
||||
};
|
||||
_chkScale.CheckedChanged += OnLimitChanged;
|
||||
OnLimitChanged(null, EventArgs.Empty);
|
||||
|
||||
Controls.AddRange(new Control[] { _lblBle, _lblWs, _lblStrength, _lblDeviceName, _txtDeviceName, _btnConnect, _btnTest, _btnMusic, _btnStop, _lblTrack, _lblGaugeA, _gaugeA, _lblGaugeB, _gaugeB, _lblLimit, _limitBar, _chkScale });
|
||||
Controls.AddRange(new Control[] { _lblBle, _lblWs, _lblDeviceName, _txtDeviceName, _btnConnect, _btnTest, _btnMusic, _btnStop, _lblTrack, _lblSendA, _gaugeSendA, _lblSendB, _gaugeSendB, _lblRecvA, _gaugeRecvA, _lblRecvB, _gaugeRecvB, _lblLimit, _limitBar, _chkScale });
|
||||
|
||||
// Tray icon — three cached variants: neutral=gray, active=gold, hot=red-orange
|
||||
_iconNeutral = CreateVoltageIcon(Color.Gray);
|
||||
@@ -242,9 +268,9 @@ public class MainForm : Form
|
||||
{
|
||||
try
|
||||
{
|
||||
var (modeA, valA, modeB, valB, freqA, intA, freqB, intB) = _state.ConsumeTick();
|
||||
if (_device.IsConnected)
|
||||
{
|
||||
var (modeA, valA, modeB, valB, freqA, intA, freqB, intB) = _state.ConsumeTick();
|
||||
var frame = B0.Build(0, modeA, modeB, valA, valB, freqA, intA, freqB, intB);
|
||||
await _device.SendB0(frame);
|
||||
}
|
||||
@@ -331,9 +357,10 @@ public class MainForm : Form
|
||||
_lblBle.Text = _device.IsConnected
|
||||
? $"BLE: connected ({_device.DeviceName})"
|
||||
: "BLE: disconnected";
|
||||
_lblStrength.Text = $"Strength: A={_device.StrengthA} B={_device.StrengthB}";
|
||||
_gaugeA.Value = Math.Clamp(_device.StrengthA, 0, 200);
|
||||
_gaugeB.Value = Math.Clamp(_device.StrengthB, 0, 200);
|
||||
_gaugeSendA.Value = Math.Clamp(_state.LastSentA, 0, 200);
|
||||
_gaugeSendB.Value = Math.Clamp(_state.LastSentB, 0, 200);
|
||||
_gaugeRecvA.Value = Math.Clamp(_device.StrengthA, 0, 200);
|
||||
_gaugeRecvB.Value = Math.Clamp(_device.StrengthB, 0, 200);
|
||||
_btnTest.Enabled = !_server.HasClient && !IsTestRunning;
|
||||
_btnMusic.Enabled = !_server.HasClient && !_isMusicRunning;
|
||||
_btnStop.Enabled = true;
|
||||
|
||||
@@ -16,6 +16,7 @@ public class State
|
||||
public readonly ConcurrentQueue<WaveFrame> StreamB = new();
|
||||
|
||||
public int ActualA, ActualB;
|
||||
public int LastSentA, LastSentB;
|
||||
|
||||
public int MaxStrength = 200;
|
||||
public LimitMode LimitMode = LimitMode.Clamp;
|
||||
@@ -99,6 +100,8 @@ public class State
|
||||
: (byte)Math.Clamp(desired, 0, limit);
|
||||
var valA = ApplyLimit(DesiredA);
|
||||
var valB = ApplyLimit(DesiredB);
|
||||
LastSentA = valA;
|
||||
LastSentB = valB;
|
||||
DirtyA = false;
|
||||
DirtyB = false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user