﻿<?xml version="1.0" encoding="utf-8"?>
<Templates format="2" protocolVersion="73">
  <Template revision="1.0" id = "0409e0d1-59f4-48b4-ac6b-a4c890546c01">
    <SuggestedCCUParameters />
    <RevisionHistory>
      <Revision id="1.0">Initial version</Revision>
      <Revision id="1.1">Fix Battery power reporting</Revision>      
      <Revision id="2.0">Refactor (mb)</Revision>
    </RevisionHistory>
    <Name>Solax Inverter</Name>
    <CcuModel>PacketParserCCU</CcuModel>
    <Producer></Producer>
    <Model></Model>
    <Description>You can obtain token ID on the API page from Solaxcloud</Description>
    <ImportParameters>
        <Parameter>
            <Name>Token ID</Name>	
            <Value></Value>
            <Id>tokenID</Id>
        </Parameter>
        <Parameter>
            <Name>Registration No. (communication module)</Name>	
            <Value></Value>
            <Id>sn</Id>
        </Parameter>
    </ImportParameters>
    <Module>
      <Name>Solax Inverter</Name>
      <Id>-1</Id>
      <Model>PacketParserModuleHttp</Model>
      <DeviceProperties>
        <ReadScriptPacketParser>var response := sendhttprequest("/proxy/api/getRealtimeInfo.do?tokenId="+tokenID+"&amp;sn="+sn);

if parsejson(response.Content, "success")
	json := parsejson(response.Content, "result", 1);
	
	var statusCode := parsejson(json,"inverterStatus");
	if statusCode = "100"
	  addwarning("Inverter in waiting - Check DC");
	end
	if statusCode =  "103"
	  adderror("Inverter in fault mode");
	end
	if statusCode = "104"
	  adderror("Inverter in permanent fault mode");
	end
	if statusCode = "110"
	  addwarning("Inverter in standby mode");
	end
else
 	adderror(parsejson(response.Content, "exception"));
