saveeye_flutter_sdk 0.0.2
saveeye_flutter_sdk: ^0.0.2 copied to clipboard
A Flutter SDK for integrating with SaveEye's device management platform. Provides GraphQL-based access to device data, monitoring, and management features.
SaveEye Flutter SDK #
The SaveEye Flutter SDK provides a Dart API to interact with SaveEye devices for provisioning over BLE, pairing, checking online status, querying historic usage, and subscribing to realtime readings.
Example app #
A complete Flutter example is available at https://github.com/saveeye/Flutter-SDK-Example
Installation #
Add the SDK to your pubspec.yaml
dependencies:
saveeye_flutter_sdk: ^x.y.z
Initialization #
import 'package:saveeye_flutter_sdk/saveeye_flutter_sdk.dart';
Future<String> getJwtToken() async {
// Return a fresh Firebase (or other) JWT for the current user
// e.g. await FirebaseAuth.instance.currentUser?.getIdToken() ?? '';
return '';
}
void main() {
SaveEyeClient.instance.initialize(
'APP_SDK_KEY',
getJwtToken,
// environment: SaveEyeEnvironment.prod, // default is prod
);
}
appSDKKey
: Your SDK key from the SaveEye Manager portal.onJWTRequest
: A callback that must return a fresh JWT when called.environment
: Optional. Defaults toSaveEyeEnvironment.prod
. This is for SaveEye internal development; partners should use production.
Provisioning #
Scan for nearby devices #
final devices = await SaveEyeClient.instance.getSaveEyeDevicesNearby();
// devices: List<String> of BLE names like 'SAVEEYE_XXXXXXXX'
Provision a device and list available Wi‑Fi networks #
Provide either a QR code string (containing the device id) or a BLE name (e.g., SAVEEYE_XXXXXXXX
).
final wifiSsids = await SaveEyeClient.instance.provisionDevice(
qrCodeOrBLEName,
/* externalId: */ null, // Optional: pair with this externalId; otherwise the JWT user is used
);
if (wifiSsids != null && wifiSsids.isNotEmpty) {
// Show available Wi‑Fi networks to the user
}
Provisioning status events
Listen to the provisioning status via a stream of StatusEvent
:
final sub = SaveEyeClient.instance.events.listen((event) {
// event.topic == SaveEyeClient.deviceStatusTopic
// event.stage is a ConnectionStage
});
ConnectionStage
values (in typical sequence):
fetchingDeviceConfig
fetchedDeviceConfig
searching
connected
pairing
paired
error
Connect device to Wi‑Fi #
await SaveEyeClient.instance.connectToWifi(
'SAVEEYE_XXXXXXXX', // BLE name
'YourSSID',
'YourPassphrase',
);
Pair a device #
final paired = await SaveEyeClient.instance.pairDevice(
qrCodeOrBLEName,
/* externalId: */ null, // Optional
);
Check if a device is online #
If a device is found via BLE it's not online and have to be onboarded via provisionDevice
final isOnline = await SaveEyeClient.instance.isDeviceOnline(qrCodeOrBLEName);
User devices #
Get my devices #
final myDevices = await SaveEyeClient.instance.getMyDevices();
for (final d in myDevices) {
// See MyDevice below (id, serial, alias, deviceType, ...)
}
// MyDevice response
class MyDevice {
String id;
String? alias;
String serial;
double allTimesHighConsumption;
double allTimesHighProduction;
bool hasProduction;
int? blinksPerKwh;
String? errorCode;
double rmsCurrentMaxPerPhaseAmpere;
DeviceType deviceType; // name, profile
List<IdOnly> remoteDevices; // id
IdOnly? baseDevice; // id
}
class DeviceType {
String name;
int? profile; // optional
}
class IdOnly {
String id;
}
Device data #
Historic usage #
import 'package:saveeye_flutter_sdk/gql/schema.graphql.dart' show Enum$IntervalType;
final start = DateTime.utc(2024, 1, 1);
final end = DateTime.utc(2024, 1, 31);
// interval: Enum$IntervalType.DAY | Enum$IntervalType.HOUR | Enum$IntervalType.MONTH
final energy = await SaveEyeClient.instance.getEnergyUsageHistory(
deviceId,
start,
end,
Enum$IntervalType.DAY,
);
final power = await SaveEyeClient.instance.getPowerUsageHistory(
deviceId,
start,
end,
Enum$IntervalType.HOUR,
);
// EnergyUsageHistory response
class EnergyUsageHistory {
String deviceId;
List<EnergyUsageSummary> energyUsageSummaries; // aggregationPeriod, consumed/produced
bool hasProduction;
String intervalType; // e.g., DAY, HOUR, MONTH
double peakEnergyProductionKWh;
double peakEnergyConsumptionKWh;
double lowestEnergyProductionKWh;
double lowestEnergyConsumptionKWh;
double totalEnergyConsumedKWh;
double totalEnergyProducedKWh;
double allTimesHighEnergyConsumedKWh;
double allTimesHighEnergyProducedKWh;
}
class EnergyUsageSummary {
DateTime aggregationPeriod; // UTC start of period
double energyConsumedKWh;
double energyProducedKWh;
}
// PowerUsageHistory response
class PowerUsageHistory {
String deviceId;
String intervalType; // e.g., DAY, HOUR, MONTH
List<PowerUsageSummary> powerUsageSummaries;
}
class PowerUsageSummary {
DateTime aggregationPeriod; // UTC start of period
double averageConsumptionWatt;
double maxConsumptionWatt;
double minConsumptionWatt;
double averageProductionWatt;
double maxProductionWatt;
double minProductionWatt;
}
Realtime #
Subscribe to realtime readings #
import 'package:saveeye_flutter_sdk/saveeye_flutter_sdk.dart';
await SaveEyeClient.instance.subscribeToRealtimeData(
deviceId,
(RealtimeReading? data, WebSocketErrorEvent? error) {
if (data != null) {
// Use data.currentConsumptionW.total, data.timestamp, etc.
} else if (error != null) {
// Handle websocket error
}
},
);
Unsubscribe #
await SaveEyeClient.instance.unsubscribeFromRealtimeData();
Platform permissions #
iOS #
Add the following to your Info.plist
:
<key>NSBluetoothAlwaysUsageDescription</key>
<string>Used for connecting to SaveEye devices</string>
If your app scans QR codes, also include:
<key>NSCameraUsageDescription</key>
<string>Camera access is needed for scanning QR codes</string>
Android #
Add required permissions to your app manifest:
<!-- BLE permissions for nearby device scanning -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- For Android 12+ -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- Camera permission for QR scanning (optional) -->
<uses-permission android:name="android.permission.CAMERA" />
On Android 12+, you must request runtime permissions for BLUETOOTH_SCAN
and BLUETOOTH_CONNECT
(and location on older versions). Use your preferred permissions package to prompt the user.
Notes #
- Passing either a QR code string (containing a device id) or a BLE name like
SAVEEYE_XXXXXXXX
is supported where indicated. The SDK resolves the device id internally.
Support #
For support or questions, please contact dst@saveeye.dk
.