HomeGuidesRecipesAPI ReferenceChangelog
Log In
Guides

Step 5 - Generate Post-Storage Profiles

In this step, we’ll make a request to /rest/v1/profiles/storage, which will simulate the battery storage system and generate three new “post-storage” profiles that adjust the base consumption and solar profiles to account for the battery’s energy timeshifting. These “post-storage” profiles are then used to perform a Savings Analysis.

These three new profiles are:

  1. Post-storage grid imports to site: The grid-to-site kWh series, excluding additional kWh imported to directly charge the battery.
  2. Post-storage grid exports from Solar: The solar-to-grid export kWh series, after any self-consumption and battery charging.
  3. Grid imports and exports to and from the Battery: This profile includes two data series representing net grid imports and net grid exports that are directly attributable to battery grid charging and battery exports.

These “post-storage” profiles can be identified with a “-usage”, “-solar”, or “-storage” suffix (respectively) on their providerProfileId field.

Together, these encapsulate the net imports and exports measured at the meter after the battery system is operational. Importantly, these profiles capture only the system’s interaction with the grid, meaning the transactions are associated with a tariff rate. Other Behind The Meter power flows (such as battery-to-site) are not stored in these profiles as they cannot be priced against a tariff rate, users who wish to persist these schedules must store them within their application.

How does the storage model use the Switch Usage Profile?

  • The storage model requires the ELECTRICITY Profile to be an hourly time series of consumption. Many Switch users, however, create ELECTRICITY Profiles using monthly statements rather than interval data. To account for this, when the Storage Profile is passed an ELECTRICITY Profile without a full 8760 array, it will automatically transform the available Reading Data into a time series that can be passed to the storage model (see Intelligent Baselining for more information).
  • If you prefer to use your own intervals, the Storage Profile will only ensure they are appropriately dated for a future time horizon.

