Back

Topic

[KB1267]Energy consumption counters using EXPORT_TREND and GETSTATISTIC

Tags: Energy, Export, Scada Basic, Trend

38 minutes ago
By LM
Options
Print
Applies to:
PcVue 16.3.4 onwards
Summary:
This article explains how to use the `EXPORT_TREND` instruction with the `GETSTATISTIC` mode and the `COUNTER` statistical flag to compute energy consumption counters (active and reactive) over multiple time periods: current day, last day, current month, last month, current year, and last year. The result is written as a formatted string into two SCADA registers (`ACTIVE_ENERGY_TXT`, `REACTIVE_ENERGY_TXT`) that can be displayed directly in a synoptic.
Details:

Overview

The script is structured around a single common export launcher (DoExport) that is called by six period-specific sub-routines. Each sub-routine calculates the appropriate start/end timestamps for its period and invokes the common launcher.

Two trend variables are sampled per export:

Trend variableMeaning
@BUILDING.ACTIVE_ENERGYActive energy (kWh)
@BUILDING.REACTIVE_ENERGYReactive energy (kvarh)

The COUNTER statistical flag (value 128) is used so that Export_Trend returns the difference between the last and first recorded values within the requested period, automatically handling meter rollover. Here below is the home mimic of the sample project with current day consumption display:

image
image

Scheduling

Counters are refreshed by two complementary mechanisms declared in Sub Main():

Cyclic triggers — current-period counters

Prime-spaced intervals are used to prevent simultaneous execution of the three cyclic jobs:

PeriodInterval (s)Sub-routineTarget branch
Current day127Export_CurrentDayCountersBUILDING.CONSUMPTION.CURRENTDAY
Current month131Export_CurrentMonthCountersBUILDING.CONSUMPTION.CURRENTMONTH
Current year137Export_CurrentYearCountersBUILDING.CONSUMPTION.CURRENTYEAR

Crontab triggers — closed-period counters

These fire once per period boundary to capture the definitive counter value:

PeriodScheduleSub-routineTarget branch
Last dayEvery day at 00:01Export_LastDayCountersBUILDING.CONSUMPTION.LASTDAY
Last month1st of month at 00:02Export_LastMonthCountersBUILDING.CONSUMPTION.LASTMONTH
Last year1st of month at 00:03Export_LastYearCountersBUILDING.CONSUMPTION.LASTYEAR

Note on offsets: The one- to three-minute offsets ensure that archiving of the last timestamp has completed before the export is triggered.


Period-Timestamp Calculation

All timestamps are expressed in milliseconds since 01/01/1980, as required by Export_Trend.

PeriodStartEnd
Current dayDateTimeValue(DAY, MONTH, YEAR, 0, 0, 0)DateTimeValue() (now)
Last dayYesterday at 00:00:00Yesterday at 23:59:59
Current monthDateTimeValue(1, MONTH, YEAR, 0, 0, 0)DateTimeValue() (now)
Last month1st of previous month at 00:00:00Last day of previous month at 23:59:59
Current yearDateTimeValue(1, 1, YEAR, 0, 0, 0)DateTimeValue() (now)
Last yearDateTimeValue(1, 1, YEAR-1, 0, 0, 0)DateTimeValue(31, 12, YEAR-1, 23, 59, 59)

Previous-month bounds are computed by GetPreviousMonthBounds: subtracting 1 ms from the first instant of the current month always lands on the last instant of the previous month, giving the correct day, month, and year without any calendar arithmetic.


Export Flow

Period sub-routine
      │
      └─► DoExport(dStart, dEnd, sPeriod)
               │
               ├── g_sPeriod = sPeriod          ← store branth tag for the callback
               ├── Event("ADDPROG", "@EXPORT.STATUS", …, sPeriod, "Get_Counters")
               ├── Export_Trend("GETSTATISTIC", …, COUNTER)
               └── CheckExportReturn(iResult)
                         │
              ┌──────────┘ (async – on @EXPORT.STATUS change)
              │
              └─► Get_Counters()
                       │
                       ├── status 0 / 4 / 5 → read buffer, write registers, DISPOSE
                       ├── status 1          → still running, do nothing
                       └── other             → log error, CANCEL + DISPOSE

The completion event (@EXPORT.STATUS) is registered before Export_Trend is called to avoid a race condition where the export completes synchronously before the event listener is armed.


Buffer Reading — Get_Counters

Export_Trend("READBUFFER", …) returns a block structured as:

Line 0  — variable names  (skipped)
Line 1  — descriptions    (skipped)
Line 2  — data row:  <Counter> ; <active_energy> ; <reactive_energy>

Seq_Buffer with "\n" separator iterates lines; with ";" separator it iterates fields within a line. The Counter column (field 0) is discarded; fields 1 and 2 are read as DOUBLE and rounded before formatting.


Output Formatting — FormatWithSpaces

Raw integer values are converted to strings and a space character is inserted every three digits from the right (e.g., 1254300 → "1 254 300"). This is done with a single forward pass:

  • Convert the number to a string with TOC().
  • For each character at position i (1-based), insert a space when (len − i) MOD 3 == 2 and i > 1.

Values of three digits or fewer are returned unchanged.


Error Handling — CheckExportReturn

If Export_Trend returns a non-zero value immediately (synchronous error), CheckExportReturn prints a human-readable description of every documented error code (−1 through −30) and calls CANCEL + DISPOSE to release the internal request object.


Debug Mode

Set Const DEBUG = 1 at the top of the script to enable Print trace output in the SCADABasic log. Set back to 0 in production.


Required Configuration

ItemRequirement
Trend recording@BUILDING.ACTIVE_ENERGY and @BUILDING.REACTIVE_ENERGY must be configured for trend recording in PcVue.
Data Export licenceThe Data Export module must be licensed in the PcVue protection key. Without it, Export_Trend runs in demonstration mode only.
Output variablesACTIVE_ENERGY_TXT and REACTIVE_ENERGY_TXT must exist as text variables in the application.
Status register@EXPORT.STATUS must exist as a register in the application.
UnitThe UnitName parameter is set to PROP_UNIT01; adjust to match your project’s unit name.

Attached Files

PowerCalcs.SCB

SampleProject.zip

Created on: 25 Apr 2026