end</ReadScriptPacketParser>
        <InternalPollInterval>20000</InternalPollInterval>
        <CustomVariables>[{"Name":"json","ValueTypeId":2,"NumericValue":0,"StringValue":"0"},{"Name":"tokenID","ValueTypeId":2,"NumericValue":0,"StringValue":"$[tokenID]"},{"Name":"sn","ValueTypeId":2,"NumericValue":0,"StringValue":"$[sn]"}]</CustomVariables>
        <ServiceAttributesScriptsPacketParser>[{"AttributeDefinition":{"Name":"Inverter status"},"ReadFormula":"var statusCode := parsejson(json,\u0022inverterStatus\u0022);\r\n\r\nIF(statusCode = \u0022100\u0022,return(\u0022Wait Mode\u0022));\r\nIF(statusCode = \u0022101\u0022,return(\u0022Check Mode\u0022));\r\nIF(statusCode = \u0022102\u0022,return(\u0022Normal Mode\u0022));\r\nIF(statusCode = \u0022103\u0022,return(\u0022Fault Mode\u0022));\r\nIF(statusCode = \u0022104\u0022,return(\u0022Permanent Fault Mode\u0022));\r\nIF(statusCode = \u0022105\u0022,return(\u0022Update Mode\u0022));\r\nIF(statusCode = \u0022106\u0022,return(\u0022EPS Check Mode\u0022));\r\nIF(statusCode = \u0022107\u0022,return(\u0022EPS Mode\u0022));\r\nIF(statusCode = \u0022108\u0022,return(\u0022Self-Test Mode\u0022));\r\nIF(statusCode = \u0022109\u0022,return(\u0022Idle Mode\u0022));\r\nIF(statusCode = \u0022110\u0022,return(\u0022Standby Mode\u0022));\r\nIF(statusCode = \u0022111\u0022,return(\u0022Pv Wake Up Bat Mode\u0022));\r\nIF(statusCode = \u0022112\u0022,return(\u0022Gen Check Mode\u0022));\r\nIF(statusCode = \u0022113\u0022,return(\u0022Gen Run Mode\u0022));\r\n"},{"AttributeDefinition":{"Name":"Inverter type"},"ReadFormula":"var type := parsejson(json,\u0022inverterType\u0022);\r\n\r\nIF(type = \u00221\u0022,return(\u0022X1-LX\u0022));\r\nIF(type = \u00222\u0022,return(\u0022X-Hybrid\u0022));\r\nIF(type = \u00223\u0022,return(\u0022X1-Hybiyd/Fit\u0022));\r\nIF(type = \u00224\u0022,return(\u0022X1-Boost/Air/Mini\u0022));\r\nIF(type = \u00225\u0022,return(\u0022X3-Hybiyd/Fit\u0022));\r\nIF(type = \u00226\u0022,return(\u0022X3-20K/30K\u0022));\r\nIF(type = \u00227\u0022,return(\u0022X3-MIC/PRO\u0022));\r\nIF(type = \u00228\u0022,return(\u0022X1-Smart\u0022));\r\nIF(type = \u00229\u0022,return(\u0022X1-AC\u0022));\r\nIF(type = \u002210\u0022,return(\u0022A1-Hybrid\u0022));\r\nIF(type = \u002211\u0022,return(\u0022A1-Fit\u0022));\r\nIF(type = \u002212\u0022,return(\u0022A1-Grid\u0022));\r\nIF(type = \u002213\u0022,return(\u0022J1-ESS\u0022));\r\nIF(type = \u002214\u0022,return(\u0022X3-Hybrid-G4\u0022));\r\nIF(type = \u002215\u0022,return(\u0022X1-Hybrid-G4\u0022));\r\nIF(type = \u002216\u0022,return(\u0022X3-MIC/PRO-G2\u0022));\r\nIF(type = \u002217\u0022,return(\u0022X1-SPT\u0022));\r\nIF(type = \u002218\u0022,return(\u0022X1-Boost/Mini-G4\u0022));\r\nIF(type = \u002219\u0022,return(\u0022A1-HYB-G2\u0022));\r\nIF(type = \u002220\u0022,return(\u0022A1-AC-G2\u0022));\r\nIF(type = \u002221\u0022,return(\u0022A1-SMT-G2\u0022));\r\nIF(type = \u002222\u0022,return(\u0022X3-FTH\u0022));\r\nIF(type = \u002223\u0022,return(\u0022X3-MGA-G2\u0022));\r\n"}]</ServiceAttributesScriptsPacketParser>
        <IpAddress>www.solaxcloud.com</IpAddress>
        <Port>9443</Port>
        <UseHttps>True</UseHttps>
      </DeviceProperties>
      <Devices>
        <Device>
          <Name>AC output</Name>
          <Model>PacketParserElectricityMeter</Model>
          <Id>-2</Id>
          <DeviceProperties>
            <DeviceType>0</DeviceType>
            <ReadScriptPacketParser></ReadScriptPacketParser>
            <InternalPollInterval>15000</InternalPollInterval>
            <CustomVariables></CustomVariables>
            <ServiceAttributesScriptsPacketParser>[{"AttributeDefinition":{"Name":"Inverter.AC.energy.out.daily [kWh]"},"ReadFormula":"parsejson(json, \u0022yieldtoday\u0022, 1)"}]</ServiceAttributesScriptsPacketParser>
            <ServiceActionsScriptsPacketParser></ServiceActionsScriptsPacketParser>
            <ReadTotalConsumptionScriptPacketParser>parsejson(json, "yieldtotal", 1)</ReadTotalConsumptionScriptPacketParser>
            <ReadDemandScriptPacketParser>parsejson(json, "acpower", 1) / 1000</ReadDemandScriptPacketParser>
          </DeviceProperties>
        </Device>
        <Device>
          <Name>${deviceType_BatterySOC}</Name>
          <Model>PacketParserAnalogInput</Model>
          <Id>-3</Id>
          <DeviceProperties>
            <DeviceType>11001</DeviceType>
            <SerializedValueLogTypeConversions />
            <ReadScriptPacketParser />
            <InternalPollInterval>2500</InternalPollInterval>
            <CustomVariables />
            <ServiceAttributesScriptsPacketParser></ServiceAttributesScriptsPacketParser>
            <ServiceActionsScriptsPacketParser></ServiceActionsScriptsPacketParser>
            <ShouldDoPeriodicWrite>False</ShouldDoPeriodicWrite>
            <ReadInputLevelScriptPacketParser>parsejson(json, "soc", 1) / 100</ReadInputLevelScriptPacketParser>
                                                                         
                                 
          </DeviceProperties>
        </Device>
        <Device>
          <Name>Battery Power</Name>
          <Model>PacketParserVariable</Model>
          <Id>-4</Id>
          <DeviceProperties>
            <DeviceType>0</DeviceType>
            <SerializedValueLogTypeConversions>{"60":"{\u0022ValueLogTypeConversionTypeId\u0022:3,\u0022SerializedValueLogTypeConversion\u0022:\u0022{\\u0022Value1OnInput\\u0022:0,\\u0022Value1OnOutput\\u0022:0,\\u0022Value2OnInput\\u0022:1000,\\u0022Value2OnOutput\\u0022:1,\\u0022SourceValueLogTypes\\u0022:[62],\\u0022TargetValueLogType\\u0022:60}\u0022}"}</SerializedValueLogTypeConversions>
            <ReadScriptPacketParser></ReadScriptPacketParser>
            <InternalPollInterval>15000</InternalPollInterval>
            <CustomVariables></CustomVariables>
            <ServiceAttributesScriptsPacketParser></ServiceAttributesScriptsPacketParser>
            <ServiceActionsScriptsPacketParser></ServiceActionsScriptsPacketParser>
            <ShouldDoPeriodicWrite>False</ShouldDoPeriodicWrite>
            <IsReadOnly>True</IsReadOnly>
            <ReadStateScriptPacketParser>parsejson(json,"batPower",1)</ReadStateScriptPacketParser>
            <WriteStateScriptPacketParser></WriteStateScriptPacketParser>
          </DeviceProperties>
        </Device>
        <Device>
          <Name>${deviceType_PVFromGrid}</Name>
          <Model>PacketParserElectricityMeter</Model>
          <Id>-5</Id>
          <DeviceProperties>
            <DeviceType>9004</DeviceType>
            <ReadScriptPacketParser></ReadScriptPacketParser>
            <InternalPollInterval>15000</InternalPollInterval>
            <CustomVariables></CustomVariables>
            <ServiceAttributesScriptsPacketParser></ServiceAttributesScriptsPacketParser>
            <ServiceActionsScriptsPacketParser></ServiceActionsScriptsPacketParser>
            <ReadTotalConsumptionScriptPacketParser>parsejson(json, "consumeenergy", 1)</ReadTotalConsumptionScriptPacketParser>
            <ReadDemandScriptPacketParser>var power := parsejson(json, "feedinpower", 1);
