Skip to content

Commit

Permalink
✨ Add the total usage time of Stream Deckin the UI + related fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
hexawyz committed Feb 9, 2025
1 parent 6aa625e commit 7d5b1f8
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 14 deletions.
File renamed without changes.
2 changes: 1 addition & 1 deletion Exo.sln
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{08303426-8
Docs\Razer DeathAdder Platform 3.md = Docs\Razer DeathAdder Platform 3.md
Docs\Razer DeathAdder V2 Pro.md = Docs\Razer DeathAdder V2 Pro.md
Docs\Razer Mamba Chroma.md = Docs\Razer Mamba Chroma.md
Docs\Stream Decl XL.md = Docs\Stream Decl XL.md
Docs\Useful Bits.md = Docs\Useful Bits.md
Docs\Stream Deck XL.md = Docs\Stream Deck XL.md
Docs\ViewSonic VP2785-4K.md = Docs\ViewSonic VP2785-4K.md
EndProjectSection
EndProject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ public async Task<uint> GetSleepTimerAsync(CancellationToken cancellationToken)
return ReadResponse(buffer.Span);
}

public async Task<ushort> GetUsageTimeAsync(CancellationToken cancellationToken)
public async Task<uint> GetUsageTimeAsync(CancellationToken cancellationToken)
{
// This command seems to return some status on the device.
// I saw one of the values increasing at some point, which was not related to a key press or any specific action from the official software, so the only explanation is that it is time.
Expand All @@ -213,8 +213,8 @@ public async Task<ushort> GetUsageTimeAsync(CancellationToken cancellationToken)

var buffer = FeatureBuffer;

static void PrepareRequest(Span<byte> buffer) => buffer[0] = 0x0A;
static ushort ReadResponse(ReadOnlySpan<byte> buffer) => LittleEndian.ReadUInt16(in buffer[2]);
static void PrepareRequest(Span<byte> buffer) => buffer[0] = 0x09;
static uint ReadResponse(ReadOnlySpan<byte> buffer) => LittleEndian.ReadUInt32(in buffer[5]);

PrepareRequest(buffer.Span);
await _stream.ReceiveFeatureReportAsync(buffer, cancellationToken).ConfigureAwait(false);
Expand Down
6 changes: 4 additions & 2 deletions src/Tools/StreamDeckPlayground/DesignMainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public sealed class StreamDeckDevice
public string DeviceName { get; }
public string SerialNumber { get; }
public string FirmwareVersion { get; }
public TimeSpan UsageTime { get; }
public int ButtonColumnCount { get; }
public int ButtonRowCount { get; }
public int ButtonImageWidth { get; }
Expand All @@ -19,11 +20,12 @@ public sealed class StreamDeckDevice
public ReadOnlyCollection<StreamDeckButton> Buttons { get; }
public StreamDeckButton? SelectedButton { get; set; }

public StreamDeckDevice(string deviceName, string serialNumber, string firmwareVersion, int buttonColumnCount, int buttonRowCount, int buttonImageWidth, int buttonImageHeight, int screensaverImageWidth, int screensaverImageHeight)
public StreamDeckDevice(string deviceName, string serialNumber, string firmwareVersion, TimeSpan usageTime, int buttonColumnCount, int buttonRowCount, int buttonImageWidth, int buttonImageHeight, int screensaverImageWidth, int screensaverImageHeight)
{
DeviceName = deviceName;
SerialNumber = serialNumber;
FirmwareVersion = firmwareVersion;
UsageTime = usageTime;
ButtonColumnCount = buttonColumnCount;
ButtonRowCount = buttonRowCount;
ButtonImageWidth = buttonImageWidth;
Expand Down Expand Up @@ -52,7 +54,7 @@ public sealed class StreamDeckButton

public DesignMainViewModel()
{
var device = new StreamDeckDevice(@"\\HID\Whatever", "SN0123456789", "42.42.42", 8, 4, 96, 96, 1024, 600);
var device = new StreamDeckDevice(@"\\HID\Whatever", "SN0123456789", "42.42.42", TimeSpan.FromDays(21, 8), 8, 4, 96, 96, 1024, 600);
Devices = new([device]);
SelectedDevice = device;
}
Expand Down
15 changes: 9 additions & 6 deletions src/Tools/StreamDeckPlayground/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,20 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Serial Number" Margin="0,6,0,6" VerticalAlignment="Center" />
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding SerialNumber}" Margin="0,6,0,6" VerticalAlignment="Center" />
<TextBlock Grid.Row="1" Text="Firmware Version" Margin="0,6,0,6" VerticalAlignment="Center" />
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding FirmwareVersion}" Margin="0,6,0,6" VerticalAlignment="Center" />
<TextBlock Grid.Row="2" Text="Grid Size" Margin="0,6,0,6" VerticalAlignment="Center" />
<TextBlock Grid.Row="2" Grid.Column="1" Margin="0,6,0,6" VerticalAlignment="Center"><Run Text="{Binding ButtonColumnCount, Mode=OneWay}" /><Run Text="x" /><Run Text="{Binding ButtonRowCount, Mode=OneWay}" /></TextBlock>
<TextBlock Grid.Row="3" Text="Button Size" Margin="0,6,0,6" VerticalAlignment="Center" />
<TextBlock Grid.Row="3" Grid.Column="1" Margin="0,6,0,6" VerticalAlignment="Center"><Run Text="{Binding ButtonImageWidth, Mode=OneWay}" /><Run Text="x" /><Run Text="{Binding ButtonImageHeight, Mode=OneWay}" /></TextBlock>
<TextBlock Grid.Row="4" Text="Screen Size" Margin="0,6,0,6" VerticalAlignment="Center" />
<TextBlock Grid.Row="4" Grid.Column="1" Margin="0,6,0,6" VerticalAlignment="Center"><Run Text="{Binding ScreensaverImageWidth, Mode=OneWay}" /><Run Text="x" /><Run Text="{Binding ScreensaverImageHeight, Mode=OneWay}" /></TextBlock>
<TextBlock Grid.Row="2" Text="Usage Time" Margin="0,6,0,6" VerticalAlignment="Center" />
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding UsageTime}" Margin="0,6,0,6" VerticalAlignment="Center" />
<TextBlock Grid.Row="3" Text="Grid Size" Margin="0,6,0,6" VerticalAlignment="Center" />
<TextBlock Grid.Row="3" Grid.Column="1" Margin="0,6,0,6" VerticalAlignment="Center"><Run Text="{Binding ButtonColumnCount, Mode=OneWay}" /><Run Text="x" /><Run Text="{Binding ButtonRowCount, Mode=OneWay}" /></TextBlock>
<TextBlock Grid.Row="4" Text="Button Size" Margin="0,6,0,6" VerticalAlignment="Center" />
<TextBlock Grid.Row="4" Grid.Column="1" Margin="0,6,0,6" VerticalAlignment="Center"><Run Text="{Binding ButtonImageWidth, Mode=OneWay}" /><Run Text="x" /><Run Text="{Binding ButtonImageHeight, Mode=OneWay}" /></TextBlock>
<TextBlock Grid.Row="5" Text="Screen Size" Margin="0,6,0,6" VerticalAlignment="Center" />
<TextBlock Grid.Row="5" Grid.Column="1" Margin="0,6,0,6" VerticalAlignment="Center"><Run Text="{Binding ScreensaverImageWidth, Mode=OneWay}" /><Run Text="x" /><Run Text="{Binding ScreensaverImageHeight, Mode=OneWay}" /></TextBlock>
</Grid>
</Expander>
<Expander Grid.Row="1" Header="Buttons" Margin="0,6,0,6" IsExpanded="True">
Expand Down
9 changes: 7 additions & 2 deletions src/Tools/StreamDeckPlayground/StreamDeckViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,31 @@ public static async Task<StreamDeckViewModel> CreateAsync(string deviceName, ush
var device = new StreamDeckDevice(new(deviceName), productId);
var serialNumber = await device.GetSerialNumberAsync(cancellationToken);
var firmwareVersion = await device.GetVersionAsync(cancellationToken);
uint usageTime = await device.GetUsageTimeAsync(cancellationToken);
var info = await device.GetDeviceInfoAsync(cancellationToken);
return new(deviceName, device, serialNumber, firmwareVersion, info);
return new(deviceName, device, serialNumber, firmwareVersion, usageTime, info);
}

