feat: basic cluster overview

This commit is contained in:
2025-08-24 21:08:40 +02:00
commit 4ab19e9ded
616 changed files with 69980 additions and 0 deletions

147
src/client/README.md Normal file
View File

@@ -0,0 +1,147 @@
# SPORE API Client
A JavaScript client for the SPORE Embedded System API, generated from the OpenAPI specification.
## Installation
```bash
npm install
```
## Usage
### Basic Setup
```javascript
const SporeApiClient = require('./index');
// Create client instance with default base URL
const client = new SporeApiClient();
// Or specify a custom base URL
const client = new SporeApiClient('http://192.168.1.100');
```
### API Methods
#### Task Management
```javascript
// Get comprehensive task status
const taskStatus = await client.getTaskStatus();
// Control individual tasks
await client.controlTask('heartbeat', 'disable');
await client.controlTask('discovery_send', 'start');
await client.controlTask('status_update', 'status');
```
#### System Status
```javascript
// Get system status and API information
const systemStatus = await client.getSystemStatus();
// Get device information
const deviceInfo = await client.getDeviceInfo();
```
#### Cluster Management
```javascript
// Get cluster discovery information
const discovery = await client.getClusterDiscovery();
// Get cluster status
const clusterStatus = await client.getClusterStatus();
```
#### Network Management
```javascript
// Get network configuration
const networkConfig = await client.getNetworkConfig();
// Update network configuration
await client.updateNetworkConfig({
wifi: {
ssid: 'MyNetwork',
password: 'password123'
}
});
// Scan for WiFi networks
const networks = await client.getWifiNetworks();
// Connect to WiFi network
await client.connectWifi('MyNetwork', 'password123');
```
#### System Health
```javascript
// Get OTA update status
const otaStatus = await client.getOtaStatus();
// Get health metrics
const healthMetrics = await client.getHealthMetrics();
// Get system logs
const logs = await client.getSystemLogs({
level: 'INFO',
limit: 100,
offset: 0
});
```
#### Device Control
```javascript
// Restart the device
await client.restartDevice();
// Factory reset (use with caution!)
await client.factoryReset();
```
### Error Handling
```javascript
try {
const status = await client.getTaskStatus();
console.log('Task status:', status);
} catch (error) {
console.error('API request failed:', error.message);
}
```
### Response Format
All API methods return promises that resolve to the response data. The client automatically:
- Parses JSON responses
- Handles HTTP error status codes
- Provides meaningful error messages
- Supports both CommonJS and ES modules
## API Endpoints
The client supports all endpoints defined in the OpenAPI specification:
- **Task Management**: `/api/tasks/status`, `/api/tasks/control`
- **System Status**: `/api/node/status`
- **Cluster Management**: `/api/cluster/discovery`, `/api/cluster/status`
- **OTA Updates**: `/api/ota/status`
- **Health Monitoring**: `/api/health/metrics`
- **System Logs**: `/api/system/logs`
- **Network Management**: `/api/network/config`, `/api/network/wifi/*`
- **Device Control**: `/api/device/info`, `/api/device/restart`, `/api/device/factory-reset`
## Requirements
- Node.js 18.0.0 or higher
- Fetch API support (built-in for Node.js 18+)
## License
MIT License - see LICENSE file for details.

74
src/client/example.js Normal file
View File

@@ -0,0 +1,74 @@
/**
* Example usage of the SPORE API Client
*/
const SporeApiClient = require('./index');
async function main() {
// Create client instance
const client = new SporeApiClient('http://10.0.1.60');
console.log('🚀 SPORE API Client Example');
console.log('============================\n');
try {
// Example 1: Get system status
console.log('1. Getting system status...');
const systemStatus = await client.getSystemStatus();
console.log('✅ System Status:', JSON.stringify(systemStatus, null, 2));
console.log('');
// Example 2: Get task status
console.log('2. Getting task status...');
const taskStatus = await client.getTaskStatus();
console.log('✅ Task Status:', JSON.stringify(taskStatus, null, 2));
console.log('');
// Example 3: Get device information
console.log('3. Getting device information...');
const deviceInfo = await client.getDeviceInfo();
console.log('✅ Device Info:', JSON.stringify(deviceInfo, null, 2));
console.log('');
// Example 4: Get cluster discovery
console.log('4. Getting cluster discovery...');
const discovery = await client.getClusterDiscovery();
console.log('✅ Cluster Discovery:', JSON.stringify(discovery, null, 2));
console.log('');
// Example 5: Get network configuration
console.log('5. Getting network configuration...');
const networkConfig = await client.getNetworkConfig();
console.log('✅ Network Config:', JSON.stringify(networkConfig, null, 2));
console.log('');
// Example 6: Get health metrics
console.log('6. Getting health metrics...');
const healthMetrics = await client.getHealthMetrics();
console.log('✅ Health Metrics:', JSON.stringify(healthMetrics, null, 2));
console.log('');
// Example 7: Get system logs (limited to 5 entries)
console.log('7. Getting recent system logs...');
const logs = await client.getSystemLogs({ limit: 5 });
console.log('✅ System Logs:', JSON.stringify(logs, null, 2));
console.log('');
console.log('🎉 All API calls completed successfully!');
} catch (error) {
console.error('❌ Error occurred:', error.message);
if (error.message.includes('fetch')) {
console.log('\n💡 Make sure the SPORE device is running and accessible at the specified IP address.');
console.log('💡 Check if the device is powered on and connected to the network.');
}
}
}
// Run the example if this file is executed directly
if (require.main === module) {
main().catch(console.error);
}
module.exports = { main };