if(power &lt; 0, power * -1, 0) / 1000</ReadDemandScriptPacketParser>
          </DeviceProperties>
        </Device>
        <Device>
          <Name>Grid Power</Name>
          <Model>PacketParserVariable</Model>
          <Id>-6</Id>
          <DeviceProperties>
            <DeviceType>0</DeviceType>
            <SerializedValueLogTypeConversions>{"60":"{\u0022ValueLogTypeConversionTypeId\u0022:3,\u0022SerializedValueLogTypeConversion\u0022:\u0022{\\u0022Value1OnInput\\u0022:0,\\u0022Value1OnOutput\\u0022:0,\\u0022Value2OnInput\\u0022:1000,\\u0022Value2OnOutput\\u0022:1,\\u0022SourceValueLogTypes\\u0022:[62],\\u0022TargetValueLogType\\u0022:60}\u0022}"}</SerializedValueLogTypeConversions>
            <ReadScriptPacketParser></ReadScriptPacketParser>
            <InternalPollInterval>15000</InternalPollInterval>
            <CustomVariables></CustomVariables>
            <ServiceAttributesScriptsPacketParser></ServiceAttributesScriptsPacketParser>
            <ServiceActionsScriptsPacketParser></ServiceActionsScriptsPacketParser>
            <ShouldDoPeriodicWrite>False</ShouldDoPeriodicWrite>
            <IsReadOnly>True</IsReadOnly>
            <ReadStateScriptPacketParser>parsejson(json, "feedinpower", 1)</ReadStateScriptPacketParser>
            <WriteStateScriptPacketParser></WriteStateScriptPacketParser>
          </DeviceProperties>
        </Device>
        <Device>
          <Name>${deviceType_PVProduction}</Name>
          <Model>PacketParserVariable</Model>
          <Id>-7</Id>
          <DeviceProperties>
            <DeviceType>9002</DeviceType>
            <SerializedValueLogTypeConversions>{"60":"{\u0022ValueLogTypeConversionTypeId\u0022:3,\u0022SerializedValueLogTypeConversion\u0022:\u0022{\\u0022Value1OnInput\\u0022:0,\\u0022Value1OnOutput\\u0022:0,\\u0022Value2OnInput\\u0022:1000,\\u0022Value2OnOutput\\u0022:1,\\u0022SourceValueLogTypes\\u0022:[62],\\u0022TargetValueLogType\\u0022:60}\u0022}"}</SerializedValueLogTypeConversions>
            <ReadScriptPacketParser></ReadScriptPacketParser>
            <InternalPollInterval>15000</InternalPollInterval>
            <CustomVariables></CustomVariables>
            <ServiceAttributesScriptsPacketParser></ServiceAttributesScriptsPacketParser>
            <ServiceActionsScriptsPacketParser></ServiceActionsScriptsPacketParser>
            <ShouldDoPeriodicWrite>False</ShouldDoPeriodicWrite>
            <IsReadOnly>True</IsReadOnly>
            <ReadStateScriptPacketParser>var PV1 := parsejson(json,"powerdc1",1);
