![]() |
VOOZH | about |
dotnet add package FrameworkDotnet --version 0.3.147
NuGet\Install-Package FrameworkDotnet -Version 0.3.147
<PackageReference Include="FrameworkDotnet" Version="0.3.147" />
<PackageVersion Include="FrameworkDotnet" Version="0.3.147" />Directory.Packages.props
<PackageReference Include="FrameworkDotnet" />Project file
paket add FrameworkDotnet --version 0.3.147
#r "nuget: FrameworkDotnet, 0.3.147"
#:package FrameworkDotnet@0.3.147
#addin nuget:?package=FrameworkDotnet&version=0.3.147Install as a Cake Addin
#tool nuget:?package=FrameworkDotnet&version=0.3.147Install as a Cake Tool
FrameworkDotnet is a .NET library for talking to Framework laptop and desktop embedded controller APIs through the native framework-system Rust FFI layer.
The current managed API is intentionally small, but it is planned to expand over time toward broader coverage of the native framework-system functionality.
It provides a small managed API for:
The public API keeps the native fixed-slot snapshot shape from Rust for consistency, while also exposing count-aware enumerable properties and Units.NET quantities for unit-bearing values.
The project uses:
framework-system-ffi-extensions Rust repository for the native .NET FFI layer, with the upstream framework-system repository nested inside it as a submodule for the hardware access layercsbindgen to generate the low-level C# interop bindingsUnitsNet for public unit-bearing values such as temperature, fan speed, voltage, current, charge, and ratio valuesFrameworkDotnet API surface on top of those bindings so normal .NET callers do not need to work with pointers or unsafe codeThis library is intended for applications that run on machines with supported Framework hardware and the required embedded controller access available on the host operating system.
It is best validated with a small smoke-test console app on a real device, because most behavior depends on native library loading, driver availability, permissions, actual Framework hardware, and the installed BIOS and firmware versions on the target machine.
using FrameworkDotnet;
using FrameworkDotnet.Enums;
using Spectre.Console;
using System.Text;
using UnitsNet;
FrameworkSystem FrameworkSystem = new FrameworkSystem();
using var ec = FrameworkSystem.OpenDefaultEc();
while (true)
{
AnsiConsole.Clear();
var fanCapabilitiesSnapshot = ec.GetFanCapabilitiesSnapshot();
var powerSnapshot = ec.GetPowerSnapshot();
var thermalSnapshot = ec.GetThermalSnapshot();
// 1. Build the top section using a StringBuilder
var sysInfo = new StringBuilder();
sysInfo.AppendLine($"[cyan]Product:[/] {FrameworkSystem.GetProductName()}");
sysInfo.AppendLine($"[cyan]Platform:[/] {FrameworkSystem.GetPlatform()}");
sysInfo.AppendLine($"[cyan]Family:[/] {FrameworkSystem.GetPlatformFamily()}");
sysInfo.AppendLine();
sysInfo.AppendLine("[cyan bold]Driver support:[/]");
foreach (FrameworkEcDriver driver in Enum.GetValues<FrameworkEcDriver>())
{
bool isSupported = FrameworkSystem.IsDriverSupported(driver);
string color = isSupported ? "green" : "red";
sysInfo.AppendLine($" [teal]{driver}:[/] [{color}]{isSupported}[/]");
}
sysInfo.AppendLine();
sysInfo.AppendLine($"[cyan]Active driver:[/] {ec.GetActiveDriver()}");
sysInfo.AppendLine($"[cyan]Build info:[/] [grey]{ec.GetBuildInfo()}[/]");
var flash = ec.GetFlashSnapshot();
sysInfo.AppendLine($"[cyan]Flash:[/] {flash.CurrentImage}, [grey]RO=[/][yellow]{flash.RoVersion}[/], [grey]RW=[/][yellow]{flash.RwVersion}[/]");
// 2. Render the top section inside a Panel
AnsiConsole.Write(
new Panel(new Markup(sysInfo.ToString()))
.Header("[bold blue]System Information[/]")
.BorderColor(Color.Blue));
// 3. Render the Snapshots (as we did before)
var fanText = fanCapabilitiesSnapshot.ToString().Replace(", ", Environment.NewLine);
AnsiConsole.Write(
new Panel(fanText)
.Header("[bold magenta]Fan Capabilities Snapshot[/]")
.BorderColor(Color.Magenta));
var powerText = powerSnapshot.ToString().Replace(", ", Environment.NewLine);
AnsiConsole.Write(
new Panel(powerText)
.Header("[bold green]Power Snapshot[/]")
.BorderColor(Color.Green));
var thermalText = thermalSnapshot.ToString().Replace(", ", Environment.NewLine);
AnsiConsole.Write(
new Panel(thermalText)
.Header("[bold red]Thermal Snapshot[/]")
.BorderColor(Color.Red));
Thread.Sleep(10000);
}
<img width="939" height="1419" alt="image" src="https://github.com/user-attachments/assets/9e45e991-2cfa-4b30-bfda-d680f2cc9b88" />
The current public API is centered around two main entry points:
FrameworkSystem
IFrameworkEcConnection
Main snapshot types:
FrameworkEcFlashSnapshotFrameworkPowerSnapshotFrameworkBatterySnapshotFrameworkFanCapabilitiesSnapshotFrameworkThermalSnapshotFrameworkTemperatureSnapshotFrameworkFanSnapshotMain response types:
FrameworkSetFanRpmResponseFrameworkSetFanDutyResponseFrameworkRestoreAutoFanControlResponseThe public snapshot API intentionally stays aligned with the native Rust fixed-slot structs.
Examples:
FrameworkPowerSnapshot.Battery_0FrameworkThermalSnapshot.Temperature_0 through Temperature_7FrameworkThermalSnapshot.Fan_0 through Fan_3To make these snapshots easier to consume in normal .NET code, the library also exposes count-aware enumerable properties:
FrameworkPowerSnapshot.ReportedBatteriesFrameworkThermalSnapshot.ReportedTemperaturesFrameworkThermalSnapshot.ReportedFansThese enumerable properties return only the entries reported by the corresponding count field.
Public unit-bearing values use UnitsNet.
Examples:
UnitsNet.TemperatureUnitsNet.RotationalSpeedUnitsNet.RatioUnitsNet.ElectricPotentialUnitsNet.ElectricCurrentUnitsNet.ElectricChargeThis allows consumers to work with quantities directly instead of manually tracking raw unit conventions.
using FrameworkDotnet;
using FrameworkDotnet.Exceptions;
var frameworkSystem = new FrameworkSystem();
try
{
using var ec = frameworkSystem.OpenDefaultEc();
var thermal = ec.GetThermalSnapshot();
foreach (var temperature in thermal.ReportedTemperatures)
{
Console.WriteLine($"Temperature: {temperature.Temperature.DegreesCelsius}C ({temperature.State})");
}
foreach (var fan in thermal.ReportedFans)
{
Console.WriteLine($"Fan: {fan.Speed.RevolutionsPerMinute} RPM ({fan.FanState})");
}
}
catch (FrameworkEcResponseException ex)
{
Console.WriteLine($"EC response failure: {ex.Detail}");
Console.WriteLine($"Description: {ex.Description}");
}
catch (FrameworkTemperatureStateException ex)
{
Console.WriteLine($"Temperature state failure: {ex.TemperatureState}");
Console.WriteLine($"Description: {ex.Description}");
}
catch (FrameworkFanStateException ex)
{
Console.WriteLine($"Fan state failure: {ex.FanState}");
Console.WriteLine($"Description: {ex.Description}");
}
Public API methods throw specific managed exception types rather than requiring callers to inspect status codes.
Examples include:
FrameworkEcResponseException and its derived EC response exceptionsFrameworkInvalidFanIndexExceptionFrameworkBatteryStateException and derived battery state exceptionsFrameworkTemperatureStateException and derived temperature state exceptionsFrameworkFanStateException and derived fan state exceptionsWhen native context is available, exceptions attempt to include native descriptions and device error messages from the Rust layer. This diagnostic enrichment is best-effort and does not prevent the primary exception from being thrown if native message retrieval fails.
Add the package reference to your project:
<PackageReference Include="FrameworkDotnet" Version="0.1.0" />
UnitsNet is already a dependency of the library, so callers do not need to add separate unit types manually unless they want direct compile-time references in their own project code.
The repository normally builds the framework-system-ffi-extensions Rust repository before compiling the managed library.
Typical source build:
dotnet build framework-dotnet/framework-dotnet.csproj
If generated bindings and native assets are already supplied externally, you can skip the Rust build step:
dotnet build framework-dotnet/framework-dotnet.csproj /p:SkipRustBuild=true
framework_lib_ffi.dll asset to be available beside the application or in the packaged runtime-specific native layout.IsDriverSupported(...) should be treated as a runtime check.libframework_lib_ffi.so asset to be available beside the application or in the packaged runtime-specific native layout.Framework is a separate company and brand with its own copyrights and trademarks.
This project is an independent community project and is not affiliated with, endorsed by, or officially associated with Framework.
FrameworkThermalSnapshot.SensorCount because the Rust layer does not yet provide a dedicated sensor count value.FanIndex for clarity and traceability.| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.