Solis Cloud API using JavaScript scripting

Inspired from SolisCloudAPI_Postman/inverterDay.js at main · Alexandra-Burlacu/SolisCloudAPI_Postman · GitHub , I have created a JSRule for getting the data from SolisCloud API.

var getData = function () {

  let log = require('openhab').log('my_logger');
  // Define credentials and API details
  const keyId = ""; // API KeyId
  const keySecret = ""; // Secret key associated with Key ID
  const baseUrl = "https://www.soliscloud.com:13333"; // Base URL for SolisCloud API
  const path = "/v1/api/inverterDetail"; // Specific endpoint for daily inverter data
  const currency = "EUR"; // Currency for the power plant; modify as needed

  const date = new Date();
  const gmtDate = date.toUTCString();
  const today = date.toISOString().split('T')[0];
  const timeZoneMinutes = date.getTimezoneOffset();
  const timeZone = timeZoneMinutes / 60;

  // Prepare request body with required fields
  var requestBody = {
    sn: "", // Inverter serial number; only provide one of 'sn' or 'id'
    money: currency,
    time: today, // Date in string format, YYYY-MM-DD
    timeZone: timeZone // Time zone offset
  };

  // Convert request body to JSON string for MD5 hashing
  const requestBodyStr = JSON.stringify(requestBody);

  const CryptoJS = require('crypto-js');

  // Calculate Content-MD5 for body integrity verification
  const md5Hash = CryptoJS.MD5(requestBodyStr);
  const contentMd5 = CryptoJS.enc.Base64.stringify(md5Hash);

  // Create string for HMAC-SHA1 signing (for Authorization header)
  const paramString = `POST\n${contentMd5}\napplication/json\n${gmtDate}\n${path}`;

  // Perform HMAC-SHA1 signing to authenticate the request
  const hmacSha1 = CryptoJS.HmacSHA1(paramString, keySecret);
  const signature = CryptoJS.enc.Base64.stringify(hmacSha1);

  // Configure the POST request options
  const URL = `${baseUrl}${path}`;
  var header = new Map();
  header.set('Authorization', `API ${keyId}:${signature}`);
  header.set('Date', gmtDate);
  header.set('Content-MD5', contentMd5)

  // Send the POST request
  const response = actions.HTTP.sendHttpPostRequest(URL, actions.HTTP.CONTENT_TYPE_JSON, requestBodyStr, header, 15000);
  if (response !== null && response != "" && response !== undefined) {
    const parsed = JSON.parse(response);
    // console.log(parsed);
    if (parsed.success == true) {
      const solarEnergy = parsed.data.eToday;
      const solarPower = parsed.data.pac;
      const batteryPower = parsed.data.batteryPower;
      const batterySoC = parsed.data.batteryCapacitySoc;

      const SolisInverter_SolarPower = items.getItem("SolisInverter_SolarPower");
      const SolisInverter_SolarEnergy = items.getItem("SolisInverter_SolarEnergy");
      const Battery_SoC = items.getItem("Battery_SoC");
      const Battery_Power = items.getItem("Battery_Power");

      try {
        SolisInverter_SolarPower.postUpdate(solarPower);
        SolisInverter_SolarEnergy.postUpdate(solarEnergy);
        Battery_SoC.postUpdate(batterySoC);
        Battery_Power.postUpdate(batteryPower);
      } catch (error) {
        log.error(error);
      }
    }
  }
}

rules.JSRule({
  name: "Get Soliscloud data",
  description: "Updates inverter and battery items",
  triggers: [triggers.GenericCronTrigger("0 */5 * ? * *")],
  execute: (event) => {
    getData()
  }
});

I think the crypto-js package can be replaced by Java.type('java.security.MessageDigest'). But I haven’t tried.

This is a good candidate for a rule template. The advantage of rule templates for end users is that they just install it like an add-on and then instantiate a rule filling in the properties (e.g. the name of Items). instead of needing to do copy/paste/edit.

Thanks for the tip. I will follow your post to make a rule template for this.