private readonly string _deviceName;
private readonly StreamDeckDevice _device;
private readonly StreamDeckDeviceInfo _deviceInformation;
private readonly string _serialNumber;
private readonly string _firmwareVersion;
private readonly uint _usageTime;
private readonly ReadOnlyCollection<StreamDeckButtonViewModel> _buttons;
private StreamDeckButtonViewModel? _selectedButton;
private readonly ChannelWriter<(byte KeyIndex, Rgb24 Color)> _updateWriter;
private CancellationTokenSource? _cancellationTokenSource;
private readonly Task _executeUpdatesTask;

public StreamDeckViewModel(string deviceName, StreamDeckDevice device, string serialNumber, string firmwareVersion, StreamDeckDeviceInfo deviceInformation)
public StreamDeckViewModel(string deviceName, StreamDeckDevice device, string serialNumber, string firmwareVersion, uint usageTime, StreamDeckDeviceInfo deviceInformation)
{
_deviceName = deviceName;
_device = device;
_deviceInformation = deviceInformation;
_serialNumber = serialNumber;
_firmwareVersion = firmwareVersion;
_usageTime = usageTime;
_buttons = Array.AsReadOnly(Enumerable.Range(0, deviceInformation.ButtonCount).Select(i => new StreamDeckButtonViewModel(this, (byte)i)).ToArray());
var channel = Channel.CreateUnbounded<(byte KeyIndex, Rgb24 Color)>(new UnboundedChannelOptions() { SingleReader = true, SingleWriter = true, AllowSynchronousContinuations = false });
_updateWriter = channel;
Expand Down Expand Up @@ -83,6 +86,8 @@ private async Task ExecuteUpdatesAsync(ChannelReader<(byte KeyIndex, Rgb24 Color
public int ScreensaverImageWidth => _deviceInformation.ScreensaverImageWidth;
public int ScreensaverImageHeight => _deviceInformation.ScreensaverImageHeight;

public TimeSpan UsageTime => TimeSpan.FromHours(_usageTime);

public ReadOnlyCollection<StreamDeckButtonViewModel> Buttons => _buttons;

public StreamDeckButtonViewModel? SelectedButton
Expand Down

0 comments on commit 7d5b1f8

Please sign in to comment.