<?php
/*
* =====================================================
* Author: Jiri Holakovsky
*
* Description: This class is used to interact with the
* EcoFlow API to retrieve device quota information.
* It can return the data either as a PHP array or JSON
* and includes the option to enable verbose mode for
* debugging purposes.
*
* This class is provided for free. If you find it useful,
* please consider giving a backlink from your website or
* blog, or mention it in discussions.
*
* https://www.elektrarna.solar/ecoflow-api-php-class.php
*
* Thank you.
*
* Requirements:
* - PHP 7.4 or higher
* - cURL extension enabled
* =====================================================
*/
class EcoFlowAPI {
private $accessKey;
private $secretKey;
private $sn;
private $returnArray;
public function __construct($accessKey, $secretKey, $sn, $returnArray = 0) {
$this->accessKey = $accessKey;
$this->secretKey = $secretKey;
$this->sn = $sn;
$this->returnArray = $returnArray;
}
private function flattenData($data, $prefix = '') {
$result = [];
foreach ($data as $key => $value) {
if (is_array($value)) {
$result = array_merge($result, $this->flattenData($value, $prefix . $key . '.'));
} else {
$result[$prefix . $key] = $value;
}
}
return $result;
}
private function generateSignature($nonce, $timestamp, $data) {
$flattenedData = $this->flattenData($data);
ksort($flattenedData, SORT_STRING);
$signatureBase = http_build_query($flattenedData);
$signatureBase .= sprintf('&accessKey=%s&nonce=%s×tamp=%s', $this->accessKey, $nonce, $timestamp);
$signatureBase = ltrim($signatureBase, '&');
$signatureBytes = hash_hmac('sha256', $signatureBase, $this->secretKey, true);
return bin2hex($signatureBytes);
}
public function getData() {
$timestamp = round(microtime(true) * 1000);
$nonce = uniqid();
$params = [
"sn" => $this->sn
];
$signature = $this->generateSignature($nonce, $timestamp, $params);
$apiUrl = "https://api-e.ecoflow.com/iot-open/sign/device/quota/all?" . http_build_query($params);
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $apiUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"accessKey: {$this->accessKey}",
"sign: $signature",
"timestamp: $timestamp",
"nonce: $nonce"
],
CURLOPT_VERBOSE => false
]);
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$error = curl_error($curl);
$errorNo = curl_errno($curl);
curl_close($curl);
if ($response === false || $httpCode !== 200) {
return [
"error" => "API request failed.",
"httpCode" => $httpCode,
"cUrlError" => $error,
"cUrlErrorNo" => $errorNo,
"response" => $response
];
} else {
$responseData = json_decode($response, true);
if ($this->returnArray) {
return $responseData;
} else {
return json_encode($responseData);
}
}
}
}
// $api = new EcoFlowAPI("YOUR_ACCESS_KEY", "YOUR_SECRET_KEY", "YOUR_SERIAL_NUMBER", 1); // 1 for PHP array, 0 for JSON
// $result = $api->getData();
// print_r($result);
?>
Example PHP array (EcoFlow Delta Pro)
Array
(
[code] => 0
[message] => Success
[data] => Array
(
[pd.iconWifiMode] => 0
[mppt.faultCode] => 0
[ems.minDsgSoc] => 0
[pd.iconOverloadState] => 0
[pd.watthisconfig] => 0
[bmsMaster.totalDsgCap] => 4294967295
[ems.emsIsNormalFlag] => 1
[inv.cfgAcOutVoltage] => 230000
[bmsMaster.bmsHeartbeatVer] => 259
[pd.iconGasGenMode] => 0
[pd.iconBmsParallelMode] => 0
[pd.iconCoGasState] => 0
[bmsMaster.chgDsgState] => 2
[inv.invOutFreq] => 50
[inv.cfgFastChgWatts] => 0
[bmsMaster.bqSysStatReg] => 128
[mppt.inAmp] => 402
[bmsMaster.errCode] => 0
[pd.usb1Watts] => 0
[inv.cfgAcXboost] => 1
[inv.outTemp] => 30
[bmsMaster.balanceState] => 0
[bmsMaster.ecloudOcv] => 65535
[pd.chgPowerDc] => 0
[mppt.dcdc12vAmp] => 0
[pd.iconUsbState] => 0
[ems.dsgCmd] => 1
[pd.extRj45Port] => 0
[bmsMaster.remainTime] => 0
[inv.inputWatts] => 0
[bmsMaster.fullCap] => 76000
[pd.iconBtMode] => 0
[bmsMaster.maxVolDiff] => 6
[pd.typec2Temp] => 23
[pd.typec1Watts] => 0
[bmsMaster.hwEdition] => Array
(
[0] => 86
[1] => 48
[2] => 46
[3] => 48
[4] => 46
[5] => 48
)
[pd.soc] => 80
[pd.iconFactoryState] => 0
[inv.invOutAmp] => 232
[pd.iconChgStationState] => 0
[ems.chgAmp] => 130000
[ems.bms2Online] => 0
[bmsMaster.remainCap] => 60849
[ems.paraVolMax] => 50513
[pd.iconCarState] => 0
[pd.ext3p8Port] => 0
[inv.dcInAmp] => 0
[mppt.carOutAmp] => 0
[bmsMaster.vol] => 50500
[bmsMaster.cellSeriesNum] => 15
[pd.iconWifiState] => 0
[bmsMaster.type] => 1
[inv.cfgAcEnabled] => 1
[bmsMaster.sysState] => 2
[mppt.chgType] => 2
[bmsMaster.mosState] => 3
[pd.iconBmsErrState] => 0
[mppt.cfgChgType] => 0
[pd.iconBmsErrMode] => 0
[inv.acPassByAutoEn] => 0
[pd.iconEcoState] => 0
[inv.dischargeType] => 1
[pd.carState] => 0
[pd.invUsedTime] => 454987
[pd.iconAcFreqMode] => 0
[ems.f32LcdShowSoc] => 80.064476
[mppt.carTemp] => 0
[pd.chgPowerAc] => 2475
[mppt.outWatts] => 4073
[pd.beepState] => 0
[pd.iconPackHeaterState] => 0
[pd.wifiAutoRcvy] => 0
[pd.remainTime] => 102
[bmsMaster.maxCellTemp] => 25
[pd.relayswitchcnt] => 0
[ems.maxChargeSoc] => 100
[mppt.outAmp] => 814
[pd.ext4p8Port] => 0
[mppt.chgPauseFlag] => 0
[inv.chargerType] => 0
[pd.chgSunPower] => 16772
[pd.lcdBrightness] => 100
[pd.iconRechgTimeState] => 0
[bmsMaster.maxMosTemp] => 25
[pd.lcdOffSec] => 300
[pd.iconTransSwState] => 0
[pd.iconTypecMode] => 0
[inv.acInVol] => 0
[ems.openUpsFlag] => 0
[pd.sysVer] => 16908436
[pd.iconOverloadMode] => 0
[mppt.dc24vTemp] => 21
[ems.bmsWarningState] => 0
[bmsMaster.cellVol] => Array
(
[0] => 3361
[1] => 3359
[2] => 3358
[3] => 3360
[4] => 3360
[5] => 3360
[6] => 3362
[7] => 3361
[8] => 3360
[9] => 3361
[10] => 3362
[11] => 3359
[12] => 3359
[13] => 3362
[14] => 3364
)
[mppt.xt60ChgType] => 2
[bmsMaster.cellNtcNum] => 4
[pd.acautooutPause] => 255
[pd.iconFactoryMode] => 0
[ems.bms0Online] => 3
[inv.cfgAcOutFreq] => 1
[pd.iconFanMode] => 1
[inv.errCode] => 0
[mppt.dcdc12vWatts] => 0
[pd.dcOutState] => 1
[mppt.cfgDcChgCurrent] => 6000
[ems.dsgRemainTime] => 18254
[bmsMaster.openBmsIdx] => 1
[pd.mpptUsedTime] => 173644
[ems.maxAvailableNum] => 1
[bmsMaster.realSoh] => 0
[mppt.mpptTemp] => 47
[pd.iconWirelessChgMode] => 0
[pd.wifiRssi] => 0
[ems.bms1Online] => 0
[bmsMaster.productType] => 14
[ems.bmsModel] => 1
[pd.iconSolarBracketState] => 0
[kit.maxKitNum] => 2
[bmsMaster.minCellVol] => 3358
[pd.iconCoGasMode] => 0
[pd.iconChgStationMode] => 0
[pd.iconGasGenState] => 0
[pd.usb2Watts] => 1
[pd.iconRcMode] => 0
[inv.cfgSlowChgWatts] => 400
[bmsMaster.f32ShowSoc] => 80.065125
[mppt.dc24vState] => 1
[pd.wattsInSum] => 345
[pd.wifiVer] => 1032
[pd.iconLowTempMode] => 0
[inv.cfgAcWorkMode] => 0
[bmsMaster.bmsFault] => 0
[bmsMaster.diffSoc] => 1.666626
[pd.iconInvParallelState] => 0
[pd.typec2Watts] => 0
[pd.iconTypecState] => 0
[pd.iconCarMode] => 1
[inv.outputWatts] => 0
[bmsMaster.soh] => 100
[pd.iconRcState] => 0
[bmsMaster.calendarSch] => 0
[kit.availableDataLen] => 83
[kit.productInfoDetails] => Array
(
[0] => Array
(
[protocolAvaiFlag] => 0
[sn] =>
[productType] => 0
[productDetail] => 0
[procedureState] => 0
[appVersion] => 0
[loaderVersion] => 0
[curPower] => 0
[f32Soc] => 0
[soc] => 0
)
[1] => Array
(
[protocolAvaiFlag] => 0
[sn] =>
[productType] => 0
[productDetail] => 0
[procedureState] => 0
[appVersion] => 0
[loaderVersion] => 0
[curPower] => 0
[f32Soc] => 0
[soc] => 0
)
)
[bmsMaster.soc] => 80
[bmsMaster.num] => 0
[pd.iconHiTempState] => 0
[mppt.inVol] => 1057
[pd.iconHiTempMode] => 0
[pd.iconEcoMode] => 0
[inv.fanState] => 1
[pd.standByMode] => 30
[bmsMaster.cellTemp] => Array
(
[0] => 25
[1] => 24
[2] => 24
[3] => 24
)
[ems.chgVol] => 51496
[pd.dsgPowerDc] => 841
[bmsMaster.inputWatts] => 0
[pd.typccUsedTime] => 41877
[inv.invOutVol] => 229968
[ems.chgState] => 1
[pd.carUsedTime] => 3101
[inv.acInFreq] => 0
[inv.chgPauseFlag] => 0
[pd.minAcoutSoc] => 255
[ems.fanLevel] => 0
[pd.iconBmsParallelState] => 0
[pd.wirelessWatts] => 0
[mppt.carOutVol] => 0
[pd.iconSocUpsMode] => 0
[inv.dcInVol] => 0
[pd.iconSolarBracketMode] => 0
[ems.minOpenOilEbSoc] => 0
[bmsMaster.packSn] => Array
(
[0] => 48
[1] => 48
[2] => 48
[3] => 48
[4] => 48
[5] => 48
[6] => 48
[7] => 48
[8] => 48
[9] => 48
[10] => 48
[11] => 48
[12] => 48
[13] => 48
[14] => 48
[15] => 48
)
[ems.paraVolMin] => 49913
[inv.dcInTemp] => 30
[mppt.dcdc12vVol] => 0
[bmsMaster.amp] => 5874
[pd.wattsOutSum] => 0
[pd.iconWindGenMode] => 0
[bmsMaster.cycleSoh] => 0
[mppt.carOutWatts] => 0
[mppt.outVol] => 500
[pd.iconUsbMode] => 0
[inv.acDipSwitch] => 1
[bmsMaster.totalChgCap] => 4294967295
[pd.iconWindGenState] => 0
[pd.iconBtState] => 0
[bmsMaster.cellId] => 2
[bmsMaster.allErrCode] => 0
[mppt.chgState] => 1
[bmsMaster.productDetail] => 2
[bmsMaster.targetSoc] => 80.06451
[mppt.carState] => 0
[bmsMaster.designCap] => 80000
[pd.typec1Temp] => 23
[bmsMaster.allBmsFault] => 0
[pd.dsgPowerAc] => 9220
[pd.dcInUsedTime] => 0
[pd.iconLowTempState] => 0
[pd.model] => 1
[bmsMaster.actSoc] => 80
[inv.cfgStandbyMin] => 720
[ems.openBmsIdx] => 1
[pd.iconFanState] => 0
[bmsMaster.sysVer] => 16843820
[pd.hysteresisAdd] => 5
[pd.carTemp] => 0
[inv.acInAmp] => 0
[pd.acautooutConfig] => 0
[pd.qcUsb2Watts] => 0
[bmsMaster.maxCellVol] => 3364
[bmsMaster.minMosTemp] => 25
[pd.iconRechgTimeMode] => 0
[bmsMaster.cycles] => 4
[kit.protocolVersion] => 1
[pd.sysChgDsgState] => 2
[pd.iconInvParallelMode] => 0
[ems.chgCmd] => 1
[pd.bppowerSoc] => 80
[pd.qcUsb1Watts] => 0
[bmsMaster.temp] => 25
[pd.iconTransSwMode] => 0
[ems.lcdShowSoc] => 80
[pd.kit1] => 0
[mppt.swVer] => 50397223
[ems.chgRemainTime] => 102
[pd.usbqcUsedTime] => 2486
[mppt.inWatts] => 4210
[bmsMaster.outputWatts] => 0
[pd.usbUsedTime] => 385797
[bmsMaster.minCellTemp] => 24
[bmsMaster.tagChgAmp] => 48000
[pd.iconSolarPanelState] => 0
[bmsMaster.sysLoaderVer] => 16842762
[inv.invType] => 8
[pd.iconSocUpsState] => 0
[pd.errCode] => 0
[pd.iconPackHeaterMode] => 0
[ems.maxCloseOilEbSoc] => 100
[pd.carWatts] => 0
[pd.iconAcFreqState] => 0
[pd.iconWirelessChgState] => 0
[pd.iconSolarPanelMode] => 0
[inv.sysVer] => 33620330
)
[eagleEyeTraceId] => ea1a2a5c2b17199914091566674XXXXX
[tid] =>
)