nut_client 0.1.0
nut_client: ^0.1.0 copied to clipboard
A pure Dart client library for the NUT (Network UPS Tools) protocol. Connect to NUT servers, monitor UPS devices, and control power management.
// Using print for example output demonstration.
// ignore_for_file: avoid_print
import 'dart:async';
import 'package:nut_client/nut_client.dart';
/// Example usage of the nut_client library.
///
/// This example demonstrates:
/// 1. Basic connection and querying UPS devices
/// 2. Getting specific variables
/// 3. Authentication for privileged operations
/// 4. Watching variables with built-in polling
/// 5. Error handling
Future<void> main() async {
// Example 1: Basic Usage
await basicUsageExample();
// Example 2: With Configuration
await configuredClientExample();
// Example 3: Polling for Updates
await pollingExample();
// Example 4: Error Handling
await errorHandlingExample();
}
/// Basic usage example with simple client creation.
Future<void> basicUsageExample() async {
print('=== Basic Usage Example ===\n');
// Create a client with default settings
final client = NutTcpClient.simple('192.168.1.10');
try {
// Connect to the NUT server
await client.connect();
print('Connected to NUT server');
// List all UPS devices
final devices = await client.listUps();
print('Found ${devices.length} UPS device(s):');
for (final device in devices) {
print(' - ${device.name}: ${device.description}');
}
// Get variables for the first UPS
if (devices.isNotEmpty) {
final upsName = devices.first.name;
// List all variables
final variables = await client.listVariables(upsName);
print('\nVariables for $upsName:');
for (final variable in variables.take(5)) {
print(' ${variable.name} = ${variable.value}');
}
// Get specific important variables
print('\nKey metrics:');
final status = await client.getVariable(upsName, 'ups.status');
print(' Status: ${status.value}');
final charge = await client.getVariable(upsName, 'battery.charge');
print(' Battery: ${charge.intValue}%');
final runtime = await client.getVariable(upsName, 'battery.runtime');
final minutes = (runtime.intValue ?? 0) ~/ 60;
print(' Runtime: $minutes minutes');
}
} on ConnectionException catch (e) {
print('Connection failed: ${e.userMessage}');
} on CommandException catch (e) {
print('Command failed: ${e.userMessage}');
} finally {
await client.dispose();
print('\nDisconnected');
}
}
/// Example with full configuration including TLS and authentication.
Future<void> configuredClientExample() async {
print('\n=== Configured Client Example ===\n');
// Create a client with full configuration
final client = NutTcpClient(
const NutClientConfig(
host: '192.168.1.10',
useTls: true, // Enable TLS encryption
credentials: Credentials(
username: 'admin',
password: 'secret',
),
),
);
try {
// Connect - will automatically use TLS and authenticate
await client.connect();
print('Connected with TLS and authenticated');
// Now we can use privileged commands
final devices = await client.listUps();
if (devices.isNotEmpty) {
final upsName = devices.first.name;
// List writable variables
final rwVars = await client.listWritableVariables(upsName);
print('Writable variables:');
for (final v in rwVars) {
print(' ${v.name} = ${v.value}');
}
// List available commands
final commands = await client.listCommands(upsName);
print('\nAvailable commands:');
for (final cmd in commands) {
print(' ${cmd.name}');
}
// Execute a command (uncomment to actually run)
// await client.runCommand(upsName, 'beeper.toggle');
// print('Beeper toggled!');
// Set a variable (uncomment to actually set)
// await client.setVariable(upsName, 'ups.delay.shutdown', '120');
// print('Shutdown delay set to 120 seconds');
}
} on AuthenticationException catch (e) {
print('Authentication failed: ${e.userMessage}');
} on ConnectionException catch (e) {
print('Connection failed: ${e.userMessage}');
} finally {
await client.dispose();
}
}
/// Example of watching variables with built-in polling.
Future<void> pollingExample() async {
print('\n=== Polling Example ===\n');
final client = NutTcpClient.simple('192.168.1.10');
try {
await client.connect();
print('Connected, starting to watch battery.charge...');
// Watch a single variable with 5-second polling interval
final subscription = client.watchVariable(
'myups',
'battery.charge',
interval: const Duration(seconds: 5),
).listen(
(variable) {
print('Battery charge: ${variable.value}%');
},
onError: (Object error) {
print('Watch error: $error');
},
);
// Let it run for a few polling cycles
await Future<void>.delayed(const Duration(seconds: 12));
// Stop watching
await subscription.cancel();
print('Stopped watching');
// Alternative: Watch all variables
print('\nWatching all variables...');
final allVarsSubscription = client.watchVariables(
'myups',
).listen((variables) {
print('Received ${variables.length} variables');
final status = variables.firstWhere(
(v) => v.name == 'ups.status',
orElse: () => const UpsVariable(name: 'ups.status', value: 'unknown'),
);
print(' Status: ${status.value}');
});
await Future<void>.delayed(const Duration(seconds: 5));
await allVarsSubscription.cancel();
} on ConnectionException catch (e) {
print('Connection failed: ${e.userMessage}');
} finally {
await client.dispose();
}
}
/// Example of proper error handling.
Future<void> errorHandlingExample() async {
print('\n=== Error Handling Example ===\n');
final client = NutTcpClient.simple('192.168.1.10');
try {
await client.connect();
// Try to get a variable from a non-existent UPS
try {
await client.getVariable('nonexistent', 'ups.status');
} on CommandException catch (e) {
print('Expected error for unknown UPS:');
print(' Error code: ${e.errorCode}');
print(' User message: ${e.userMessage}');
}
// Try to get a non-existent variable
try {
await client.getVariable('myups', 'nonexistent.var');
} on CommandException catch (e) {
print('\nExpected error for unknown variable:');
print(' Error code: ${e.errorCode}');
print(' User message: ${e.userMessage}');
}
// Try to execute a command without authentication
try {
await client.setVariable('myups', 'ups.delay.shutdown', '120');
} on AuthenticationException catch (e) {
print('\nExpected error for unauthorized access:');
print(' Error code: ${e.errorCode}');
print(' User message: ${e.userMessage}');
} on CommandException catch (e) {
// Some servers might return a command error instead
print('\nCommand error: ${e.userMessage}');
}
} on NutException catch (e) {
// Catch-all for any NUT-related errors
print('NUT error: ${e.userMessage}');
} finally {
await client.dispose();
}
}