Integration guide
About this guide
This is a technical guide for connecting physical battery systems to the Tensor Cloud battery optimization service. It is aimed at:
- System integrators implementing battery optimization solutions
- EMS developers building gateway connections to Tensor Cloud
- Technical stakeholders responsible for energy storage system operations
This guide consists of two parts: The guide itself, and communication protocol specifications in AsyncAPI format. The guide provides an overview of the integration process, technical requirements, and operational responsibilities. The AsyncAPI specification contains detailed message schemas, telemetry requirements, and command structures.
We highly recommend making yourself familiar with the AsyncAPI specification before starting the integration process, as it contains all necessary details on the communication protocol, and guidance on automatic client code generation.
Before building an integration with Tensor Cloud, make sure you contact our technical team for detailed guidance and for getting access to a Tensor Cloud development workspace.
About Tensor Cloud
The battery optimization API enables automated, intelligent management of battery energy storage systems through real-time communication between Tensor Cloud's optimization engine and on-site Energy Management Systems (EMS). It aims to maximize the value of battery storage systems by creating economically optimal charge/discharge schedules.
It does this by aggregating technical signals from the battery system and other on-site hardware, and combining them with economic signals from electricity markets and other sources to arrive at an economically optimized battery operating schedule.
For the physical control of the battery system, and for collecting site telemetry, Tensor Cloud relies on EMS operated and provisioned by specialized providers. While Tensor Energy has a number of established partners that can handle physical integration at any scale, we are vendor agnostic within the limits of technical feasibility.
System overview
Note that Tensor Cloud currently only supports a single battery, solar system, and electrical load per site.
Use cases
Tensor Cloud supports three main use cases for battery optimization: AC-link, DC-link, and stand-alone.
Each use case has different requirements when it comes to required telemetry data that the EMS needs to send. Refer to the telemetry section for details.
AC-linked battery systems
This is often the case for retrofit FIP-conversion projects where the original solar topology cannot be fundamentally changed without losing FIT/FIP certification. The battery and solar system exchange energy through their respective inverters, with an optional on-site electrical load also connected via AC.
DC-linked battery systems
In DC-linked systems, the battery and solar PV are connected on the DC side, allowing for more efficient energy transfer. An optional on-site electrical load is also supported. This use-case is common in new installations where the system can be designed from the ground up to optimize for battery integration.
Stand-alone battery systems
Stand-alone battery systems are not co-located with solar or electrical loads. They often operate as merchant systems for exclusive participation in energy markets.
Technical requirements
Communication
The communication protocol used by Tensor Cloud for battery optimization is MQTT (Message Queuing Telemetry Transport) 3.1.1 over TLS 1.2+. This protocol is designed for lightweight, reliable pub/sub information exchange between the EMS and Tensor Cloud.
Endpoints
The Tensor Cloud battery optimization service is accessible via the following MQTT broker endpoints:
Testing environment: mqtt.staging.tensorenergy.jp:8883
Production environment: mqtt.tensorenergy.jp:8883
The testing environment is used during the integration development phase and for post-integration testing. The production environment is used for live operations once the integration is complete and validated.
Authentication
Tensor Cloud uses X.509 certificates for secure authentication with our MQTT broker. Each EMS gateway or software application must have its own unique certificate. Your technical contact at Tensor Energy will provide certificates for development and production environments on request within 24 hours.
Certificates are scoped to specific topics on the MQTT broker, which means that each certificate can only publish and subscribe to the topics it is authorized for. This ensures that your EMS can only interact with the data and commands relevant to the site it is installed at.
QoS (Quality of Service)
Tensor Cloud supports MQTT QoS levels 0 and 1 for message delivery. This means that messages are delivered at most once (QoS 0) or at least once (QoS 1). If your client library supports QoS 1, explicit acknowledgement messages are not required, as the MQTT protocol will handle message delivery guarantees.
MQTT topics
All communication between the EMS and Tensor Cloud is done through MQTT topics in a publish/subscribe fashion. The topic structure is designed to be intuitive and follows a hierarchical format based on site and device identifiers.
Overview
Telemetry
Site hardware telemetry (e.g., site meter discharge, solar generation, battery SoE) is published by the EMS using a unified dt/
topic prefix, followed by the site ID, gateway ID, and an ending specific to the type of telemetry (lifetime, windowed, instantaneous), resulting in the following formats:
Lifetime metric topic structure:
dt/{siteId}/{gatewayId}/{metric}/lifetime
Windowed metric topic structure:
dt/{siteId}/{gatewayId}/{metric}/energy/{window}
Instantaneous metric topic structure:
dt/{siteId}/{gatewayId}/{metric}/power
The Site ID and Gateway ID are unique identifiers assigned to each site and its associated EMS gateway. They will be provided to you by your technical contact at Tensor Energy together with each set of certificates.
For a list of telemetry types and their definitions, see the tables below and the protocol schema.
Units
All energy units in the tables below can be expressed as
- energy over time in kWh over a fixed window (e.g., 30 minutes)
- increasing sum of the total (similar to an electricity meter) in kWh
- instantaneous power in kW
It is required for any EMS to send either (1) or (2) for the Tensor Cloud optimization engine to work correctly. Instantaneous power (3) can be sent in addition to 1 or 2 to improve results for some use-cases, but not as a replacement.
Common to all use cases
Telemetry name | Required/Optional | Description |
---|---|---|
meter_export_ac | 🔴 Required | Amount of energy exported to the grid measured at the main site meter. |
meter_import_ac | 🔴 Required | Amount of energy imported from the grid measured at the main site meter. |
battery_soe | 🔴 Required | State of Energy (SoE) in kWh of the battery system. This is the amount of energy currently stored in the battery. |
battery_energy_remaining | 🔴 Required | Remaining energy capacity of the battery system in kWh at nominal temperature (usually ~25°C) including cell degradation and faulty cells. This is the amount of energy the battery can hold at a maximum. |
grid_to_load_ac | ⚪️ Optional | Amount of energy sent from the site meter to an on-site electrical load (e.g., factory). Required if on-site load exists. |
load_demand_ac | ⚪️ Optional | Total amount of energy consumed by an on-site electrical load (e.g., factory). Sum of grid_to_load_ac and either battery_to_load_ac for AC-link, or inverter_to_load_kwh for DC-link. Required if on-site load exists. |
curtailment | ⚪️ Optional | Curtailment schedule by the TSO captured by the EMS from the on-site curtailment device. |
AC-linked battery systems
Telemetry name | Required/Optional | Description |
---|---|---|
solar_net_generation_ac | 🔴 Required | Solar generation after subtracting curtailment. Sum of solar_to_load_ac , solar_to_battery_ac , and solar_to_grid_ac . |
battery_charge_ac | 🔴 Required | Amount of energy charged into the battery system, usually measured at the battery meter or monitoring system. Sum of grid_to_battery_ac and solar_to_battery_ac . |
battery_discharge_ac | 🔴 Required | Amount of energy discharged from the battery system, usually measured at the battery meter or monitoring system. Sum of battery_to_grid_ac and battery_to_load_ac . |
solar_to_grid_ac | ⚪️ Optional | Amount of energy sent directly from the solar system to the site meter. |
solar_to_battery_ac | ⚪️ Optional | Amount of energy sent from the solar system to the battery. |
solar_to_load_ac | ⚪️ Optional | Amount of energy sent from the solar system to an on-site electrical load (e.g., factory). |
battery_to_grid_ac | ⚪️ Optional | Amount of energy sent from the battery to the grid measured at the main site meter. |
battery_to_load_ac | ⚪️ Optional | Amount of energy sent from the battery to an on-site electrical load (e.g., factory). |
grid_to_battery_ac | ⚪️ Optional | Amount of grid energy sent to the battery measured at the main site meter. |
DC-linked battery systems
Telemetry name | Required/Optional | Description |
---|---|---|
solar_generation_dc | 🔴 Required | Amount of energy generated by the solar system measured on the DC side. Sum of solar_to_battery_dc and solar_to_inverter_dc . |
battery_charge_dc | 🔴 Required | Amount of energy charged into the battery system measured on the DC side. Sum of solar_to_battery_dc and inverter_to_battery_dc . |
battery_to_inverter_dc | 🔴 Required | Amount of energy sent from the battery to the site inverter. Measured on the DC side. |
inverter_net_output_ac | ⚪️ Optional | Net output of the site inverter. This is the amount of energy sent from the inverter to the grid minus the amount of energy received from the grid. Measured on the AC side. Sum of inverter_to_load_ac and inverter_to_grid_ac . Required in case of an on-site electrical load. |
solar_to_battery_dc | ⚪️ Optional | Amount of energy sent from the solar system to the battery. Measured on the DC side. |
solar_to_inverter_dc | ⚪️ Optional | Amount of energy sent from the solar system to the site inverter. Measured on the DC side. |
inverter_to_battery_dc | ⚪️ Optional | Amount of energy sent from the inverter to the battery. Measured on the DC side. |
inverter_to_load_ac | ⚪️ Optional | Amount of energy sent from the inverter to an on-site electrical load (e.g., factory). Measured on the AC side. Required if on-site load exists. |
inverter_to_grid_ac | ⚪️ Optional | Amount of energy sent from the inverter to the grid. Measured on the AC side. |
grid_to_inverter_ac | ⚪️ Optional | Amount of grid energy sent to the inverter. Measured on the AC side. Required if the battery system can charge from the grid. |
Stand-alone battery systems
Stand-alone battery systems only require the telemetry listed in the "Common to all use cases" section above.
Commands
Commands (e.g., containing charge/discharge schedules for the battery) are sent by Tensor Cloud using a unified cmd/
topic prefix, followed by the site ID and command type, resulting in the following format:
cmd/{siteId}/battery/power
For a list of command types and their definitions, see the protocol schema.
Payload format
All messages published to the MQTT broker use JSON format. The payload structure is defined in the protocol schema, which includes telemetry messages and command formats expressed in JSON schema. The schema provides detailed definitions for each message type, including required fields, data types, and validation rules.
Schedule prioritization
Tensor Cloud sends battery charge/discharge schedules in multiple layers or priority: Every 30 minutes a schedule covering the next 3 hours is sent with the highest priority (2). Every 6 hours a schedule covering the next 48 hours is sent with a medium priority (1). On a weekly basis, a fallback schedule covering the next year is sent with the lowest priority (0).
When interpreting the schedules, the EMS must adhere to the following rules:
- Execute higher priority over lower priority schedules
- If schedules covering the same time period have the same priority, execute the most recent one
Message timing
The EMS should publish new telemetry data at least every 10 minutes, preferably more frequently. Different types of telemetry should be published independently from each other as they become available.
The only two telemetry types that can be published less frequently are battery_energy_remaining
, and curtailment
. Curtailment schedules should be published as they become available from the TSO, and battery_energy_remaining
should be published at least once per day.
- Immediate publishing for alarm conditions or significant state changes
Error handling
Telemetry errors
In case the EMS is unable to send site telemetry data to Tensor Cloud (e.g., due to malformed commands or communication issues), the EMS application logic should follow these guidelines:
- Retain telemetry data locally and attempt retransmission when the network is available
- Log the error details for analysis
- Implement exponential backoff strategies to avoid rate limits on the MQTT broker
- Prioritize recent telemetry data over sending retained data in bulk
Command errors
If the EMS receives a command that it cannot process (e.g., due to malformed JSON or unsupported parameters), or, if it does not receive any command schedule (e.g., due to communication issues), it should:
- Respond in the
res/{siteId}/command
topic with an appropriate error message - Continue executing the previous valid schedule until the error is resolved in order of priority and time
Error Codes
The protocol uses standardized error codes across all error surfaces:
MESSAGE_MALFORMED
: Message is not valid JSONMISSING_FIELD
: Required field is missingTYPE_MISMATCH
: Field has incorrect typeFIELD_OUT_OF_RANGE
: Numeric value outside valid rangeTIME_WINDOW_INVALID
: Invalid time window or schedule (e.g., start time is after end time)DUPLICATE
: Duplicate message or identifier (e.g., message with same id sent twice)EXPIRED
: Message or command has expired (e.g., schedule starts and ends in the past)RESOURCE_UNAVAILABLE
: Required resource is unavailable (e.g., connection between EMS and battery system is severed)INTERNAL_ERROR
: Internal system error not covered by other error types
Error Surfaces
- CommandResponse.errors[]: Machine-actionable command execution results
- TelemetryFeedback.code: Validation error codes (staging only)
Testing environment
To make it easier for EMS integrators to validate their implementation, Tensor Cloud provides a testing environment. The differences between the production and testing environments are:
- Complete isolation in terms of data and operations between both environments
- In testing, Tensor Cloud will respond to all telemetry messages from EMS devices with an explicit
error
/ok
response in topicres/{siteId}/{gatewayId}/telemetry
Responsibility model
Tensor Cloud works under a shared responsibility model with its partners and battery system owners. Each party has specific roles and responsibilities in the integration and operation of the battery optimization service.
Party | Responsibilities |
---|---|
Tensor Energy | • Economic optimization and schedule generation • Soft guarantees of battery system owner preferences (e.g., min/max SoE) |
Integrator/EMS | • EMS uptime management and guarantees in alignment with battery owner • Accurate telemetry reading from site hardware according to the protocol specifications • Local enforcement of TSO constraints (e.g., battery ramp rates, curtailment, data logging requirements) • Hard guarantees of battery system owner preferences (e.g., min/max SoE) • Emergency response and EMS hardware fault handling |
Battery system owner | • Imbalance responsibility (depending on contract terms, this could be shared with Tensor Energy) • Relationship management with TSO and other stakeholders like OCCTO (depending on contract terms, this could be shared with Tensor Energy) |
Battery OEM | • Hardware maintenance and support (depending on contract terms with battery system owner) • Battery firmware updates and bug fixes |
Implementation process
1. Initial reach out
If you are interested in integrating with Tensor Cloud's battery optimization service, please start by contacting us through our website contact form. Our team will get back to you with a schedule for an initial meeting to discuss the details of your integration project. Depending on the complexity of your use case, multiple meetings may be required at this point.
We also recommend early conversations, involving Tensor Energy representatives, with the battery system owner to discuss their operational and economic requirements, and any specific constraints that may affect the integration process.
2. Certificate setup
After the initial meeting, our technical team will provide you with an initial set of development X.509 certificates for secure authentication with our staging MQTT broker.
3. Integration phase
Depending on the maturity and flexibility of your EMS solution, expect the integration process to take anywhere from a few days to several months. During that process, our technical team can provide support for establishing an initial connection to our MQTT broker, and for answering any questions the communication protocol.
If there are any customizations required on our end, our team will synchronize this work with your development timeline to the best of our ability.
4. Testing and validation
Once the initial integration is complete, we will coordinate with you to perform integration testing. This includes
- Validating telemetry data publishing
- Testing command processing and response
- Ensuring proper error handling and recovery mechanisms
Contact your technical representative at Tensor Energy for details on the testing process.
Resources
- AsyncAPI schema file: Download JSON
- Protocol specifications: Online documentation