var PV2 := parsejson(json,"powerdc2",1);
var PV3 := parsejson(json,"powerdc3",1);
var PV4 := parsejson(json,"powerdc4",1);

if(isnull(PV1), 0, PV1) +
if(isnull(PV2), 0, PV2) +
if(isnull(PV3), 0, PV3) +
if(isnull(PV4), 0, PV4)</ReadStateScriptPacketParser>
            <WriteStateScriptPacketParser></WriteStateScriptPacketParser>
          </DeviceProperties>
        </Device>
        <Device>
          <Name>${deviceType_PVProduction} (MPPT 1)</Name>
          <Model>PacketParserVariable</Model>
          <Id>-8</Id>
          <DeviceProperties>
            <DeviceType>9002</DeviceType>
            <SerializedValueLogTypeConversions>{"60":"{\u0022ValueLogTypeConversionTypeId\u0022:3,\u0022SerializedValueLogTypeConversion\u0022:\u0022{\\u0022Value1OnInput\\u0022:0,\\u0022Value1OnOutput\\u0022:0,\\u0022Value2OnInput\\u0022:1000,\\u0022Value2OnOutput\\u0022:1,\\u0022SourceValueLogTypes\\u0022:[62],\\u0022TargetValueLogType\\u0022:60}\u0022}"}</SerializedValueLogTypeConversions>
            <ReadScriptPacketParser></ReadScriptPacketParser>
            <InternalPollInterval>15000</InternalPollInterval>
            <CustomVariables></CustomVariables>
            <ServiceAttributesScriptsPacketParser></ServiceAttributesScriptsPacketParser>
            <ServiceActionsScriptsPacketParser></ServiceActionsScriptsPacketParser>
            <ShouldDoPeriodicWrite>False</ShouldDoPeriodicWrite>
            <IsReadOnly>True</IsReadOnly>
            <ReadStateScriptPacketParser>parsejson(json,"powerdc1",1)</ReadStateScriptPacketParser>
            <WriteStateScriptPacketParser></WriteStateScriptPacketParser>
          </DeviceProperties>
        </Device>
        <Device>
          <Name>${deviceType_PVProduction} (MPPT 2)</Name>
          <Model>PacketParserVariable</Model>
          <Id>-9</Id>
          <DeviceProperties>
            <DeviceType>9002</DeviceType>
            <SerializedValueLogTypeConversions>{"60":"{\u0022ValueLogTypeConversionTypeId\u0022:3,\u0022SerializedValueLogTypeConversion\u0022:\u0022{\\u0022Value1OnInput\\u0022:0,\\u0022Value1OnOutput\\u0022:0,\\u0022Value2OnInput\\u0022:1000,\\u0022Value2OnOutput\\u0022:1,\\u0022SourceValueLogTypes\\u0022:[62],\\u0022TargetValueLogType\\u0022:60}\u0022}"}</SerializedValueLogTypeConversions>
            <ReadScriptPacketParser></ReadScriptPacketParser>
            <InternalPollInterval>15000</InternalPollInterval>
            <CustomVariables></CustomVariables>
            <ServiceAttributesScriptsPacketParser></ServiceAttributesScriptsPacketParser>
            <ServiceActionsScriptsPacketParser></ServiceActionsScriptsPacketParser>
            <ShouldDoPeriodicWrite>False</ShouldDoPeriodicWrite>
            <IsReadOnly>True</IsReadOnly>
            <ReadStateScriptPacketParser>parsejson(json,"powerdc2",1)</ReadStateScriptPacketParser>
            <WriteStateScriptPacketParser></WriteStateScriptPacketParser>
          </DeviceProperties>
        </Device>
        <Device>
          <Name>${deviceType_PVProduction} (MPPT 3)</Name>
          <Model>PacketParserVariable</Model>
          <Id>-10</Id>
          <DeviceProperties>
            <DeviceType>9002</DeviceType>
            <SerializedValueLogTypeConversions>{"60":"{\u0022ValueLogTypeConversionTypeId\u0022:3,\u0022SerializedValueLogTypeConversion\u0022:\u0022{\\u0022Value1OnInput\\u0022:0,\\u0022Value1OnOutput\\u0022:0,\\u0022Value2OnInput\\u0022:1000,\\u0022Value2OnOutput\\u0022:1,\\u0022SourceValueLogTypes\\u0022:[62],\\u0022TargetValueLogType\\u0022:60}\u0022}"}</SerializedValueLogTypeConversions>
            <ReadScriptPacketParser>parsejson(json,"powerdc3",1)</ReadScriptPacketParser>
            <InternalPollInterval>15000</InternalPollInterval>
            <CustomVariables></CustomVariables>
            <ServiceAttributesScriptsPacketParser></ServiceAttributesScriptsPacketParser>
            <ServiceActionsScriptsPacketParser></ServiceActionsScriptsPacketParser>
            <ShouldDoPeriodicWrite>False</ShouldDoPeriodicWrite>
            <IsReadOnly>True</IsReadOnly>
            <ReadStateScriptPacketParser></ReadStateScriptPacketParser>
            <WriteStateScriptPacketParser></WriteStateScriptPacketParser>
          </DeviceProperties>
        </Device>
        <Device>
          <Name>${deviceType_PVProduction} (MPPT 4)</Name>
          <Model>PacketParserVariable</Model>
          <Id>-11</Id>
          <DeviceProperties>
            <DeviceType>9002</DeviceType>
            <SerializedValueLogTypeConversions>{"60":"{\u0022ValueLogTypeConversionTypeId\u0022:3,\u0022SerializedValueLogTypeConversion\u0022:\u0022{\\u0022Value1OnInput\\u0022:0,\\u0022Value1OnOutput\\u0022:0,\\u0022Value2OnInput\\u0022:1000,\\u0022Value2OnOutput\\u0022:1,\\u0022SourceValueLogTypes\\u0022:[62],\\u0022TargetValueLogType\\u0022:60}\u0022}"}</SerializedValueLogTypeConversions>
            <ReadScriptPacketParser>parsejson(json,"powerdc4",1)</ReadScriptPacketParser>
            <InternalPollInterval>15000</InternalPollInterval>
            <CustomVariables></CustomVariables>
            <ServiceAttributesScriptsPacketParser></ServiceAttributesScriptsPacketParser>
            <ServiceActionsScriptsPacketParser></ServiceActionsScriptsPacketParser>
            <ShouldDoPeriodicWrite>False</ShouldDoPeriodicWrite>
            <IsReadOnly>True</IsReadOnly>
            <ReadStateScriptPacketParser></ReadStateScriptPacketParser>
            <WriteStateScriptPacketParser></WriteStateScriptPacketParser>
          </DeviceProperties>
        </Device>
        <Device>
          <Name>${deviceType_PVToGrid}</Name>
          <Model>PacketParserElectricityMeter</Model>
          <Id>-12</Id>
          <DeviceProperties>
            <DeviceType>9005</DeviceType>
            <ReadScriptPacketParser></ReadScriptPacketParser>
            <InternalPollInterval>15000</InternalPollInterval>
            <CustomVariables></CustomVariables>
            <ServiceAttributesScriptsPacketParser></ServiceAttributesScriptsPacketParser>
            <ServiceActionsScriptsPacketParser></ServiceActionsScriptsPacketParser>
            <ReadTotalConsumptionScriptPacketParser>parsejson(json, "feedinenergy", 1)</ReadTotalConsumptionScriptPacketParser>
            <ReadDemandScriptPacketParser>var power := parsejson(json, "feedinpower", 1);
if(power &gt; 0, power, 0) / 1000</ReadDemandScriptPacketParser>
          </DeviceProperties>
        </Device>
      </Devices>
    </Module>
  </Template>
</Templates>