SDS P4 API

<back to all web services

Reading

Get readings of a metering point

The following routes are available for this service:
GET/api/v5/meteringpoints/{Ean}/readings/{Filter}/{DateFrom}Shows all readings available after DateFrom
GET/api/v5/meteringpoints/{Ean}/readings/{Filter}/{DateFrom}/{DateTo}Shows readings for period
import Foundation
import ServiceStack

/**
* Get readings of a metering point
*/
// @Api(Description="Get readings of a metering point")
public class Reading : Generic
{
    /**
    * Request of details of specific metering point with Ean
    */
    // @ApiMember(DataType="EAN (18 numbers)", Description="Request of details of specific metering point with Ean", Name="Ean")
    public var ean:String

    /**
    * Detail gives hourly readings for gas and 15 minutes readings for electricity. Only register 1.8.0 (G&E) and 2.8.0 (E) are available. The Day and Month filter are by default also based on the detail readings. Optional it is possible to get the values from the day channels. Advantage: readings are the readings visible as on the smart meter and for electricity the High/Low distinction is available. Downside: for some of the older smart meter models, no decimals are available. Registers starting with 1 are usage, starting with 2 are return. Registers ending on 1 are normal/high tariff, ending on 2 are low/night/weekend tariff. For gas only register 1.8.0 is available. For electricity 1.8.1/1.8.2/2.8.1/2.8.2 are available
    */
    // @ApiMember(DataType="Enum: none/hour/day/month/year", Description="Detail gives hourly readings for gas and 15 minutes readings for electricity. Only register 1.8.0 (G&E) and 2.8.0 (E) are available. The Day and Month filter are by default also based on the detail readings. Optional it is possible to get the values from the day channels. Advantage: readings are the readings visible as on the smart meter and for electricity the High/Low distinction is available. Downside: for some of the older smart meter models, no decimals are available. Registers starting with 1 are usage, starting with 2 are return. Registers ending on 1 are normal/high tariff, ending on 2 are low/night/weekend tariff. For gas only register 1.8.0 is available. For electricity 1.8.1/1.8.2/2.8.1/2.8.2 are available", IsRequired=true, Name="Filter")
    public var filter:Filter

    /**
    * Start date the readings are requested for
    */
    // @ApiMember(DataType="Date: yyyy-mm-dd", Description="Start date the readings are requested for", IsRequired=true, Name="DateFrom")
    public var dateFrom:Date

    /**
    * End date the readings are requested for (this date is included in the response). If no date is provided the DateTo will be seven days from DateFrom.
    */
    // @ApiMember(DataType="Date: yyyy-mm-dd", Description="End date the readings are requested for (this date is included in the response). If no date is provided the DateTo will be seven days from DateFrom.", Name="DateTo")
    public var dateTo:Date?

    /**
    * See filter. Readings are available from the Detail or Day channel. Default value: Detail
    */
    // @ApiMember(DataType="Enum: detail/day", Description="See filter. Readings are available from the Detail or Day channel. Default value: Detail", Name="Source")
    public var source:MeasurementSource

    /**
    * Add column with Dutch day (Default: false)
    */
    // @ApiMember(DataType="Boolean", Description="Add column with Dutch day (Default: false)", Name="AddDateNL")
    public var addDateNL:Bool

    /**
    * Add the first reading of the next day if available. Only available/relevant if no aggregation / source is detail (Default: true)
    */
    // @ApiMember(DataType="Boolean", Description="Add the first reading of the next day if available. Only available/relevant if no aggregation / source is detail (Default: true)", Name="AddFirstReadingNextDay")
    public var addFirstReadingNextDay:Bool?

    /**
    * Add columns with CreatedOn and LastUpdated (Default: false)
    */
    // @ApiMember(DataType="Boolean", Description="Add columns with CreatedOn and LastUpdated (Default: false)", Name="AddTimestamps")
    public var addTimestamps:Bool

    /**
    * Add column with ean (Default: false)
    */
    // @ApiMember(DataType="Boolean", Description="Add column with ean (Default: false)", Name="AddEan")
    public var addEan:Bool

    /**
    * Add column with the meter serial number (Default: false)
    */
    // @ApiMember(DataType="Boolean", Description="Add column with the meter serial number (Default: false)", Name="AddMeterId")
    public var addMeterId:Bool

    /**
    * Create a row for each register instead of a column/field for each register (Default: false)
    */
    // @ApiMember(DataType="Boolean", Description="Create a row for each register instead of a column/field for each register (Default: false)", Name="RegistersInRows")
    public var registersInRows:Bool

    required public init(){ super.init() }

    private enum CodingKeys : String, CodingKey {
        case ean
        case filter
        case dateFrom
        case dateTo
        case source
        case addDateNL
        case addFirstReadingNextDay
        case addTimestamps
        case addEan
        case addMeterId
        case registersInRows
    }

