mgth/LittleBigMouse · error · InvalidOperationException
Associate a Hisense VIDAA projector first.
Error message
Associate a Hisense VIDAA projector first.
What it means
HisenseVidaaService throws this InvalidOperationException from its Required() helper when a per-projector operation (e.g. PowerOnAsync and other commands) references a projector id whose stored configuration is missing or has no IP address. The service requires an associated (configured, IP-reachable) Hisense VIDAA projector before any device command can run. It is a precondition/state guard, not a network failure.
Solutions
- Complete the projector association flow first so the configuration has a valid IpAddress, then retry the call.
- Verify the projector id exists in the configuration store and that HisenseVidaaConfiguration.IpAddress is set before invoking service methods.
- Fix or re-create the configuration entry if the IP was lost (hand-edited file, migration, reset).
- In automation code, check the configuration for a non-empty IpAddress before calling service commands.
Example fix
// before
await service.PowerOnAsync(projectorId);
// after
var cfg = store.Get(projectorId);
if (cfg is null || string.IsNullOrWhiteSpace(cfg.IpAddress))
throw new InvalidOperationException("Projector not associated: run the VIDAA association flow first.");
await service.PowerOnAsync(projectorId); Defensive patterns
Strategy: validation
Validate before calling
var cfg = store.Get(projectorId);
bool associated = cfg is not null && !string.IsNullOrWhiteSpace(cfg.IpAddress);
if (!associated)
throw new InvalidOperationException("Associate the Hisense VIDAA projector (set its IP address) before issuing commands."); Type guard
static bool IsAssociated(HisenseVidaaConfiguration? c) =>
c is not null && !string.IsNullOrWhiteSpace(c.IpAddress); Try / catch
try
{
await service.PowerOnAsync(id);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Associate a Hisense VIDAA projector"))
{
// surface setup instructions to the user
} Prevention
- Always run the association/pairing flow before automating projector commands.
- Persist configurations through the store API instead of hand-editing files.
- Guard automation entry points with an IsAssociated check on the stored config.
When it happens
Trigger: Calling PowerOnAsync(id) (or any service method that calls Required(id)) when: the id is not present in _store; the stored HisenseVidaaConfiguration exists but IpAddress is null/empty/whitespace.
Common situations: User added the projector entry but never completed the association/pairing flow that sets the IP address; configuration was migrated or hand-edited and the IP field was lost; caller passes a stale id after the projector config was deleted; automation calls PowerOnAsync before the initial setup UI flow ran.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Enter the projector Wi-Fi MAC address first.
- Enter a valid projector IPv4 address.
- Could not find the network interface used to reach
- The VIDAA client certificate was not found.
- VIDAA rejected TLS. Select the PKCS#12 client certificate…
AI-assisted analysis of mgth/LittleBigMouse@7a42f01d47 (2026-09-16).
Data as JSON: /api/errors/6c9f8f234e53c54c.
Report an issue: GitHub.
Appendix: source
Thrown at LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/HisenseVidaa/HisenseVidaaService.cs:195
_store.Save(c);
}
/// <summary>
/// Slower burst than Tizen, and the trailing delay is kept: awaiting PowerOnAsync
/// therefore leaves the projector 150 ms to react before the caller reconnects.
/// </summary>
static readonly WakeOnLanOptions WakeOnLanBurst = new()
{
PacketCount = 3,
Port = 9,
DelayBetweenPackets = TimeSpan.FromMilliseconds(150),
DelayAfterLastPacket = true,
};
public Task PowerOnAsync(string id, CancellationToken ct = default)
{
var c=Required(id); if (string.IsNullOrWhiteSpace(c.MacAddress)) throw new InvalidOperationException("Enter the projector Wi-Fi MAC address first."); return WakeOnLan.SendAsync(c.MacAddress, WakeOnLanBurst, cancellationToken: ct);
}
HisenseVidaaConfiguration Required(string id) => _store.Get(id) is { } c && !string.IsNullOrWhiteSpace(c.IpAddress) ? c : throw new InvalidOperationException("Associate a Hisense VIDAA projector first.");
async Task<HisenseVidaaClient> ClientForAsync(string id, HisenseVidaaConfiguration configuration)
{
HisenseVidaaClient? previous = null;
HisenseVidaaClient client;
lock (_clientLock)
{
if (_clients.TryGetValue(id, out client!)
&& SameConnection(client.Configuration, configuration)) return client;
previous = client;
client = new HisenseVidaaClient(configuration);
_clients[id] = client;
}
if (previous is not null) await previous.DisposeAsync().ConfigureAwait(false);
return client;
}View on GitHub (pinned to 7a42f01d47)