Storage Only Workflow
Model a battery-only storage system without solar production by following the standard setup flow and applying storage-specific adjustments.
Model a storage system tied to the home without solar production by completing the standard setup steps, then applying the battery-only adjustments.
When to use this workflow
Use this workflow when you need to model a storage system tied to the home without solar production. Use case examples include a backup only system or one specifically designed for peak shaving (storing energy during cheaper TOU periods and leveraging discharge during higher priced intervals).
Do not use this workflow when the project includes solar production. In that case, follow the standard Forecasting Savings with Storage-in-Switch workflow.
Steps 1–3: Complete initial setup
Follow the first three steps from the Forecasting Savings with Storage-in-Switch workflow:
- Step 1: Create a Full Switch Account
- Step 2: Confirm the Utility and Electricity Tariff
- Step 3: Baseline Electricity Usage
Step 4: Apply Battery Configurations & Generate Optimized Profiles
Step 4: Apply Battery Configurations & Generate Optimized Profiles
Create post-storage profiles
POST /rest/v1/profiles/storageRequest example with optimized dispatch
Important DistinctionNote that the
providerProfileIdyou choose to supply in your storage endpoint call will be referenced in Step 5 as thestorageProviderProfileId. Include the time zone infromDateTimeso that the generated profiles align with your savings analysis period.
{
"providerAccountId": "storage-switch-example",
"providerProfileId": "storage-switch-example-post-storage",
"fromDateTime": "2023-05-01T00:00:00-07:00",
"consumption": {
"providerProfileId": "storage-switch-example-usage"
},
"storage" : {
"mainTariffId": 3424821,
"dispatchStrategy": {
"optimize": true
},
"batteryNameplatePower": "3.0",
"batteryNameplateCapacity": "6.0",
"batteryMinSoc": "0.1",
"batteryMaxSoc": "1.0",
"batteryInitialSoc": "0.5",
"batteryDcCoupled": true,
"batteryAcToDcEfficiency": "0.96",
"batteryDcToAcEfficiency": "0.96",
"batteryInputEfficiency": "0.975",
"batteryDegradationCost": "0",
"solarDcToAcEfficiency": "0",
"allowBatteryToGrid": true,
"allowGridToBattery": true,
"allowSolarToGrid": false,
"allowSolarToBattery": false,
"tariffPropertyInputs": [
{"keyName": "accPlusAdderCustomerType", "dataValue": "nonLowIncome"},
{"keyName": "hasCareDiscount", "dataValue": "false"}
]
}
}
In the request we simply pass our base consumption along with our storage object which houses all of our battery configuration parameters. Note that for a storage only approach allowSolarToGrid and allowSolarToBattery should be set to false and solarDcToAcEfficiency has been set to 0.
| Field | Purpose |
|---|---|
providerAccountId | Account created in Step 1. |
providerProfileId | Client generated ID prefix used for the three generated post-storage profiles. |
fromDateTime | Start timestamp aligned with the usage profile, solar profile, and Savings Analysis inputs. |
consumption.providerProfileId | Usage profile created in Step 3. |
storage.mainTariffId | Post-solar masterTariffId used by the optimization model. Make sure this aligns with your after scenario tariff designation in the savings analysis. |
storage.dispatchStrategy.optimize | Uses optimized dispatch. |
After this request succeeds, the account will contain profiles with these providerProfileId values:
storage-switch-example-post-storage-usagestorage-switch-example-post-storage-solarstorage-switch-example-post-storage-storage
These will all live under the parent providerProfileId value you supply when initiating the POST request to /rest/v1/profiles/storage.
Optional: Request example with fixed schedule dispatch
{
"providerAccountId": "storage-switch-example",
"providerProfileId": "storage-switch-example-post-storage-fixed-schedule",
"fromDateTime": "2023-05-01T00:00:00-07:00",
"consumption": {
"providerProfileId": "storage-switch-example-usage"
},
"storage": {
"dispatchStrategy": {
"fixedSchedule": {
"chargeTous": [
{
"season": {
"seasonFromMonth": 10, "seasonFromDay": 1,
"seasonToMonth": 5, "seasonToDay": 31
},
"touPeriods": [{
"fromHour": 8, "toHour": 17,
"fromDayOfWeek": 0, "toDayOfWeek": 6
}]
},
{
"season": {
"seasonFromMonth": 6, "seasonFromDay": 1,
"seasonToMonth": 9, "seasonToDay": 30
},
"touPeriods": [{
"fromHour": 8, "toHour": 18,
"fromDayOfWeek": 0, "toDayOfWeek": 6
}]
}
],
"dischargeTous": [
{
"season": {
"seasonFromMonth": 10, "seasonFromDay": 1,
"seasonToMonth": 5, "seasonToDay": 31
},
"touPeriods": [{
"fromHour": 17, "toHour": 22,
"fromDayOfWeek": 0, "toDayOfWeek": 6
}]
},
{
"season": {
"seasonFromMonth": 6, "seasonFromDay": 1,
"seasonToMonth": 9, "seasonToDay": 30
},
"touPeriods": [{
"fromHour": 18, "toHour": 22,
"fromDayOfWeek": 0, "toDayOfWeek": 6
}]
}
]
}
}
}
}
This formatting allows for you to pass a fixed schedule for dispatch optimization which can work well for storage only implementations that are grid-tied.
For a full overview of available input fields please see our Storage Object Reference.
Step 5: Run the savings forecast
Request example with 3% battery degradation year-over-year
POST /rest/v1/accounts/analysisRequest:
{
"providerAccountId": "storage-switch-example",
"fromDateTime": "2023-05-01T00:00:00-07:00",
"toDateTime": "2024-05-01T00:00:00-07:00",
"propertyInputs": [
{
"scenarios": "before",
"keyName": "masterTariffId",
"dataValue": "522"
},
{
"scenarios": "before",
"keyName": "providerProfileId",
"dataValue": "storage-switch-example-usage"
},
{
"scenarios": "after,solar",
"keyName": "storageProviderProfileId",
"dataValue": "storage-switch-example-post-storage"
},
{
"scenarios":"solar,after,before",
"keyName": "projectDuration",
"dataValue": 10
}
],
"batteryDegradation": { "percentPerYear": 3 }
}]}| Field | Purpose |
|---|---|
providerAccountId | Account created in Step 1. |
fromDateTime / toDateTime | Savings Analysis period. |
before.masterTariffId | Pre-intervention tariff used for the before scenario. |
before.providerProfileId | Original usage profile created in Step 3. |
storageProviderProfileId | Post-storage family ID created in Step 4. |
projectDuration | Number of years to model (1-25). |
batteryDegradation.percentPerYear | Annual battery capacity degradation rate. |
Step 6: Implementing Storage System Costs
Within the savings analysis request body shown in Step 5 exists an optional rateInputs list, which is where you can leverage the solar scenario to designate costs for the system. The "solar" scenario encompasses PV and Storage, so even though we are not applying solar array production to the analysis, we will still use this scenario for the cost since storage is a component.
For example, if we wanted to factor in a monthly Lease/Loan, our rateInputs list would contain this object:
"rateInputs": [
{
"chargeType": "FIXED_PRICE",
"chargePeriod": "MONTHLY",
"transactionType": "BUY",
"rateBands": [
{
"rateAmount": 85.00
}
],
"scenarios": "solar"
}
]You can adjust the rateAmount value to align with your specific cost value. Please note that with a storage-only simulation, you are limited to this lease/loan structure (i.e., a per-month system cost of the project lifetime). If your cost application is different, this will need to be done via post-processing outside of the savings analysis.
If you need to take this post-processing approach, you can simply avoid passing in an object tied to the solar scenario, which will treat the system as a cash purchase (i.e., no cost for the system is attributed in the simulation). You can then apply the projected costs retroactively to the results as you see fit.
Putting It All Together
Below is a simple, non-exhaustive template for a basic Savings Analysis call using our storage-optimized profiles tied to the storageProviderProfileId covered previously. This also includes a per month cost attributed to a theoretical loan on the site's storage system.
POST /rest/v1/accounts/analysis{
"accountId": "{accountId}",
"fromDateTime": "2025-10-10T00:00:00-07:00",
"propertyInputs": [
{
"scenarios": "before",
"keyName": "masterTariffId",
"dataValue": "522"
},
// Our consumption profile, you can use profileId or providerProfileId here
{
"scenarios": "before",
"keyName": "providerProfileId",
"dataValue": "{providerProfileId}"
},
// storageProviderProfileId is the providerProfileId designated on our storage optimization call (POST /rest/v1/profiles/storage)
{
"scenarios": "after,solar",
"keyName": "storageProviderProfileId",
"dataValue": "{storageProviderProfileId}"
},
{
"scenarios": "solar,after,before",
"keyName": "projectDuration",
"dataValue": 10
}
],
// Here we define our monthly system cost, which is applied to the project lifetime
"rateInputs": [
{
"chargeType": "FIXED_PRICE",
"chargePeriod": "MONTHLY",
"transactionType": "BUY",
"rateBands": [
{
"rateAmount": 85.00
}
],
"scenarios": "solar"
}
],
"batteryDegradation": {
"percentPerYear": 0.5
}
}In the resulting savings analysis, our solar scenario now includes the monthly cost attributed to our storage system and is factored into the net savings total for the simulation. Note that a yearly escalation factor can be applied in the propertyInputs list via the property keyname of rateInflation, specifying the solar scenario.
Updated 2 days ago