205
src/client/index.js Normal file
View File

@@ -0,0 +1,205 @@
/**
* SPORE API Client
* Generated from api/openapi.yaml
*/
class SporeApiClient {
constructor(baseUrl = 'http://10.0.1.60') {
this.baseUrl = baseUrl;
this.defaultHeaders = {
'Content-Type': 'application/json',
'Accept': 'application/json'
};
}
/**
* Make an HTTP request
* @param {string} method - HTTP method
* @param {string} path - API path
* @param {Object} options - Request options
* @returns {Promise<Object>} Response data
*/
async request(method, path, options = {}) {
const url = `${this.baseUrl}${path}`;
const config = {
method,
headers: { ...this.defaultHeaders, ...options.headers },
...options
};
try {
const response = await fetch(url, config);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
// Handle empty responses
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
return await response.json();
}
return await response.text();
} catch (error) {
throw new Error(`Request failed: ${error.message}`);
}
}
/**
* Get comprehensive task status
* @returns {Promise<Object>} Task status response
*/
async getTaskStatus() {
return this.request('GET', '/api/tasks/status');
}
/**
* Control individual task operations
* @param {string} task - Name of the task to control
* @param {string} action - Action to perform (enable, disable, start, stop, status)
* @returns {Promise<Object>} Task control response
*/
async controlTask(task, action) {
const formData = new URLSearchParams();
formData.append('task', task);
formData.append('action', action);
return this.request('POST', '/api/tasks/control', {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: formData.toString()
});
}
/**
* Get system status and API information
* @returns {Promise<Object>} System status response
*/
async getSystemStatus() {
return this.request('GET', '/api/node/status');
}
/**
* Get cluster discovery information
* @returns {Promise<Object>} Cluster discovery response
*/
async getClusterDiscovery() {
return this.request('GET', '/api/cluster/members');
}
/**
* Get cluster status
* @returns {Promise<Object>} Cluster status response
*/
async getClusterStatus() {
return this.request('GET', '/api/cluster/members');
}
/**
* Get OTA update status
* @returns {Promise<Object>} OTA update status response
*/
async getOtaStatus() {
return this.request('GET', '/api/ota/status');
}
/**
* Get system health metrics
* @returns {Promise<Object>} Health metrics response
*/
async getHealthMetrics() {
return this.request('GET', '/api/health/metrics');
}
/**
* Get system logs
* @param {Object} options - Query options
* @returns {Promise<Object>} System logs response
*/
async getSystemLogs(options = {}) {
const queryParams = new URLSearchParams();
if (options.level) queryParams.append('level', options.level);
if (options.limit) queryParams.append('limit', options.limit);
if (options.offset) queryParams.append('offset', options.offset);
const queryString = queryParams.toString();
const path = queryString ? `/api/system/logs?${queryString}` : '/api/system/logs';
return this.request('GET', path);
}
/**
* Get network configuration
* @returns {Promise<Object>} Network configuration response
*/
async getNetworkConfig() {
return this.request('GET', '/api/network/config');
}
/**
* Update network configuration
* @param {Object} config - Network configuration
* @returns {Promise<Object>} Update response
*/
async updateNetworkConfig(config) {
return this.request('POST', '/api/network/config', {
body: JSON.stringify(config)
});
}
/**
* Get WiFi networks
* @returns {Promise<Object>} WiFi networks response
*/
async getWifiNetworks() {
return this.request('GET', '/api/network/wifi/scan');
}
/**
* Connect to WiFi network
* @param {string} ssid - Network SSID
* @param {string} password - Network password
* @returns {Promise<Object>} Connection response
*/
async connectWifi(ssid, password) {
return this.request('POST', '/api/network/wifi/connect', {
body: JSON.stringify({ ssid, password })
});
}
/**
* Get device information
* @returns {Promise<Object>} Device info response
*/
async getDeviceInfo() {
return this.request('GET', '/api/device/info');
}
/**
* Restart the device
* @returns {Promise<Object>} Restart response
*/
async restartDevice() {
return this.request('POST', '/api/device/restart');
}
/**
* Factory reset the device
* @returns {Promise<Object>} Factory reset response
*/
async factoryReset() {
return this.request('POST', '/api/device/factory-reset');
}
}
// Export the client class
module.exports = SporeApiClient;
// Also export for ES modules if available
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = SporeApiClient;
}
}

27
src/client/package.json Normal file
View File

@@ -0,0 +1,27 @@
{
"name": "spore-api-client",
"version": "1.0.0",
"description": "JavaScript client for the SPORE Embedded System API",
"main": "index.js",
"type": "commonjs",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"spore",
"api",
"client",
"embedded",
"iot",
"esp8266"
],
"author": "SPORE Development Team",
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"repository": {
"type": "git",
"url": "https://git.dcentral.systems/iot/spore"
}
}