{ "@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [ { "@type": "Question", "name": "How are estimated meter readings distinguished from measured readings, and can they be corrected without data loss?", "acceptedAnswer": { "@type": "Answer", "text": "meter_readings carries a quality_flag (MEASURED | ESTIMATED | SUBSTITUTED). Estimated readings are flagged rather than replacing measured rows. When a confirmed MEASURED reading arrives for the same timestamp, it is written alongside the estimated row -- the estimated record is preserved. Billing logic references quality_flag and prefers MEASURED over ESTIMATED when both exist for the same interval." } }, { "@type": "Question", "name": "How are energy tariffs applied when a billing period spans a tariff change date?", "acceptedAnswer": { "@type": "Answer", "text": "energy_tariff_config rows are immutable once published. Each billing_calculation row references the tariff_version_id active at billing_period_start. Consumption before the change is billed at the old tariff, consumption after at the new tariff. Because both config rows are preserved, the calculation can always be re-audited against the exact tariff active at each interval." } }, { "@type": "Question", "name": "How is demand response settlement calculated if a site delivers less capacity than it committed?", "acceptedAnswer": { "@type": "Answer", "text": "demand_response_events records both capacity_mw_committed (at dispatch) and capacity_mw_delivered (at settlement). Shortfall between committed and delivered writes to dr_shortfall_events, which are the input to penalty calculations under the programme's settlement rules. All events are append-only -- the settlement audit trail is always preserved." } }, { "@type": "Question", "name": "Can carbon intensity factors be updated when the grid mix changes without recalculating historical emissions?", "acceptedAnswer": { "@type": "Answer", "text": "carbon_intensity_config is keyed by (source_type, effective_from/to). Updating the grid mix factor writes a new config row. Each carbon_events row stores the intensity factor that was active at event time, so historical emissions are preserved as-recorded. The materialised carbon footprint view always reflects the factor that was actually used, not the current factor." } }, { "@type": "Question", "name": "How quickly can an energy management platform be deployed?", "acceptedAnswer": { "@type": "Answer", "text": "Scrums.com dedicated engineering teams deliver a working first deployment in 21 days." } } ] }

Energy Management App Development

Build custom app solutions with Scrums.com's expert development team. With an NPS (Net Promoter Score) of 82, Scrums.com crafts cost-effective, custom applications that drive results.

Utilities, renewable energy operators, and industrial energy managers building management platforms need engineering teams who understand the specific data architecture of energy systems -- high-frequency meter data pipelines, generation event logging, battery state management, demand response dispatch, and the tariff and billing logic that connects consumption to revenue. Scrums.com provides dedicated software engineering teams for energy management app development, deploying production-ready systems with immutable meter reading ledgers, configurable alert and dispatch rule engines, TimescaleDB time-series pipelines, and the analytics infrastructure that measures energy balance, renewable penetration, and carbon intensity.

Energy Asset Registry, Metering, and Generation Data Architecture

The energy asset registry holds every asset with type (SOLAR_PANEL_ARRAY | WIND_TURBINE | BATTERY_STORAGE | TRANSFORMER | SUBSTATION | GRID_METER | EV_CHARGER | GENERATOR | HEAT_PUMP), capacity_kw, location_id, and commissioning_date; status follows OPERATIONAL -- DEGRADED -- OFFLINE -- MAINTENANCE -- DECOMMISSIONED with each transition appended to asset_status_events. Meter readings land in TimescaleDB hypertables: meter_id, reading_timestamp, energy_kwh (cumulative register), interval_kwh (computed delta), and quality_flag (MEASURED | ESTIMATED | SUBSTITUTED). Idempotency is enforced via ON CONFLICT DO NOTHING on (meter_id, reading_timestamp); ESTIMATED and SUBSTITUTED readings are flagged rather than replacing MEASURED rows -- when a confirmed MEASURED reading arrives for the same timestamp, it is written alongside the estimated row, and billing logic prefers MEASURED. Meter data validation runs against validation_rules_config (rule_type: RANGE_CHECK | SPIKE_DETECTION | MISSING_INTERVAL, parameters JSONB); failed validations write to meter_data_exceptions for review without blocking the ingest pipeline. Generation events record asset_id, generation_kwh, period_start, period_end, irradiance_w_m2 (solar), wind_speed_ms (wind), and performance_ratio (actual output versus theoretical output at conditions) -- append-only, feeding curtailment and degradation analytics.

Battery Dispatch, Demand Response, and Grid Integration

Battery state is captured in battery_state_events: asset_id, state_of_charge_pct, charge_mode (CHARGING | DISCHARGING | IDLE | STANDBY), power_kw, occurred_at -- stored in TimescaleDB; current state is always the latest event per asset, never a mutable field on the asset record. Charge dispatch rules in charge_dispatch_rules (rule_type: TOU_ARBITRAGE | PEAK_SHAVING | FREQUENCY_RESPONSE | SELF_CONSUMPTION | GRID_SERVICES, rule_config JSONB with thresholds, time windows, and priority) are config-driven; every dispatch decision writes a dispatch_events row referencing the rule that triggered it, preserving the full dispatch audit trail. Demand response events record program_id, event_type (NOTIFICATION_ISSUED | DISPATCH_SENT | RESPONSE_CONFIRMED | SETTLEMENT_COMPLETE), capacity_mw_committed, and capacity_mw_delivered; shortfall between committed and delivered writes to dr_shortfall_events for settlement penalty calculation -- all append-only. Grid import and export each append to their respective event tables (power flow direction, energy_kwh, grid_connection_point_id, occurred_at); a grid_energy_balance_by_period materialised view computes net import/export without a mutable balance field. Energy tariffs in energy_tariff_config (rate_type: FLAT | TIME_OF_USE | DYNAMIC | CAPACITY | DEMAND_CHARGE, rate_schedule JSONB, effective_from, effective_to) are immutable once published; billing always reads the tariff active at consumption time, so a mid-period tariff change cannot retroactively reprice prior consumption.

Energy Tariffs, Billing, and Revenue Analytics

Energy tariff rows in energy_tariff_config are immutable once published (rate_type: FLAT | TIME_OF_USE | DYNAMIC | CAPACITY | DEMAND_CHARGE, rate_schedule JSONB, effective_from, effective_to); new rows handle rate changes. Each billing_calculations row references the tariff_version_id active at billing_period_start -- consumption before a rate change is billed at the old tariff, consumption after at the new tariff, and both config rows are preserved so any calculation can be re-audited. Billing recalculations write new rows rather than overwriting prior calculations, preserving the full calculation history for dispute resolution. Tariff disputes follow a state machine (OPEN -- UNDER_REVIEW -- RESOLVED | ACCEPTED) and are never deleted; resolved disputes write dispute_resolution_events. Feed-in export credits are priced at the tariff active at export time, not the current tariff -- export_credits rows carry credit_rate as a stored value at the time of the export event. Revenue analytics materialised views include revenue_by_tariff_by_period, peak_demand_charge_by_account, export_credit_by_account_by_period, and billing_dispute_rate_by_tariff_type -- all recomputable from billing_calculations and tariff_dispute source events.

Sustainability Reporting, Carbon Accounting, and Energy Analytics

Carbon intensity factors are stored in carbon_intensity_config keyed by (source_type, effective_from/to); updating the grid mix writes a new config row. Each carbon_events row stores the carbon_intensity_gco2_per_kwh that was active at event time, so historical emissions are preserved as-recorded and the materialised carbon footprint view always reflects the intensity factor that was actually used. Renewable energy certificates (REC | REGO | LGC) are tracked in renewable_certificates: issuing_body, mwh_certified, and status (ISSUED | RETIRED | EXPIRED); retirements write immutable retirement_events, and the original certificate record is never deleted. Sustainability targets (RENEWABLE_PCT | CARBON_INTENSITY | PEAK_DEMAND_REDUCTION) are stored in config; a sustainability_target_progress materialised view compares actual performance from source events against each target_value -- always recomputable. Analytics materialised views include energy_balance_by_site_by_hour, renewable_penetration_by_period, load_factor_by_asset, peak_demand_by_day, battery_cycle_count_by_asset, and grid_export_revenue_by_period -- all derived from append-only event logs.

Frequently Asked Questions

How are estimated meter readings distinguished from measured readings, and can they be corrected without data loss?

meter_readings carries a quality_flag (MEASURED | ESTIMATED | SUBSTITUTED). Estimated readings are flagged rather than replacing measured rows. When a confirmed MEASURED reading arrives for the same timestamp, it is written alongside the estimated row -- the estimated record is preserved. Billing logic references quality_flag and prefers MEASURED over ESTIMATED when both exist for the same interval.

How are energy tariffs applied when a billing period spans a tariff change date?

energy_tariff_config rows are immutable once published. Each billing_calculation row references the tariff_version_id active at billing_period_start. Consumption before the change is billed at the old tariff, consumption after at the new tariff. Because both config rows are preserved, the calculation can always be re-audited against the exact tariff active at each interval.

How is demand response settlement calculated if a site delivers less capacity than it committed?

demand_response_events records both capacity_mw_committed (at dispatch) and capacity_mw_delivered (at settlement). Shortfall between committed and delivered writes to dr_shortfall_events, which are the input to penalty calculations under the programme's settlement rules. All events are append-only -- the settlement audit trail is always preserved.

Can carbon intensity factors be updated when the grid mix changes without recalculating historical emissions?

carbon_intensity_config is keyed by (source_type, effective_from/to). Updating the grid mix factor writes a new config row. Each carbon_events row stores the intensity factor that was active at event time, so historical emissions are preserved as-recorded. The materialised carbon footprint view always reflects the factor that was actually used, not the current factor.

How quickly can an energy management platform be deployed?

Scrums.com dedicated engineering teams deliver a working first deployment in 21 days.

Want to Know if Scrums.com is a Good Fit for Your Business?

Get in touch and let us answer all your questions.

Get started

Don't Just Take Our Word for It

Hear from some of our amazing customers who are building with Scrums.com Teams.

"Scrums.com has been a long-term partner of OneCart. You have a great understanding of our business, our culture and have helped us find some real tech rockstars. Our Scrums.com team members are high-impact, hard working, always available, and fun to have around. Thanks a million!"
CTO, OneCart
On-demand marketplace connecting users and top retailers
"The Scrums.com Team is always ready to take my call and assist me with my unique challenges. No problem is to big or small. Great partner, securing strong talent to support our teams."
CIO, Network
Leading digital payments provider
"Finding great developers through Scrums.com is easier than explaining to my mom what I do for a living. Over the past couple of years, their top-tier devs and QAs have plugged seamlessly into Payfast by Network, turbo-charging our sprints without a hitch."
Engineering Manager, PayFast by Network
A secure digital payment processor for online businesses
"Our project was incredibly successful thanks to the guidance and professionalism of the Scrums.com teams. We were supported throughout the robust and purpose-driven process, and clear channels for open communication were established. The Scrums.com team often pre-empted and identified solutions and enhancements to our project, going over and above to make it a success."
CX Expert, Volkswagen Financial Services
Handles insurance, fleet and leasing
"The Scrums.com teams are extremely professional and a pleasure to work with. Open communication channels and commitment to deliver against deadlines ensures successful delivery against requirements. Their willingness to go beyond what is required and technical expertise resulted in a world class product that we are extremely proud to take to market."
Product Manager, BankservAfrica
Africa's largest clearing house
“Scrums.com Team Subscriptions allow us to easily move between tiers and as our needs have evolved, it has been incredibly convenient to adjust the subscription to meet our demands. This flexibility has been a game-changer for our business. Over and above this, one of their key strengths is the amazing team members who have brought passion and creativity to our project, with enthusiasm and commitment. They have been a joy to work with and I look forward to the continued partnership.”
CEO & Co-Founder, Ikue
World's first CDP for telcos
“Since partnering with Scrums.com in 2022, our experience has been nothing short of transformative. From day one, Scrums.com hasn't just been a service provider; they've become an integral part of our team. Despite the physical distance, their presence feels as close and accessible as if they were located in the office next door. This sense of proximity is not just geographical but extends deeply into how they have seamlessly integrated with our company's culture and identity.”
SOS Team, Skole
Helping 60k kids learn, every day
"Scrums.com joined Shout-It-Now on our mission to empower young women in South Africa to reduce the rates of HIV, GBV and unwanted pregnancy. By developing iSHOUT!, an app exclusively for young women, and Chomi, a multilingual GBV chatbot, they have contributed to the critical task of getting information & support to those who need it most. Scrums.com continues to be our collaborative partner on the vital journey."
CX Expert, iShout
Empowering the youth of tomorrow
"Scrums.com has been Aesara Partner's tech provider for the past few years; and with the development support provided by the Scrums.com team, our various platforms have evolved. Throughout the developing journey, Scrums.com has been able to provide us with a team to match our needs for that point in time."
Founder, Aesara Partners
A global transformation practice

Find Related App Types

IT Services app

Payroll app development

Loan Management app

Insurance App

Marketing Analytics app

Payment Gateway app