.NET SDK
Async pagination, typed IoT models, Machines service.
Install
Fetching ...
NuGet
Fetching package info…
Initialize Client
var client = new SeshatClient(apiKey, secret, new SeshatClientOptions {
Host = "localhost", // seshat host
Company = "<company>"
});
Sensors
var fo = client.Sensors.FindOpts();
fo.Name = "temp"; fo.Tag = "critical"; fo.All = true;
await client.Sensors.FindEachPageAsync(fo, (items, total, page, limit) => {
// items page
return true;
});
var q = client.Sensors.IoTQueryOptions()
.SensorId("sensor123")
.PerPage(50)
.SortByDateDesc();
var data = await client.Sensors.GetIoTDataAsync(q);
if (data?.Items != null){ foreach (var it in data.Items){ /* it.Value */ } }
Function behaviors: FindAsync fetches a single page plus totals. FindEachPageAsync iterates pages invoking your handler until all pages covered or handler returns false; iteration stops on errors or empty results. FindHandlerAsync (not shown) gives pagination metadata only for progress tracking. IoT endpoints (GetIoTDataAsync, GetIoTDataChangesAsync) accept an IoTQueryOptions builder: omit any property to skip its query parameter. Extension methods (SortByDateDesc(), etc.) set paired sort fields atomically. CancellationTokens allow mid-iteration aborts; always pass them in long-running UI loops.
Returns
Find / FindEachPage callbacks return sensor models and pagination info.
IEnumerable<Sensor>: list of sensorsint total: total count across all pagesint page,int limit: current page metadata
Sensor properties (C#)
Id(string),Name(string),Key(string)Company(string),Machine(string),Collector(string)Tags(List<string>),IsDeleted(bool)CreationDate(long),DataType(int)LatestValue(SensorValue),LatestChange(SensorValue)Generative(bool),SendOnlyChange(bool)
SensorValue
Date(string),Type(int),Value(object)
FindOptions parameters
Name: Case-insensitive substring match on names.Key: Exact key filter (unique key when available).Tag: Comma-separated tags; matches any (e.g."prod,critical").Machine/Collector: Filter by machine/collector id or name (aliases).Limit: Page size; API default if null. Ignored whenAll == true.Page: 1-based page index for manual paging. Ignored with handlers or whenAll == true.All: Auto-paginate across all pages. OverridesLimit/Page.
Notes: filters are combined with AND; the server may cap maximum page size; the same options are available on the Machines service.
IoTQueryOptions (C#) – fluent extensions
SensorId(string)Page(int),PerPage(int)Start(string),End(string)Value(string),Min(double),Max(double)SortBy("date"|"value"),SortOrder("asc"|"desc")or shortcutsSortByDateDesc(), etc.
Returns
FindAsync(opts)→ItemListResponse<Sensor>(Data,Total,Page,Limit)FindEachPageAsync(opts, handler)→ handler gets (IEnumerable<Sensor> items, int total, int page, int limit)
Sensor properties
Id(string),Name(string),Key(string)Company(string),Machine(string),Collector(string)Tags(List<string>),IsDeleted(bool)CreationDate(long),DataType(int)LatestValue(SensorValue),LatestChange(SensorValue)Generative(bool),SendOnlyChange(bool)
SensorValue
Date(string),Type(int),Value(object)
IoTDataRecord
Timestamp,Value,Metadata(dictionary / null)
Machines
var mo = new MachinesService.FindOptions{ Tag = "production" };
var res = await client.Machines.FindAsync(mo);
var list = res?.Data; var total = res?.Total ?? 0;
Machines service mirrors sensor search semantics: apply filters, retrieve single page + totals. Use combined with Sensors to scope queries to machine-specific sensor subsets.
Returns
IEnumerable<Machine>: list of machinesint total: total count
Machine struct fields (C#)
Id(string)Collector(string)Company(string)Name(string)Key(string)Tags(List<string>)CreatedBy(string)CreationDate(long)SendMqttDirect(bool)
FindOptions summary
Name,Key,TagCollector/MachineLimit,Page,All
Live
// Direct live streaming via Sensors service (resilient)
await client.Sensors.LiveWithAsync(null, null, (sensorId, value, type) => {
Console.WriteLine($"{sensorId}: {value}");
});
Resilient streaming auto-reconnects with exponential backoff and falls back to polling when repeated failures occur. Customize LiveStreamOptions for retry limits, backoff, jitter, and polling intervals. Use Filter to pre-filter values and OnFallbackActivated to observe fallback events.
Data Types (type → C# value)
In live tuples, type is the type id and value is deserialized to:
1→int,2→uint3→sbyte,4→byte5→short,6→ushort7→int,8→uint9→long,10→ulong11→double12→DateTime(ISO)13→string14→int[]15→byte[]16→bool17→Dictionary<string,object>18→List<Dictionary<string,object>>19→object(raw JSON)22→string
IoT Data
var q = client.Sensors.IoTQueryOptions()
.SensorId("sensor-1")
.PerPage(100)
.SortByDateDesc()
.Start("2024-01-01T00:00:00Z")
.End("2024-01-02T00:00:00Z");
var data = await client.Sensors.GetIoTDataAsync(q);
var changes = await client.Sensors.GetIoTDataChangesAsync(q);
if (data?.Items != null) {
foreach (var rec in data.Items) {
// rec.Timestamp, rec.Value, rec.Metadata
}
}
Returns
GetIoTDataAsync(query)→IoTDataResponse(Items,Ok,Page,PerPage,Total,SensorIds)GetIoTDataChangesAsync(query)→ same shape with changes timeline
IoTDataRecord
Timestamp(string, ISO)Value(object)Metadata(IoTDataMetadata or null)
IoTDataMetadata
CompanyId(string),Machine(string),Sensor(string)Change(bool)BeforeChangeData(IoTDataChangeMeta),ChangeData(IoTDataChangeMeta)TogetherTrigger(string)TogetherValues(Dictionary<string,object>)
IoTDataChangeMeta
Start(string),End(string)DurationMS(long)StartValue(object),EndValue(object)IncValue(double),DecValue(double)StartId(string)
Connections
Each sensor is associated with a connection. The endpoints a sensor reads from or writes to are referred to as connections. Examples include an MQTT client or a PostgreSQL database. To publish to an MQTT connection with parameters (e.g., topic), use a WriteItem and set Parameters.
// Advanced: boolean write with 'topic' parameter
var item = new SeshatSdk.Services.ConnectionsService.WriteItem {
AnyValue = new { value = true },
Type = 16, // bool
Parameters = new List {
new() { Key = "topic", Value = System.Text.Encoding.UTF8.GetBytes("67333c8d615f8c6cd6f07c38/67333c8d615f8c6cd6f07c39") }
}
};
await client.Connections.WriteItemAsync("mqtt://0.0.0.0:8888", item);
Events
var resp = await client.Events.TriggerAsync("rebuild-cache", new { fast = true });
var list = await client.Events.ListAsync();
Error handling
try {
var fo = client.Sensors.FindOpts();
var page = await client.Sensors.FindAsync(fo);
} catch (HttpRequestException ex) {
// network issue -> log, maybe retry
} catch (TaskCanceledException) {
// timeout/cancellation
}
try {
var q = client.Sensors.IoTQueryOptions().SensorId("sensor123").PerPage(100).SortByDateDesc();
var data = await client.Sensors.GetIoTDataAsync(q);
} catch (Exception ex) {
// parse or transport error
}