    required public init(from decoder: Decoder) throws {
        try super.init(from: decoder)
        let container = try decoder.container(keyedBy: CodingKeys.self)
        ean = try container.decodeIfPresent(String.self, forKey: .ean)
        filter = try container.decodeIfPresent(Filter.self, forKey: .filter)
        dateFrom = try container.decodeIfPresent(Date.self, forKey: .dateFrom)
        dateTo = try container.decodeIfPresent(Date.self, forKey: .dateTo)
        source = try container.decodeIfPresent(MeasurementSource.self, forKey: .source)
        addDateNL = try container.decodeIfPresent(Bool.self, forKey: .addDateNL)
        addFirstReadingNextDay = try container.decodeIfPresent(Bool.self, forKey: .addFirstReadingNextDay)
        addTimestamps = try container.decodeIfPresent(Bool.self, forKey: .addTimestamps)
        addEan = try container.decodeIfPresent(Bool.self, forKey: .addEan)
        addMeterId = try container.decodeIfPresent(Bool.self, forKey: .addMeterId)
        registersInRows = try container.decodeIfPresent(Bool.self, forKey: .registersInRows)
    }

    public override func encode(to encoder: Encoder) throws {
        try super.encode(to: encoder)
        var container = encoder.container(keyedBy: CodingKeys.self)
        if ean != nil { try container.encode(ean, forKey: .ean) }
        if filter != nil { try container.encode(filter, forKey: .filter) }
        if dateFrom != nil { try container.encode(dateFrom, forKey: .dateFrom) }
        if dateTo != nil { try container.encode(dateTo, forKey: .dateTo) }
        if source != nil { try container.encode(source, forKey: .source) }
        if addDateNL != nil { try container.encode(addDateNL, forKey: .addDateNL) }
        if addFirstReadingNextDay != nil { try container.encode(addFirstReadingNextDay, forKey: .addFirstReadingNextDay) }
        if addTimestamps != nil { try container.encode(addTimestamps, forKey: .addTimestamps) }
        if addEan != nil { try container.encode(addEan, forKey: .addEan) }
        if addMeterId != nil { try container.encode(addMeterId, forKey: .addMeterId) }
        if registersInRows != nil { try container.encode(registersInRows, forKey: .registersInRows) }
    }
}

public class Generic : Codable
{
    /**
    * Api-key. Used to provide credentials to the api. Can also be provided through the request headers with key: X-API-KEY
    */
    // @ApiMember(DataType="String", Description="Api-key. Used to provide credentials to the api. Can also be provided through the request headers with key: X-API-KEY", IsRequired=true, Name="ApiKey")
    public var apiKey:String

    /**
    * Normally the result of the request is put inside a resultobject with some status information about the request. If you want the output as csv this outer object can be irritating. Default value: FALSE 
    */
    // @ApiMember(DataType="Boolean", Description="Normally the result of the request is put inside a resultobject with some status information about the request. If you want the output as csv this outer object can be irritating. Default value: FALSE ", Name="OnlyPayload")
    public var onlyPayload:Bool

    /**
    * Show the request as interpreted by the api. Useful to see how filters / dates are parsed. If no value us provided, the default value is: FALSE 
    */
    // @ApiMember(DataType="Boolean", Description="Show the request as interpreted by the api. Useful to see how filters / dates are parsed. If no value us provided, the default value is: FALSE ", Name="ShowRequest")
    public var showRequest:Bool

    /**
    * Format all DateTime in the response object. If used in browser, sometimes ISO8601 is not correctly transformed. Enum options: ISO8601 (DEFAULT), UTC, NL, NLOffset, Unix, UnixMillis
    */
    // @ApiMember(DataType="Enum", Description="Format all DateTime in the response object. If used in browser, sometimes ISO8601 is not correctly transformed. Enum options: ISO8601 (DEFAULT), UTC, NL, NLOffset, Unix, UnixMillis", Name="DateTimeFormat")
    public var dateTimeFormat:DateTimeFormat

    required public init(){}
}

public enum DateTimeFormat : String, Codable
{
    case ISO8601
    case UTC
    case NL
    case NLOffset
    case IN
    case INOffset
    case Unix
    case UnixMillis
}

public enum Filter : String, Codable
{
    case None
    case Hour
    case Day
    case Month
    case Year
}

public enum MeasurementSource : String, Codable
{
    case Detail
    case Day
    case Month
    case Unknown
}


Swift Reading DTOs

To override the Content-type in your clients, use the HTTP Accept Header, append the .other suffix or ?format=other

HTTP + OTHER

The following are sample HTTP requests and responses. The placeholders shown need to be replaced with actual values.

GET /api/v5/meteringpoints/{Ean}/readings/{Filter}/{DateFrom} HTTP/1.1 
Host: p4v8.smartdatasolutions.nl 
Accept: text/jsonl