A library for communication with solar power inverters of the RCT power brand. This library is designed to interface with RCT power inverters using JavaScript.
RCT power is a registered trademark of RCT Power GmbH. This library is not provided by, endorsed by, supported by, or affiliated with the company in any way.
This library is a Java adaptation of the original Go-based library developed by Markus Noga, enhanced with additional features.
It is provided without any warranties, entirely for use at your own risk under an LGPL 2.1 license.
This project is based on the work of Markus Noga. His Go-based library can be found at https://github.com/mlnoga/rct. I thank Markus Noga for his valuable contribution to the community. Likewise, thanks to Stefan Valouch for his extensive insights and documentation provided with his project available at https://github.com/svalouch/python-rctclient that have contributed to the completion of this project.
To use the rctjavalib library in your project, you can install it via npm:
npm install rctjavalibAfter installation, you can import and use the library in your JavaScript project:
const Connection = require('rctjavalib/connection.js');
const { Identifier, SOCStrategy } = require('rctjavalib/datagram.js');
// Establish a connection
const conn = new Connection('192.168.1.100', 8899); // Host, Port
await conn.connect();
// Example: Query the power generated by Solar Generator A
const power = await conn.query(Identifier.SOLAR_GEN_A_POWER_W);
console.log(`Solar generator A power: ${Math.round(power)} W`);
// Example: Set inverter to charge battery from grid
await conn.write(Identifier.POWER_MNG_SOC_STRATEGY, SOCStrategy.EXTERNAL);
await conn.write(Identifier.POWER_MNG_BATTERY_POWER_EXTERN_W, -6000);
await conn.write(Identifier.POWER_MNG_USE_GRID_POWER_ENABLE, true);
console.log(`Charge Battery with 6000W from Power Grid`);
// Example: Set inverter to charge battery from solar
await conn.write(Identifier.POWER_MNG_SOC_STRATEGY, SOCStrategy.INTERNAL);
await conn.write(Identifier.POWER_MNG_BATTERY_POWER_EXTERN_W, 0);
await conn.write(Identifier.POWER_MNG_USE_GRID_POWER_ENABLE, false);
console.log(`Standard Battery Charge from Solar`);
// Example: Set inverter to not discharge the battery
await conn.write(Identifier.POWER_MNG_SOC_STRATEGY, SOCStrategy.EXTERNAL);
await conn.write(Identifier.POWER_MNG_BATTERY_POWER_EXTERN_W, 0);
await conn.write(Identifier.POWER_MNG_USE_GRID_POWER_ENABLE, true);
console.log(`Discharge Lock activated`);
// Close the connection when done
conn.close();This example demonstrates how to establish a connection, query the power generated by Solar Generator A, and then close the connection. You can use similar methods to query or update other data points by referencing the appropriate identifiers from the Identifier class in datagram.js.
For efficient and robust communication, rctjavalib supports transparent connection pooling. This allows you to reuse the same connection instance for each inverter (host:port), reducing overhead and ensuring consistent communication.
Use pooling as follows:
const Connection = require('rctjavalib/connection.js');
const { Identifier } = require('rctjavalib/datagram.js');
// Obtain a pooled connection (recommended)
const conn = Connection.getPooledConnection('192.168.1.100', 8899, 5000); // Host, Port, [cacheDurationMs]
await conn.connect();
const power = await conn.query(Identifier.SOLAR_GEN_A_POWER_W);
console.log(`Solar generator A power: ${Math.round(power)} W`);
conn.close();- Multiple calls to getPooledConnection with the same host and port will always return the same instance (until .close() is called).
- For non-pooled connections, you can still use new Connection(...).
-
datagram.js:- Defines constants for commands, identifiers, and datagram packet structures.
- Provides mappings for enums like SOC strategies and inverter states.
- Includes validation logic for writable identifiers to prevent invalid commands and ensure safe interactions.
-
crc.js:- Implements the cyclic redundancy check (CRC) algorithm to validate data integrity for datagrams.
- Ensures reliable communication by detecting data corruption during transmission.
-
build.js:- Handles datagram construction, ensuring compliance with protocol requirements such as BigEndian formatting.
- Escapes special bytes where required by the protocol.
-
parse.js:- Parses incoming data into structured datagrams using a state-machine-based approach.
- Handles escaped bytes and verifies CRC to ensure data integrity.
- Provides detailed error messages for recoverable parsing failures.
-
connection.js:- Manages the bidirectional connection with the inverter.
- Integrates datagram builders and parsers for seamless communication.
- Implements caching to reduce redundant queries and improve performance.
- Provides high-level methods for querying and writing to the inverter, ensuring safety and validation.
- Supports efficient connection pooling via getPooledConnection for robust, resource-friendly usage.
-
cache.js:- Implements a caching mechanism to store and reuse recent datagrams.
- Automatically expires entries based on configurable timeouts and cache size to optimize resource usage.
- Cleans up outdated or least recently used entries when the cache exceeds its size limit.
-
recoverable.js:- Defines a
RecoverableErrorclass to handle transient errors (e.g., parsing failures, network issues, or retries). - Includes utility functions to determine if an error is recoverable, allowing for automatic retry mechanisms.
- Defines a
The library uses Jest for testing. To run tests, use the following command:
npm testContributions are welcome! Please fork the repository, create a feature branch, and submit a pull request. Make sure to include tests for any new functionality.