/**
 * @license
 * Copyright 2022-2025 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
import { MutableCluster } from "../cluster/mutation/MutableCluster.js";
import { Attribute, OptionalAttribute, Event, FixedAttribute } from "../cluster/Cluster.js";
import { TlvField, TlvOptionalField, TlvObject } from "../tlv/TlvObject.js";
import { TlvInt64, TlvEpochS, TlvSysTimeMS } from "../tlv/TlvNumber.js";
import { TlvNullable } from "../tlv/TlvNullable.js";
import { Priority } from "../globals/Priority.js";
import { BitFlag } from "../schema/BitmapSchema.js";
import { TlvMeasurementAccuracy } from "../globals/MeasurementAccuracy.js";
import { ClusterRegistry } from "../cluster/ClusterRegistry.js";
var ElectricalEnergyMeasurement;
((ElectricalEnergyMeasurement2) => {
  let Feature;
  ((Feature2) => {
    Feature2["ImportedEnergy"] = "ImportedEnergy";
    Feature2["ExportedEnergy"] = "ExportedEnergy";
    Feature2["CumulativeEnergy"] = "CumulativeEnergy";
    Feature2["PeriodicEnergy"] = "PeriodicEnergy";
  })(Feature = ElectricalEnergyMeasurement2.Feature || (ElectricalEnergyMeasurement2.Feature = {}));
  ElectricalEnergyMeasurement2.TlvEnergyMeasurement = TlvObject({
    /**
     * This field shall be the reported energy.
     *
     * If the EnergyMeasurementStruct represents cumulative energy, then this shall represent the cumulative energy
     * recorded at either the value of the EndTimestamp field or the value of the EndSystime field, or both.
     *
     * If the EnergyMeasurementStruct represents periodic energy, then this shall represent the energy recorded
     * during the period specified by either the StartTimestamp and EndTimestamp fields, the period specified by the
     * StartSystime and EndSystime fields, or both.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 2.12.5.2.1
     */
    energy: TlvField(0, TlvInt64.bound({ min: 0 })),
    /**
     * This field shall indicate the timestamp in UTC of the beginning of the period during which the value of the
     * Energy field was measured.
     *
     * If this EnergyMeasurementStruct represents cumulative energy, this field shall be omitted.
     *
     * Otherwise, if the server had determined the time in UTC at or before the beginning of the measurement period,
     * this field shall be indicated.
     *
     * Otherwise, if the server had not yet determined the time in UTC at or before the beginning of the measurement
     * period, or does not have the capability of determining the time in UTC, this field shall be omitted.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 2.12.5.2.2
     */
    startTimestamp: TlvOptionalField(1, TlvEpochS),
    /**
     * This field shall indicate the timestamp in UTC of the end of the period during which the value of the Energy
     * field was measured.
     *
     * If the server had determined the time in UTC by the end of the measurement period, this field shall be
     * indicated.
     *
     * Otherwise, if the server had not yet determined the time in UTC by the end of the measurement period, or does
     * not have the capability of determining the time in UTC, this field shall be omitted.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 2.12.5.2.3
     */
    endTimestamp: TlvOptionalField(2, TlvEpochS),
    /**
     * This field shall indicate the time elapsed since boot at the beginning of the period during which the value
     * of the Energy field was measured.
     *
     * If this EnergyMeasurementStruct represents cumulative energy, this field shall be omitted.
     *
     * Otherwise, if the server had not yet determined the time in UTC at the start of the measurement period, or
     * does not have the capability of determining the time in UTC, this field shall be indicated.
     *
     * Otherwise, if the server had determined the time in UTC at or before the beginning of the measurement period,
     * this field may be omitted; if it is indicated, its value shall be the time elapsed since boot at the UTC time
     * indicated in StartTimestamp.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 2.12.5.2.4
     */
    startSystime: TlvOptionalField(3, TlvSysTimeMS),
    /**
     * This field shall indicate the time elapsed since boot at the end of the period during which the value of the
     * Energy field was measured.
     *
     * If the server had not yet determined the time in UTC by the end of the measurement period, or does not have
     * the capability of determining the time in UTC, this field shall be indicated.
     *
     * Otherwise, if the server had determined the time in UTC by the end of the measurement period, this field may
     * be omitted; if it is indicated, its value shall be the time elapsed since boot at the UTC time indicated in
     * EndTimestamp.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 2.12.5.2.5
     */
    endSystime: TlvOptionalField(4, TlvSysTimeMS)
  });
  ElectricalEnergyMeasurement2.TlvCumulativeEnergyReset = TlvObject({
    /**
     * This field shall indicate the timestamp in UTC when the value of the Energy field on the
     * CumulativeEnergyImported attribute was most recently zero.
     *
     * If the server had determined the time in UTC when the value of the Energy field on the
     * CumulativeEnergyImported attribute was most recently zero, this field shall be indicated.
     *
     * Otherwise, if the server had not yet determined the time in UTC when the value of the Energy field on the
     * CumulativeEnergyImported attribute was most recently zero, or does not have the capability of determining the
     * time in UTC, this field shall be omitted.
     *
     * If the timestamp in UTC when the value of the Energy field on the CumulativeEnergyImported attribute was most
     * recently zero cannot currently be determined, a value of null shall be returned.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 2.12.5.3.1
     */
    importedResetTimestamp: TlvOptionalField(0, TlvNullable(TlvEpochS)),
    /**
     * This field shall indicate the timestamp in UTC when the value of the Energy field on the
     * CumulativeEnergyExported attribute was most recently zero.
     *
     * If the server had determined the time in UTC when the value of the Energy field on the
     * CumulativeEnergyExported attribute was most recently zero, this field shall be indicated.
     *
     * Otherwise, if the server had not yet determined the time in UTC when the value of the Energy field on the
     * CumulativeEnergyExported attribute was most recently zero, or does not have the capability of determining the
     * time in UTC, this field shall be omitted.
     *
     * If the timestamp in UTC when the value of the Energy field on the CumulativeEnergyExported attribute was most
     * recently zero cannot currently be determined, a value of null shall be returned.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 2.12.5.3.2
     */
    exportedResetTimestamp: TlvOptionalField(1, TlvNullable(TlvEpochS)),
    /**
     * This field shall indicate the time elapsed since boot when the value of the Energy field on the
     * CumulativeEnergyImported attribute was most recently zero.
     *
     * If the server had not yet determined the time in UTC when the value of the Energy field on the
     * CumulativeEnergyImported attribute was most recently zero, or does not have the capability of determining the
     * time in UTC, this field shall be indicated.
     *
     * Otherwise, if the server had determined the time in UTC when the value of the Energy field on the
     * CumulativeEnergyImported attribute was most recently zero, this field may be omitted; if it is indicated, its
     * value shall be the time elapsed since boot at the UTC time indicated in ImportedResetTimestamp.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 2.12.5.3.3
     */
    importedResetSystime: TlvOptionalField(2, TlvNullable(TlvSysTimeMS)),
    /**
     * This field shall indicate the time elapsed since boot when the value of the Energy field on the
     * CumulativeEnergyExported attribute was most recently zero.
     *
     * If the server had not yet determined the time in UTC when the value of the Energy field on the
     * CumulativeEnergyExported attribute was most recently zero, or does not have the capability of determining the
     * time in UTC, this field shall be indicated.
     *
     * Otherwise, if the server had determined the time in UTC when the value of the Energy field on the
     * CumulativeEnergyExported attribute was most recently zero, this field may be omitted; if it is indicated, its
     * value shall be the time elapsed since boot at the UTC time indicated in ImportedResetTimestamp.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 2.12.5.3.4
     */
    exportedResetSystime: TlvOptionalField(3, TlvNullable(TlvSysTimeMS))
  });
  ElectricalEnergyMeasurement2.TlvCumulativeEnergyMeasuredEvent = TlvObject({
    /**
     * This field shall be the value of CumulativeEnergyImported attribute at the timestamp indicated in its
     * EndTimestamp field, EndSystime field, or both.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 2.12.7.1.1
     */
    energyImported: TlvOptionalField(0, ElectricalEnergyMeasurement2.TlvEnergyMeasurement),
    /**
     * This field shall be the value of CumulativeEnergyExported attribute at the timestamp indicated in its
     * EndTimestamp field, EndSystime field, or both.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 2.12.7.1.2
     */
    energyExported: TlvOptionalField(1, ElectricalEnergyMeasurement2.TlvEnergyMeasurement)
  });
  ElectricalEnergyMeasurement2.TlvPeriodicEnergyMeasuredEvent = TlvObject({
    /**
     * This field shall be the value of PeriodicEnergyImported attribute at the timestamp indicated in its
     * EndTimestamp field, EndSystime field, or both.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 2.12.7.2.1
     */
    energyImported: TlvOptionalField(0, ElectricalEnergyMeasurement2.TlvEnergyMeasurement),
    /**
     * This field shall be the value of PeriodicEnergyExported attribute at the timestamp indicated in its
     * EndTimestamp field, EndSystime field, or both.
     *
     * @see {@link MatterSpecification.v142.Cluster} § 2.12.7.2.2
     */
    energyExported: TlvOptionalField(1, ElectricalEnergyMeasurement2.TlvEnergyMeasurement)
  });
  let MeasurementType;
  ((MeasurementType2) => {
    MeasurementType2[MeasurementType2["Unspecified"] = 0] = "Unspecified";
    MeasurementType2[MeasurementType2["Voltage"] = 1] = "Voltage";
    MeasurementType2[MeasurementType2["ActiveCurrent"] = 2] = "ActiveCurrent";
    MeasurementType2[MeasurementType2["ReactiveCurrent"] = 3] = "ReactiveCurrent";
    MeasurementType2[MeasurementType2["ApparentCurrent"] = 4] = "ApparentCurrent";
    MeasurementType2[MeasurementType2["ActivePower"] = 5] = "ActivePower";
    MeasurementType2[MeasurementType2["ReactivePower"] = 6] = "ReactivePower";
    MeasurementType2[MeasurementType2["ApparentPower"] = 7] = "ApparentPower";
    MeasurementType2[MeasurementType2["RmsVoltage"] = 8] = "RmsVoltage";
    MeasurementType2[MeasurementType2["RmsCurrent"] = 9] = "RmsCurrent";
    MeasurementType2[MeasurementType2["RmsPower"] = 10] = "RmsPower";
    MeasurementType2[MeasurementType2["Frequency"] = 11] = "Frequency";
    MeasurementType2[MeasurementType2["PowerFactor"] = 12] = "PowerFactor";
    MeasurementType2[MeasurementType2["NeutralCurrent"] = 13] = "NeutralCurrent";
    MeasurementType2[MeasurementType2["ElectricalEnergy"] = 14] = "ElectricalEnergy";
    MeasurementType2[MeasurementType2["ReactiveEnergy"] = 15] = "ReactiveEnergy";
    MeasurementType2[MeasurementType2["ApparentEnergy"] = 16] = "ApparentEnergy";
  })(MeasurementType = ElectricalEnergyMeasurement2.MeasurementType || (ElectricalEnergyMeasurement2.MeasurementType = {}));
  ElectricalEnergyMeasurement2.ImportedEnergyAndCumulativeEnergyComponent = MutableCluster.Component({
    attributes: {
      /**
       * Indicates the most recent measurement of cumulative energy imported by the server over the lifetime of
       * the device, and the timestamp of when the measurement was recorded.
       *
       * The reporting interval of this attribute shall be manufacturer dependent. The server may choose to omit
       * publication of deltas considered not meaningful.
       *
       * The server shall NOT mark this attribute ready for report if the last time this was done was more
       * recently than 1 second ago.
       *
       * The server may delay marking this attribute ready for report for longer periods if needed, however the
       * server shall NOT delay marking this attribute as ready for report for longer than 60 seconds.
       *
       * If the cumulative energy imported cannot currently be determined, a value of null shall be returned.
       *
       * @see {@link MatterSpecification.v142.Cluster} § 2.12.6.2
       */
      cumulativeEnergyImported: Attribute(1, TlvNullable(ElectricalEnergyMeasurement2.TlvEnergyMeasurement))
    }
  });
  ElectricalEnergyMeasurement2.ExportedEnergyAndCumulativeEnergyComponent = MutableCluster.Component({
    attributes: {
      /**
       * Indicates the most recent measurement of cumulative energy exported by the server over the lifetime of
       * the device, and the timestamp of when the measurement was recorded.
       *
       * The reporting interval of this attribute shall be manufacturer dependent. The server may choose to omit
       * publication of deltas considered not meaningful.
       *
       * The server shall NOT mark this attribute ready for report if the last time this was done was more
       * recently than 1 second ago.
       *
       * The server may delay marking this attribute ready for report for longer periods if needed, however the
       * server shall NOT delay marking this attribute as ready for report for longer than 60 seconds.
       *
       * If the cumulative energy exported cannot currently be determined, a value of null shall be returned.
       *
       * @see {@link MatterSpecification.v142.Cluster} § 2.12.6.3
       */
      cumulativeEnergyExported: Attribute(2, TlvNullable(ElectricalEnergyMeasurement2.TlvEnergyMeasurement))
    }
  });
  ElectricalEnergyMeasurement2.ImportedEnergyAndPeriodicEnergyComponent = MutableCluster.Component({
    attributes: {
      /**
       * Indicates the most recent measurement of energy imported by the server and the period during which it was
       * measured.
       *
       * The reporting interval of this attribute shall be manufacturer dependent. The server may choose to omit
       * publication of deltas considered not meaningful.
       *
       * The server shall NOT mark this attribute ready for report if the last time this was done was more
       * recently than 1 second ago.
       *
       * The server may delay marking this attribute ready for report for longer periods if needed, however the
       * server shall NOT delay marking this attribute as ready for report for longer than 60 seconds.
       *
       * If the periodic energy imported cannot currently be determined, a value of null shall be returned.
       *
       * @see {@link MatterSpecification.v142.Cluster} § 2.12.6.4
       */
      periodicEnergyImported: Attribute(3, TlvNullable(ElectricalEnergyMeasurement2.TlvEnergyMeasurement))
    }
  });
  ElectricalEnergyMeasurement2.ExportedEnergyAndPeriodicEnergyComponent = MutableCluster.Component({
    attributes: {
      /**
       * Indicates the most recent measurement of energy exported by the server and the period during which it was
       * measured.
       *
       * The reporting interval of this attribute shall be manufacturer dependent. The server may choose to omit
       * publication of deltas considered not meaningful.
       *
       * The server shall NOT mark this attribute ready for report if the last time this was done was more
       * recently than 1 second ago.
       *
       * The server may delay marking this attribute ready for report for longer periods if needed, however the
       * server shall NOT delay marking this attribute as ready for report for longer than 60 seconds.
       *
       * If the periodic energy exported cannot currently be determined, a value of null shall be returned.
       *
       * @see {@link MatterSpecification.v142.Cluster} § 2.12.6.5
       */
      periodicEnergyExported: Attribute(4, TlvNullable(ElectricalEnergyMeasurement2.TlvEnergyMeasurement))
    }
  });
  ElectricalEnergyMeasurement2.CumulativeEnergyComponent = MutableCluster.Component({
    attributes: {
      /**
       * Indicates when cumulative measurements were most recently zero.
       *
       * @see {@link MatterSpecification.v142.Cluster} § 2.12.6.6
       */
      cumulativeEnergyReset: OptionalAttribute(5, TlvNullable(ElectricalEnergyMeasurement2.TlvCumulativeEnergyReset), { default: null })
    },
    events: {
      /**
       * This event shall be generated when the server takes a snapshot of the cumulative energy imported by the
       * server, exported from the server, or both, but not more frequently than the rate mentioned in the
       * description above of the related attribute.
       *
       * @see {@link MatterSpecification.v142.Cluster} § 2.12.7.1
       */
      cumulativeEnergyMeasured: Event(0, Priority.Info, ElectricalEnergyMeasurement2.TlvCumulativeEnergyMeasuredEvent)
    }
  });
  ElectricalEnergyMeasurement2.PeriodicEnergyComponent = MutableCluster.Component({
    events: {
      /**
       * This event shall be generated when the server reaches the end of a reporting period for imported energy,
       * exported energy, or both.
       *
       * @see {@link MatterSpecification.v142.Cluster} § 2.12.7.2
       */
      periodicEnergyMeasured: Event(1, Priority.Info, ElectricalEnergyMeasurement2.TlvPeriodicEnergyMeasuredEvent)
    }
  });
  ElectricalEnergyMeasurement2.Base = MutableCluster.Component({
    id: 145,
    name: "ElectricalEnergyMeasurement",
    revision: 1,
    features: {
      /**
       * The feature indicates the server is capable of measuring how much energy is imported by the server.
       *
       * @see {@link MatterSpecification.v142.Cluster} § 2.12.4.1
       */
      importedEnergy: BitFlag(0),
      /**
       * The feature indicates the server is capable of measuring how much energy is exported by the server.
       *
       * @see {@link MatterSpecification.v142.Cluster} § 2.12.4.2
       */
      exportedEnergy: BitFlag(1),
      /**
       * The feature indicates the server is capable of measuring how much energy has been imported or exported by
       * the server over the device’s lifetime. This measurement may start from when a device’s firmware is
       * updated to include this feature, when a device’s firmware is updated to correct measurement errors, or
       * when a device is factory reset.
       *
       * @see {@link MatterSpecification.v142.Cluster} § 2.12.4.3
       */
      cumulativeEnergy: BitFlag(2),
      /**
       * The feature indicates the server is capable of measuring how much energy has been imported or exported by
       * the server during a certain period of time. The start and end times for measurement periods shall be
       * determined by the server, and may represent overlapping periods.
       *
       * @see {@link MatterSpecification.v142.Cluster} § 2.12.4.4
       */
      periodicEnergy: BitFlag(3)
    },
    attributes: {
      /**
       * Indicates the accuracy of energy measurement by this server. The value of the MeasurementType field on
       * this MeasurementAccuracyStruct shall be ElectricalEnergy.
       *
       * @see {@link MatterSpecification.v142.Cluster} § 2.12.6.1
       */
      accuracy: FixedAttribute(0, TlvMeasurementAccuracy)
    },
    /**
     * This metadata controls which ElectricalEnergyMeasurementCluster elements matter.js activates for specific
     * feature combinations.
     */
    extensions: MutableCluster.Extensions(
      {
        flags: { importedEnergy: true, cumulativeEnergy: true },
        component: ElectricalEnergyMeasurement2.ImportedEnergyAndCumulativeEnergyComponent
      },
      {
        flags: { exportedEnergy: true, cumulativeEnergy: true },
        component: ElectricalEnergyMeasurement2.ExportedEnergyAndCumulativeEnergyComponent
      },
      {
        flags: { importedEnergy: true, periodicEnergy: true },
        component: ElectricalEnergyMeasurement2.ImportedEnergyAndPeriodicEnergyComponent
      },
      {
        flags: { exportedEnergy: true, periodicEnergy: true },
        component: ElectricalEnergyMeasurement2.ExportedEnergyAndPeriodicEnergyComponent
      },
      { flags: { cumulativeEnergy: true }, component: ElectricalEnergyMeasurement2.CumulativeEnergyComponent },
      { flags: { periodicEnergy: true }, component: ElectricalEnergyMeasurement2.PeriodicEnergyComponent },
      { flags: { importedEnergy: false, exportedEnergy: false }, component: false },
      { flags: { cumulativeEnergy: false, periodicEnergy: false }, component: false }
    )
  });
  ElectricalEnergyMeasurement2.ClusterInstance = MutableCluster.ExtensibleOnly(ElectricalEnergyMeasurement2.Base);
  ElectricalEnergyMeasurement2.Cluster = ElectricalEnergyMeasurement2.ClusterInstance;
  const IMPE_CUME = { importedEnergy: true, cumulativeEnergy: true };
  const EXPE_CUME = { exportedEnergy: true, cumulativeEnergy: true };
  const IMPE_PERE = { importedEnergy: true, periodicEnergy: true };
  const EXPE_PERE = { exportedEnergy: true, periodicEnergy: true };
  const CUME = { cumulativeEnergy: true };
  const PERE = { periodicEnergy: true };
  ElectricalEnergyMeasurement2.CompleteInstance = MutableCluster({
    id: ElectricalEnergyMeasurement2.Base.id,
    name: ElectricalEnergyMeasurement2.Base.name,
    revision: ElectricalEnergyMeasurement2.Base.revision,
    features: ElectricalEnergyMeasurement2.Base.features,
    attributes: {
      ...ElectricalEnergyMeasurement2.Base.attributes,
      cumulativeEnergyImported: MutableCluster.AsConditional(
        ElectricalEnergyMeasurement2.ImportedEnergyAndCumulativeEnergyComponent.attributes.cumulativeEnergyImported,
        { mandatoryIf: [IMPE_CUME] }
      ),
      cumulativeEnergyExported: MutableCluster.AsConditional(
        ElectricalEnergyMeasurement2.ExportedEnergyAndCumulativeEnergyComponent.attributes.cumulativeEnergyExported,
        { mandatoryIf: [EXPE_CUME] }
      ),
      periodicEnergyImported: MutableCluster.AsConditional(
        ElectricalEnergyMeasurement2.ImportedEnergyAndPeriodicEnergyComponent.attributes.periodicEnergyImported,
        { mandatoryIf: [IMPE_PERE] }
      ),
      periodicEnergyExported: MutableCluster.AsConditional(
        ElectricalEnergyMeasurement2.ExportedEnergyAndPeriodicEnergyComponent.attributes.periodicEnergyExported,
        { mandatoryIf: [EXPE_PERE] }
      ),
      cumulativeEnergyReset: MutableCluster.AsConditional(
        ElectricalEnergyMeasurement2.CumulativeEnergyComponent.attributes.cumulativeEnergyReset,
        { optionalIf: [CUME] }
      )
    },
    events: {
      cumulativeEnergyMeasured: MutableCluster.AsConditional(
        ElectricalEnergyMeasurement2.CumulativeEnergyComponent.events.cumulativeEnergyMeasured,
        { mandatoryIf: [CUME] }
      ),
      periodicEnergyMeasured: MutableCluster.AsConditional(
        ElectricalEnergyMeasurement2.PeriodicEnergyComponent.events.periodicEnergyMeasured,
        { mandatoryIf: [PERE] }
      )
    }
  });
  ElectricalEnergyMeasurement2.Complete = ElectricalEnergyMeasurement2.CompleteInstance;
})(ElectricalEnergyMeasurement || (ElectricalEnergyMeasurement = {}));
const ElectricalEnergyMeasurementCluster = ElectricalEnergyMeasurement.Cluster;
ClusterRegistry.register(ElectricalEnergyMeasurement.Complete);
export {
  ElectricalEnergyMeasurement,
  ElectricalEnergyMeasurementCluster
};
//# sourceMappingURL=electrical-energy-measurement.js.map