What dispatch options does the storage model support?
SinS supports passing a dispatchStrategy option on storage profile creation, which controls how the battery charges and discharges. dispatchStrategy supports three sub-options:

  1. { "dispatchStrategy": { "optimize": true } }: create a storage profile with an optimized dispatch schedule to maximize savings for the given tariff (also passed as a parameter). This dispatch strategy is appropriate for granular TOU tariffs and hardware controls that support hourly schedules. For tariffs with tiers or demand charges, the schedules generated by the optimal dispatch logic will produce feasible, though not necessarily optimal, battery plans.
  2. { "dispatchStrategy": { "chargeOnSurplus": true } }: create a storage profile where the battery charges on surplus solar whenever generation exceeds consumption, and discharges to meet unmet site demand otherwise. For this strategy, the storage system does not charge from, or export to, the grid. This dispatch option is designed to support grid-independent installations.
  3. { "dispatchStrategy":{ "fixedSchedule": {"chargeTous":\[], "dischargeTous": \[]}}: create a storage profile where the battery charges and discharges on a fixed schedule. To specify this schedule, pass in arrays of time-of-use objects (all fields are allowed, but only a subset is required — see the example below). These examples can be taken directly from tariff JSON to facilitate charging off-peak and discharging on-peak. The battery will attempt to charge as much as possible during charge periods and discharge as much as possible during discharge periods. When there is not enough generation to cover both site consumption and battery charging, we apply the following prioritization:
    1. When the battery can charge from the grid { "allowGridToBattery": true } we prioritize charging the battery from solar and send surplus generation to the site.
    2. When the battery can only charge from solar { "allowBatteryToGrid": false } we prioritize powering the home, and only charge the battery from surplus generation.

*Note, Switch will default to the optimized dispatch strategy if the field is not included in the request.

Input parameter notes:

  • "serviceType": "ELECTRICITY" - There is no new service type for the Storage profile. Instead, we use ELECTRICITY, same as a Usage Profile.
  • The endpoint supports using either or both accountId and providerAccountId – consistent with Usage and Solar Profile.
  • For looking up solar and consumption profiles, the endpoint supports using either or both profileId and providerProfileId — consistent with Usage and Solar Profile.
  • All inputs under ‘Storage’ are optional - defaults are displayed below.
  • Although all inputs under the storage object are optional if a mainTariffId is not passed we will use the primary tariff on the Account. Depending on the Account configuration, this may be a pre-solar tariff. We recommend always specifying the desired solar tariff in a Storage Profile.
  • The storage model supports one or more solar profiles, allowing users to upload multiple arrays per project, each under a different profile. This implementation assumes a single inverter such that when more than one solar profile is passed to the storage endpoint, the service will sum up all generation per time step.
  • When passing a solar profile users have the option of scaling the production using the dataFactor parameter (see example call below). This input field acts as a scalar, multiplying each of the solar curve’s readings by the given value. For example, “dataFactor”: 4 will result in a 400% increase in each of the solar profile’s intervals.
  • Top-level providerProfileId – used as a prefix to the IDs of the three new profiles created by the call. We will append the type of profile (usage/solar/storage) to each so that it’s easier to track what profiles go together for a Savings Analysis. For example, if you set the parameter as "providerProfileId": "sins-example-jun23-poststorage", then the three new profiles will have the following providerProfileId’s:
    • "sins-example-jun23-poststorage-usage"
    • "sins-example-jun23-poststorage-solar"
    • "sins-example-jun23-poststorage-storage"
  • profileName - used as a prefix of the names of the three new profiles created by the call. For example, if you set the request parameter as "profileName": "Fav Customer", then the three new profiles will have the following profileNames:
    • "Fav Customer - Post-storage grid imports to site"
    • "Fav Customer - Post-storage grid exports from solar"
    • "Fav Customer - Grid imports and exports to and from battery"
  • There are four power flow parameters that allow users to customize the model to the site installation. By default, all powerflows are enabled (true).
    • allowGridToBattery
    • allowBatteryToGrid
    • allowSolarToGrid
    • allowSolarToBattery
  • Battery hardware specifications are captured in the storage object (see example requests below for available fields).
  • fromDateTime should match the value used in the usage and solar profiles. Please be sure to pass the timezone in your request. This timestamp should be the same as was used for the electricity Profile, Solar Profile, and Savings Analysis.
  • exportLimitKwhAc restricts exported to the grid per time step in kWh AC. Leave unspecified for unlimited exports, or set to 0 to forbid them.
  • batteryMinSoc ("0.1"): This is the minimum state of charge for the battery, expressed as a fraction of the total capacity. In this case, the minimum SoC is 10% of the battery's full capacity.
  • batteryMaxSoc ("1.0"): This is the maximum state of charge for the battery, expressed as a fraction of the total capacity. Here, the maximum SoC is 100% of the battery's full capacity.
  • batteryInitialSoc ("0.5"): This is the initial state of charge of the battery when it starts operating, expressed as a fraction of the total capacity. In this case, the battery starts at 50% of its full capacity.
  • Arcadia’s storage model supports two options for passing in battery power ratings - the rate at which a battery can charge and discharge. Note that users should pass one of these options, not both.:
    • batteryNameplatePower - for batteries that have the same charge and discharge rate limits. This is the default option used by the system.
    • A combination of batteryNameplateChargePowerKwDc AND batteryNameplateDischargePowerKwDc - for batteries that have different charge and discharge rate limits.

Response notes:

  • The response from this call will automatically create three new profiles within the account, each with the same providerProfileId prefix and source.requestId to indicate they are part of the same set. If no providerProfileId is sent in the initial request, then the request ID will be included in their default providerProfileId and profileName.
  • The original power flows returned by the Storage Model can be found under the storageOptimizationResponse field. Please note that we do not store BTM power flows under the new optimized profiles. To use these outputs you must store them on your end.

New URL:

POST /rest/v1/profiles/storage

Request example with optimized dispatch:

{
  "providerAccountId": "sins-example-jun23",
  "providerProfileId": "sins-example-jun23-poststorage", //This will be the id used in next step for storage profile
  "fromDateTime": "2023-05-01T00:00:00-07:00", // Important: pass the timezone!
  "consumption": {
    "providerProfileId": "sins-example-jun23-bills"
  },
  "solar": [
    {"providerProfileId": "sins-example-jun23-solar",
"dataFactor": 1.5 //this first solar profile will be scaled by 150%
    },
    {"providerProfileId": "sins-example-jun23-solar2"}
    
  ],
  "storage" : {
    "mainTariffId": 3424821,
    "dispatchStrategy": {
      "optimize": true // pass `"chargeOnSurplus": true` for quicker response
    },
    "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.96",
    "allowBatteryToGrid": true,
    "allowGridToBattery": true,
    "allowSolarToGrid": true,
    "allowSolarToBattery": true,
    "tariffPropertyInputs": [
      {"keyName": "accPlusAdderCustomerType", "dataValue": "nonLowIncome"},
      {"keyName": "hasCareDiscount", "dataValue": "false"}
    ]
  }
}


Request example with fixed schedule dispatch:

{
  "providerAccountId": "sins-example-jun23",
  "providerProfileId": "sins-example-jun23-poststorage-fixed-schedule",
  "fromDateTime": "2023-05-01T00:00:00-07:00",
  "consumption": {
    "providerProfileId": "sins-example-jun23-bills"
  },
  "solar": {
    "providerProfileId": "sins-example-jun23-solar"
  },
  "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
            }]
          }
        ]
      }
    }
  }
}