Skip to content

Instantly share code, notes, and snippets.

@Thomptronics
Created September 20, 2024 21:15
Show Gist options
  • Save Thomptronics/efd17b8326cf6291b65fe24add2c38c6 to your computer and use it in GitHub Desktop.
Save Thomptronics/efd17b8326cf6291b65fe24add2c38c6 to your computer and use it in GitHub Desktop.
Example JavaScript module for turning on or off an EcoFlow SHP1 discharge job
// https://developer.ecoflow.com/us/document/generalInfo
// https://www.npmjs.com/package/@ecoflow-api/rest-client
// https://rustyy.github.io/ecoflow-api/modules/_ecoflow_api_rest_client.html
import {RestClient} from '@ecoflow-api/rest-client';
const ecoflowAPI = new RestClient({
accessKey: "ENTERYOURACCESSKEYHERE",
secretKey: "ENTERYOURSECRETKEYHERE",
host: "https://api-a.ecoflow.com" // use api-e.ecoflow.com for the EU area
});
// leave deviceName blank if you haven't named your device or if you only have one device of deviceType
async function getDeviceSerialNumber(deviceType, deviceName) {
console.log("Searching for " + deviceType + " " + (deviceName ? `(${deviceName})` : "") + "...");
let results;
const payload = await ecoflowAPI.getDevicesPlain();
console.log("Device List:", payload);
const deviceList = payload.data;
if (deviceList && Array.isArray(deviceList)) {
for (let i in deviceList) {
let entry = deviceList[i];
if (entry["productName"]===deviceType && (!deviceName || entry["deviceName"]===deviceName)) {
results = entry["sn"];
console.log("...found this:", results);
break;
}
}
}
if (!results) {console.log("...device not found!");}
return results;
}
// onOff = true or false (or 1 or 0) to turn discharge job on or off
// circuits = 10-element array of 0s and 1s denoting which circuits to use; leave blank to affect all circuits
// deviceName = leave blank if you only own one SHP1; otherwise, specify which SHP1 by providing its name here
async function dischargeJob(onOff, circuits, deviceName) {
let today = new Date();
let dischargeParams = {
"cfgIndex": 0,
"cfg": {
"chSta": (circuits && Array.isArray(circuits) && circuits.length===10) ? circuits : [1,1,1,1,1,1,1,1,1,1],
"comCfg": {
"timeScale": [
255,
255,
255,
255,
255,
255,
255,
255,
255,
255,
255,
255,
255,
255,
255,
255,
255,
255
],
"isCfg": 1,
"type": 2,
"timeRange": {
"isCfg": 1,
"timeMode": 0,
"startTime": {
"sec": 0,
"min": 0,
"week": 1,
"hour": 0,
"month": 1,
"year": 2024,
"day": 1
},
"endTime": {
"sec": 59,
"min": 59,
"week": 3,
"hour": 23,
"month": 12,
"year": 2064,
"day": 31
},
"isEnable": 1
},
"isEnable": onOff ? 1 : 0,
"setTime": {
"sec": today.getSeconds(),
"min": today.getMinutes(),
"week": today.getDay(),
"hour": today.getHours(),
"month": today.getMonth() + 1,
"year": today.getFullYear(),
"day": today.getDate()
}
}
}
};
const smartHomePanelSN = await getDeviceSerialNumber("Smart Home Panel", deviceName);
const smartHomePanelDevice = await ecoflowAPI.getDevice(smartHomePanelSN);
return await smartHomePanelDevice.setScheduledDischargingJob(dischargeParams);
}
// turns on discharging for circuits 1, 2, 3, 5, 9, and 10
const results = await dischargeJob(true, [1, 1, 1, 0, 1, 0, 0, 0, 1, 1]);
console.log(JSON.stringify(results, null, 2));
{
"name": "discharge_job_example",
"version": "1.0.0",
"main": "index.mjs",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "Example JavaScript module for turning on or off an EcoFlow SHP1 discharge job",
"dependencies": {
"@ecoflow-api/rest-client": "^0.0.13"
}
}
@Thomptronics
Copy link
Author

By default, this code example creates an Automated Task (a "job") that runs until you stop it by calling dischargeJob(false) or by using the EcoFlow app. Well, it would automatically stop in late 2064, though it's doubtful your batteries would last that long.

IMPORTANT NOTE: This will overwrite any job/automation you have in the slot that appears after the default "If Power outage" automation. To change the slot that it uses, change the value assigned to cfgIndex on line 39. Of course, you could easily add a slot number parameter to the dischargeJob() function if you prefer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment