Official C# SDK for TofuPilot - Hardware Testing Platform (V2 API)
$ dotnet add package TofuPilotThe unofficial open-source C# SDK for TofuPilot. Quickly and seamlessly integrate all your hardware test runs into one app with just a few lines of C#.
Install via NuGet Package Manager:
dotnet add package TofuPilot
Or via Package Manager Console:
Install-Package TofuPilot
using TofuPilot;
// Create a client with your API key
using var client = new TofuPilotClient(apiKey: "your-api-key");
// List recent runs
var runs = await client.Runs.ListAsync(new ListRunsRequest { Limit = 10 });
// Create a new test run
var run = await client.Runs.CreateAsync(new CreateRunRequest
{
ProcedureId = "your-procedure-id",
Outcome = RunOutcome.PASS,
SerialNumber = "SN-001",
StartedAt = DateTimeOffset.UtcNow.AddMinutes(-5),
EndedAt = DateTimeOffset.UtcNow
});
Console.WriteLine($"Created run: {run.Id}");
The V2 API provides a clean, resource-based interface for all TofuPilot operations.
using TofuPilot;
// Basic usage
using var client = new TofuPilotClient(apiKey: "your-api-key");
// With custom base URL
using var client = new TofuPilotClient(
apiKey: "your-api-key",
baseUrl: "https://your-instance.tofupilot.com"
);
var request = new CreateRunRequest
{
ProcedureId = "proc-123",
Outcome = RunOutcome.PASS,
SerialNumber = "UNIT-001",
StartedAt = DateTimeOffset.UtcNow.AddMinutes(-10),
EndedAt = DateTimeOffset.UtcNow,
Phases = new List<CreateRunPhase>
{
new()
{
Name = "Voltage Test",
Outcome = PhaseOutcome.PASS,
StartTimeMillis = DateTimeOffset.UtcNow.AddMinutes(-10).ToUnixTimeMilliseconds(),
EndTimeMillis = DateTimeOffset.UtcNow.AddMinutes(-5).ToUnixTimeMilliseconds(),
Measurements = new List<CreateRunMeasurement>
{
new()
{
Name = "Output Voltage",
Outcome = MeasurementOutcome.PASS,
MeasuredValue = 5.02,
Units = "V",
LowerLimit = 4.8,
UpperLimit = 5.2
}
}
}
}
};
var run = await client.Runs.CreateAsync(request);
// List units
var units = await client.Units.ListAsync(new ListUnitsRequest { Limit = 20 });
// Create a unit
var unit = await client.Units.CreateAsync(new CreateUnitRequest
{
SerialNumber = "UNIT-001",
PartNumber = "PART-A"
});
// Add a child unit (for assemblies)
await client.Units.AddChildAsync(parentUnitId, new AddChildRequest
{
ChildId = childUnitId
});
// List procedures
var procedures = await client.Procedures.ListAsync(new ListProceduresRequest());
// Create a procedure
var procedure = await client.Procedures.CreateAsync(new CreateProcedureRequest
{
Name = "Battery Test",
Description = "Full battery charge/discharge cycle test"
});
// Create a version
var version = await client.Procedures.Versions.CreateAsync(
procedureId: procedure.Id,
new CreateVersionRequest { Name = "v1.0.0" }
);
The SDK supports ASP.NET Core dependency injection:
// In Program.cs or Startup.cs
services.AddTofuPilot(options =>
{
options.ApiKey = configuration["TofuPilot:ApiKey"];
options.BaseUrl = "https://www.tofupilot.com";
options.Retry = new RetryOptions
{
MaxRetries = 3,
InitialDelayMs = 1000,
MaxDelayMs = 30000
};
});
// In your service
public class TestRunService
{
private readonly TofuPilotClient _client;
public TestRunService(TofuPilotClient client)
{
_client = client;
}
public async Task<Run> CreateTestRunAsync(string serialNumber)
{
return await _client.Runs.CreateAsync(new CreateRunRequest
{
SerialNumber = serialNumber,
// ...
});
}
}
| Resource | Methods |
|---|---|
| Runs | ListAsync, CreateAsync, GetAsync, UpdateAsync, DeleteAsync |
| Units | ListAsync, CreateAsync, GetAsync, UpdateAsync, DeleteAsync, AddChildAsync, RemoveChildAsync |
| Procedures | ListAsync, CreateAsync, GetAsync, UpdateAsync, DeleteAsync |
| Procedures.Versions | ListAsync, CreateAsync, GetAsync, DeleteAsync |
| Parts | ListAsync, CreateAsync, GetAsync, UpdateAsync |
| Parts.Revisions | ListAsync, CreateAsync, GetAsync, UpdateAsync, DeleteAsync |
| Batches | ListAsync, CreateAsync, GetAsync, UpdateAsync, DeleteAsync |
| Stations | ListAsync, CreateAsync, GetAsync, UpdateAsync, RemoveAsync, LinkProcedureAsync, UnlinkProcedureAsync |
| Attachments | InitializeAsync, DeleteAsync |
The SDK throws specific exceptions for different error types:
using TofuPilot.Abstractions.Exceptions;
try
{
var run = await client.Runs.GetAsync("invalid-id");
}
catch (NotFoundException ex)
{
Console.WriteLine($"Run not found: {ex.Message}");
}
catch (UnauthorizedException ex)
{
Console.WriteLine($"Invalid API key: {ex.Message}");
}
catch (BadRequestException ex)
{
Console.WriteLine($"Invalid request: {ex.Message}");
Console.WriteLine($"Response body: {ex.ResponseBody}");
}
catch (TofuPilotException ex)
{
Console.WriteLine($"API error ({ex.StatusCode}): {ex.Message}");
}
| Exception | HTTP Status | Description |
|---|---|---|
BadRequestException | 400 | Invalid request parameters |
UnauthorizedException | 401 | Invalid or missing API key |
ForbiddenException | 403 | Access denied |
NotFoundException | 404 | Resource not found |
ConflictException | 409 | Resource conflict |
UnprocessableEntityException | 422 | Validation error |
RateLimitException | 429 | Rate limit exceeded |
InternalServerErrorException | 500 | Server error |
ServiceUnavailableException | 503 | Service unavailable |
Please read CONTRIBUTING.md for details on our code of conduct and the process for submitting pull requests.
This project is licensed under the MIT License - see the LICENSE file for details.