gs2

package module
v0.0.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 24, 2022 License: Apache-2.0 Imports: 9 Imported by: 0

README

GS2 decoder/encoder

Tool for decoding and encoding data according to the GS2 format (https://sintef.brage.unit.no/sintef-xmlui/handle/11250/2391930).

Current version is mostly forgiving. Mainly because there is a a lot of variation in the applications of this format in pratice.

Inspired by go json decoding/encoding, but does not support custom types as of yet.

Usage

package main

import (
	"github.com/rejlersembriq/gs2"
	"log"
	"os"
)

func main() {
	file, _ := os.Open("someGS2File.gs2")

	// Decode
	g, err := gs2.NewDecoder(file).Decode()
	if err != nil {
		log.Fatalf("error decoding: %v", err)
	}

	// Encode
	if err = gs2.NewEncoder(file).Encode(g); err != nil {
		log.Fatalf("error encoding: %v", err)
	}
}
Encoder/Decoder Options

Current options supported:

  • Decoder
    • DecodeValidators (slice of Validator to be run on GS2 object after decoding)
  • Encoder
    • EncodeValidators (slice of Validator to be run on GS2 object before encoding)
    • EncodeFloatPrecision (sets float precision when encoding floats. Default -1 = auto)

Validator

A validator is simply a function with a pointer to a GS2 object as an argument and an error as a return value.

type Validator func(*GS2) error

If you need some kind of validation that is not already defined you can define your own Validators and add them to the Encoder/Decoder before encoding/decoding. NB: When adding Validators manually remeber to also add the default validators if they are needed. Validators can also be disabled by providing an empty slice.

Example

package main

import (
	"fmt"
	"github.com/rejlersembriq/gs2"
	"log"
	"os"
)

func customValidator(g *gs2.GS2) error {
	if g.StartMessage.Description == "" {
		return fmt.Errorf("startmessage needs a description")
	}

	return nil
}

func main() {
	file, _ := os.Open("someGS2File.gs2")

	g := gs2.GS2{}

	options := []gs2.EncoderOption{
		gs2.EncodeFloatPrecision(4),
		gs2.EncodeValidators(
			gs2.ValidateNoOfObjects,
			gs2.ValidateTimeSeriesValues,
			customValidator,
		),
	}

	// Encode
	encoder := gs2.NewEncoder(file, options...)
	if err := encoder.Encode(&g); err != nil {
		log.Fatalf("error encoding: %v", err)
	}
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ValidateNoOfObjects

func ValidateNoOfObjects(g *GS2) error

ValidateNoOfObjects validates that the reported number of objects are equal to the actual number of objects in the decoded object.

func ValidateTimeSeriesValues

func ValidateTimeSeriesValues(g *GS2) error

ValidateTimeSeriesValues validates the number ov values are consistent and that sum og values in a time series block are equal to the sum attribute.

Types

type Decoder

type Decoder struct {
	// contains filtered or unexported fields
}

Decoder reads and decodes GS2 input. NB: year, month and day is not supported in Step attribute. Only hour, minute and seconds are used when decoding duration.

func NewDecoder

func NewDecoder(r io.Reader, opt ...DecoderOption) *Decoder

NewDecoder returna a new Decoder reading from r.

func (*Decoder) Decode

func (d *Decoder) Decode() (*GS2, error)

Decode reads the input and puts it in a GS2 object.

type DecoderOption

type DecoderOption func(*decoderOptions)

DecoderOption sets configuration for a Decoder.

func DecodeValidators

func DecodeValidators(v ...Validator) DecoderOption

DecodeValidators sets the validators to be run after decoding an object. Will overwrite the default ones. So remeber to add the defaults as well if needed.

type Encoder

type Encoder struct {
	// contains filtered or unexported fields
}

Encoder encodes a GS2 object and writes to an io.Writer. NB: year, month and day is not supported in Step attribute. Only hour, minute and seconds are used when encoding duration.

func NewEncoder

func NewEncoder(w io.Writer, opt ...EncoderOption) *Encoder

NewEncoder returna a new Encoder writing to w.

func (*Encoder) Encode

func (e *Encoder) Encode(g *GS2) error

Encode encodes and writes a GS2 object to an io.Writer.

type EncoderOption

type EncoderOption func(*encoderOptions)

EncoderOption sets configuration for a Encoder.

func EncodeFloatPrecision

func EncodeFloatPrecision(i int) EncoderOption

EncodeFloatPrecision sets precision when encoding floats.

func EncodeValidators

func EncodeValidators(v ...Validator) EncoderOption

EncodeValidators sets the validators to be run before encoding an object. Will overwrite the default ones. So remeber to add the defaults as well if needed.

type EndMessage

type EndMessage struct {
	ID              string    `gs2:"Id,omitempty"`
	MessageType     string    `gs2:"Message-type,omitempty"`
	Version         string    `gs2:"Version,omitempty"`
	Time            time.Time `gs2:"Time,omitempty"`
	To              string    `gs2:"To,omitempty"`
	From            string    `gs2:"From,omitempty"`
	ReferenceTable  string    `gs2:"Reference-table,omitempty"`
	GMTReference    int       `gs2:"GMT-reference,omitempty"`
	NumberOfObjects int       `gs2:"Number-of-objects"`
	TypeOfObjects   string    `gs2:"Type-of-objects,omitempty"`
	ContainsObjects string    `gs2:"Contains-objects,omitempty"`
	RequestedAction string    `gs2:"Requested-action,omitempty"`
	Description     string    `gs2:"Description,omitempty"`
}

EndMessage should always be the last object in any GS2-file-

type GS2

type GS2 struct {
	StartMessage  StartMessage   `gs2:"Start-message"`
	MeterReadings []MeterReading `gs2:"Meter-reading"`
	TimeSeries    []TimeSeries   `gs2:"Time-series"`
	EndMessage    EndMessage     `gs2:"End-message"`
}

GS2 represents the data of a GS2 file.

type MeterReading

type MeterReading struct {
	Reference       string    `gs2:"Reference,omitempty"`
	Time            time.Time `gs2:"Time,omitempty"`
	Unit            string    `gs2:"Unit,omitempty"`
	Value           Triplet   `gs2:"Value"`
	Installation    string    `gs2:"Installation,omitempty"`
	Plant           string    `gs2:"Plant,omitempty"`
	MeterLocation   string    `gs2:"Meter-location,omitempty"`
	NetOwner        string    `gs2:"Net-owner,omitempty"`
	Supplier        string    `gs2:"Supplier,omitempty"`
	Customer        string    `gs2:"Customer,omitempty"`
	Meter           string    `gs2:"Meter,omitempty"`
	Channel         string    `gs2:"Channel,omitempty"`
	Description     string    `gs2:"Description,omitempty"`
	DirectionOfFlow string    `gs2:"Direction-of-flow,omitempty"`
}

MeterReading contains a single value that is a channel reading at a given point in time.

type StartMessage

type StartMessage struct {
	ID              string    `gs2:"Id,omitempty"`
	MessageType     string    `gs2:"Message-type,omitempty"`
	Version         string    `gs2:"Version,omitempty"`
	Time            time.Time `gs2:"Time,omitempty"`
	To              string    `gs2:"To,omitempty"`
	From            string    `gs2:"From,omitempty"`
	ReferenceTable  string    `gs2:"Reference-table,omitempty"`
	GMTReference    int       `gs2:"GMT-reference,omitempty"`
	NumberOfObjects int       `gs2:"Number-of-objects,omitempty"`
	TypeOfObjects   string    `gs2:"Type-of-objects,omitempty"`
	ContainsObjects string    `gs2:"Contains-objects,omitempty"`
	RequestedAction string    `gs2:"Requested-action,omitempty"`
	Description     string    `gs2:"Description,omitempty"`
}

StartMessage should always be the first object in any GS2-file-

type TimeSeries

type TimeSeries struct {
	Reference       string        `gs2:"Reference,omitempty"`
	Start           time.Time     `gs2:"Start,omitempty"`
	Stop            time.Time     `gs2:"Stop,omitempty"`
	Step            time.Duration `gs2:"Step,omitempty"`
	Unit            string        `gs2:"Unit,omitempty"`
	TypeOfValue     string        `gs2:"Type-of-value,omitempty"`
	DirectionOfFlow string        `gs2:"Direction-of-flow,omitempty"`
	Value           []Triplet     `gs2:"Value,omitempty"`
	NoOfValues      int           `gs2:"No-of-values"`
	Sum             float64       `gs2:"Sum"`
	Installation    string        `gs2:"Installation,omitempty"`
	Plant           string        `gs2:"Plant,omitempty"`
	MeterLocation   string        `gs2:"Meter-location,omitempty"`
	NetOwner        string        `gs2:"Net-owner,omitempty"`
	Supplier        string        `gs2:"Supplier,omitempty"`
	Customer        string        `gs2:"Customer,omitempty"`
	Meter           string        `gs2:"Meter,omitempty"`
	Channel         string        `gs2:"Channel,omitempty"`
	Description     string        `gs2:"Description,omitempty"`
}

TimeSeries contains time series of metered values within the interval given by start and stop.

type Triplet

type Triplet struct {
	Value   float64
	Time    time.Time
	Quality string
}

Triplet represents a value triplet with value, time and quality.

type Validator

type Validator func(*GS2) error

Validator is a function taking in a refenrece to a GS" object and returns an error if its not valid.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL