Skip to main content

A Python library for the Itron / Actaris IFLAG and Corus protocol

Project description

iflag

A Python library for the Itron / Actaris IFLAG and Corus protocol

Installing

Install via pip, python 3.6+ only

pip install iflag

About

iflag is a library focused on reading and writing data to devices using the IFLAG or Corus protocol. Mainly Itron / Actaris gas volume converters. Communication is done over TCP/IP

Features

The library is now only focused on using Single Address Mode (SAM) of the Corus protocol to access data. SEVC-D parameters of I-FLAG is not supported.

  • Read parameters
  • Write parameters
  • Read databases (logs), event log not yet implemented

Usage

  • Different firmware versions have different ID for each parameter. But the parameter_id_map is always on id 0x5e. So the mapping should be known beforehand or it should be read from the device before reading more values.

  • Different firmware versions also have different database record layout. You will need to supply a mapping of how the databases looks like for the meters you want to read. A default mapping is not supplied since it would infer opinionated interpretation of some values.

    You should create a mapping like: Dict[str, Dict[int, List[DatabaseRecordParameter]]] interval is the database and 52 is the length of the database record. A list of DatabaseRecordParameter in the order they are appearing in the data base record will make it possible to convert the bytes into python values.

    Ex:

  {
    "interval": {
        52: [
            DatabaseRecordParameter(name="record_duration", data_class=data.Byte),
            DatabaseRecordParameter(name="status", data_class=data.Byte),
            DatabaseRecordParameter(name="end_date", data_class=data.Date),
            DatabaseRecordParameter(
                name="consumption_interval_unconverted",
                data_class=data.Word,
                affected_by_pulse_input=True,
            ),
            DatabaseRecordParameter(
                name="consumption_interval_converted",
                data_class=data.ULong,
                affected_by_pulse_input=True,
            ),
            DatabaseRecordParameter(
                name="counter_interval_unconverted",
                data_class=data.Word,
                affected_by_pulse_input=True,
            ),
            DatabaseRecordParameter(
                name="counter_interval_converted",
                data_class=data.ULong,
                affected_by_pulse_input=True,
            ),
            DatabaseRecordParameter(
                name="temperature_interval_minimum", data_class=data.Float1
            ),
            DatabaseRecordParameter(
                name="temperature_interval_maximum", data_class=data.Float1
            ),
            DatabaseRecordParameter(
                name="temperature_interval_average", data_class=data.Float1
            ),
            DatabaseRecordParameter(
                name="pressure_interval_minimum", data_class=data.Float2
            ),
            DatabaseRecordParameter(
                name="pressure_interval_maximum", data_class=data.Float2
            ),
            DatabaseRecordParameter(
                name="pressure_interval_average", data_class=data.Float2
            ),
            DatabaseRecordParameter(
                name="flowrate_unconverted_interval_minimum",
                data_class=data.Float3,
                affected_by_pulse_input=True,
            ),
            DatabaseRecordParameter(
                name="flowrate_unconverted_interval_maximum",
                data_class=data.Float3,
                affected_by_pulse_input=True,
            ),
            DatabaseRecordParameter(
                name="flowrate_converted_interval_minimum",
                data_class=data.Float3,
                affected_by_pulse_input=True,
            ),
            DatabaseRecordParameter(
                name="flowrate_converted_interval_maximum",
                data_class=data.Float3,
                affected_by_pulse_input=True,
            ),
            DatabaseRecordParameter(name="none_data_1", data_class=data.Null4),
            DatabaseRecordParameter(
                name="flowrate_unconverted_interval_average",
                data_class=data.Float3,
                affected_by_pulse_input=True,
            ),
            DatabaseRecordParameter(
                name="flowrate_converted_interval_average",
                data_class=data.Float3,
                affected_by_pulse_input=True,
            ),
            DatabaseRecordParameter(name="start_date", data_class=data.Date),
            DatabaseRecordParameter(name="none_data_2", data_class=data.Null2),
        ]
    }
} 
  • Good to know: There are several different float formats due to memory constraints in the protocol and device. All floats are handled as decimal.Decimal in Python to not have float rounding errors.

Read parameters:

``python

from iflag import CorusClient from iflag.data import CorusString, Index from iflag.parse import IFlagParameter from decimal import Decimal

client = CorusClient.with_tcp_transport(address=("localhost", 4000))

Read single value

client.read_parameters([IFlagParameter(id=0x5e, data_class=CorusString)])

{0x5e: "FL_b0040"}

Read multiple values

client.read_parameters( [ IFlagParameter(id=0x5e, data_class=CorusString), IFlagParameter(id=48, data_class=Index), IFlagParameter(id=49, data_class=Index) ] )

{0x5e: "FL_b0040", 48: Decimal("234567.982"), 49: Decimal("222222.982")}


### Write parameters

```python
from iflag import CorusClient, TcpTransport
from iflag.data import Date
from iflag.parse import IFlagParameter
from datetime import datetime

transport = TcpTransport(address=('localhost', 4000))
client = CorusClient(transport=transport)
client.write_parameters([(IFlagParameter(id=106, data_class=Date), datetime.now())])

Read database

from iflag import CorusClient
from datetime import datetime, timedelta
client = CorusClient.with_tcp_transport(address=('localhost', 4000), database_layout=MY_DATABASE_LAYOUT)
client.read_database(database='interval', start=datetime.now(), stop=(datetime.now() - timedelta(hours=4)))
  • When reading databases you will need to know the input_pulse_weight. If it is not set on the client at initiation or on the read_database call the client will read it from the meter automatically.

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

Added

Changed

Deprecated

Removed

Fixed

Security

[1.0.1] - 2020-10-07

Fixed

  • Index9 was not parsed correctly due to misinterpretation of documentation.

[1.0.0] - 2020-10-07

Changed

  • Since different Corus firmware version have different parameter ids and different data database layouts the library is rewritten to be less opinionated and work with all firmwares. This means the user needs to know what ID represents what data and how it is interpreted and how databases the they will read are structured.

[0.2.0] - 2020-01-14

Removed

  • Removed internal session handling as it was in the way of optimizing running several actions directly after each other. Instead now you need to call client.startup() in the beginning and client.shutdown() when you are done.

[0.1.2] - 2020-01-14

Changed

  • Separated value identification in parsing config for the different databases so that it is possible to know if for example an average value is the monthly or hourly average.

[0.1.1] - 2020-01-08

Fixed

  • Fixed error in setup.py that listed the wrong dependency. (attr instead of attrs)

[0.1.0] - 2020-01-08 [YANKED]

Added

  • Initial implementation of reading and writing data to Corus device.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

iflag-1.0.1.tar.gz (20.8 kB view details)

Uploaded Source

Built Distribution

iflag-1.0.1-py3-none-any.whl (39.4 kB view details)

Uploaded Python 3

File details

Details for the file iflag-1.0.1.tar.gz.

File metadata

  • Download URL: iflag-1.0.1.tar.gz
  • Upload date:
  • Size: 20.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.11.0 pkginfo/1.4.2 requests/2.18.4 setuptools/44.0.0 requests-toolbelt/0.8.0 tqdm/4.23.3 CPython/3.6.4

File hashes

Hashes for iflag-1.0.1.tar.gz
Algorithm Hash digest
SHA256 4c551892d97079d72485932de04746013f916da83d3ce915b7d406e945802081
MD5 8530420f3880b11117709e81e293bd1c
BLAKE2b-256 a01b920b6cb5e9dc19f9a4822c86795725857f5ea5df95a65390e9b708d2f58b

See more details on using hashes here.

File details

Details for the file iflag-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: iflag-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 39.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.11.0 pkginfo/1.4.2 requests/2.18.4 setuptools/44.0.0 requests-toolbelt/0.8.0 tqdm/4.23.3 CPython/3.6.4

File hashes

Hashes for iflag-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c82a00e58d0f95865e2ce1946d41f7973fb6854114119c0a2b4ed84c1b469004
MD5 cf7c20e8fef248cdb3c36c2c8751e212
BLAKE2b-256 523120382bc418ffbd27a00d0290c71562f92ede20bfe531cfa77c4aa75006d3

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page