# -*- coding: utf-8 -*-
from setuptools import setup

package_dir = \
{'': 'src'}

packages = \
['sdm_modbus']

package_data = \
{'': ['*']}

install_requires = \
['pymodbus>=2.4.0,<3.0.0']

setup_kwargs = {
    'name': 'sdm-modbus',
    'version': '0.5.2',
    'description': 'Eastron SDM Modbus parser library',
    'long_description': '# sdm_modbus\n\nsdm_modbus is a python library that collects data from Eastron SDM single- and three-phase kWh meters over Modbus RTU or Modbus TCP.\n\nSupported devices:\n* [Eastron SDM72D-M](https://www.eastroneurope.com/products/view/sdm72modbus)\n* [Eastron SDM120-Modbus](https://www.eastroneurope.com/products/view/sdm120modbus)\n* [Eastron SDM230-Modbus](https://www.eastroneurope.com/products/view/sdm230modbus)\n* [Eastron SDM630-Modbus](https://www.eastroneurope.com/products/view/sdm630modbus)\n* [Garo GNM3D-RS485](https://www.garo.se/en/professional/products/installation-products/din-rail-components/energy-meters/energymeter-3p-modbus-rs485)\n* [ESP2866/32 P1 Modbus](https://github.com/nmakel/esp_p1_modbus)\n\n## Installation\n\nTo install, either clone this project and install using `poetry`:\n\n```poetry install```\n\nor install the package from PyPi:\n\n```pip3 install sdm_modbus```\n\n## Usage\n\nThe script `example-tcp.py` provides a minimal example of connecting to and displaying all input and holding registers on a **SDM120** over **Modbus TCP**. To display values as a JSON object, add `--json`.\n\n```\nusage: example-tcp.py [-h] [--unit UNIT] [--json] host port\n\npositional arguments:\n  host         Modbus TCP address\n  port         Modbus TCP port\n\noptional arguments:\n  -h, --help   show this help message and exit\n  --unit UNIT  Modbus device address\n  --json       Output as JSON\n```\n\nOutput:\n\n```\nSDM120(10.0.0.123:502, connectionType.TCP: timeout=1, retries=3, unit=0x1):\n\nInput Registers:\n    Voltage: 237.00V\n    Current: 8.63A\n    Power (Active): -1919.70W\n    Power (Apparent): 2035.57VA\n    Power (Reactive): -676.70VA\n    Power Factor: -0.94\n    Phase Angle: 0.00°\n    Frequency: 50.00Hz\n    Imported Energy (Active): 1551.37kWh\n    Imported Energy (Active): 1335.69kWh\n    Imported Energy (Reactive): 0.01kVAh\n    Exported Energy (Reactive): 4362.14kVAh\n    Total Demand Power (Active): 1668.02W\n    Maximum Total Demand Power (Active): 3347.26W\n    Import Demand Power (Active): 0.00W\n    Maximum Import Demand Power (Active): 3347.26W\n    Export Demand Power (Active): 1668.02W\n    Maximum Export Demand Power (Active): 2109.45W\n    Total Demand Current: 7.57A\n    Maximum Total Demand Current: 14.97A\n    Total Energy (Active): 2887.07kWh\n    Total Energy (Reactive): 0.00kVAh\n\nHolding Registers:\n    Demand Time: 1s\n    Demand Period: 60s\n    Relay Pulse Width: 60ms\n    Network Parity Stop: N-1\n    Meter ID: 1\n    Baud Rate: 9600\n    P1 Output Mode: Export Energy (Active)\n    Display Scroll Timing: 0s\n    P1 Divisor: 0.001kWh/imp\n    Measurement Mode: 0\n    Pulse/LED Indicator Mode: Import + Export Energy (Active)\n```\n\n### Connecting\n\nIf you wish to use Modbus TCP the following parameters are relevant:\n\n`host = IP or DNS name of your Modbus TCP gateway, required`  \n`port = TCP port of the Modbus TCP gateway, required`  \n`unit = Modbus device address, default=1, optional`\n\nWhile if you are using a Modbus RTU connection you can specify:\n\n`device = path to serial device, e.g. /dev/ttyUSB0, required`  \n`baud = baud rate of your SDM unit, defaults to factory default, optional`  \n`unit = Modbus device address, defaults to 1, optional`\n\nConnecting to the meter:\n\n```\n    >>> import sdm_modbus\n\n    # SDM120 over Modbus TCP\n    >>> device = sdm_modbus.SDM120(host="10.0.0.123", port=502)\n\n    # SDM630 over Modbus RTU\n    >>> device = sdm_modbus.SDM630(device="/dev/ttyUSB0", baud=9600)\n```\n\nTest the connection:\n\n```\n    >>> device.connected()\n    True\n```\n\nPrinting the object yields basic device parameters:\n\n```\n    >>> device\n    SDM120(10.0.0.123:502, connectionType.TCP: timeout=1, retries=3, unit=0x1):\n```\n\n### Connecting to Multiple Devices\n\nRe-using an existing RTU or TCP connection is possible by providing an already connected device as `parent` when creating a new instance. This may be necessary if the Modbus TCP gateway only accepts a limited number of connections, or you wish to address multiple RTU devices on the same bus. For example:\n\n```\n    # Connect to a SDM630 over Modbus TCP\n    >>> device_1 = sdm_modbus.SDM630(host="10.0.0.123", port=502, unit=1)\n\n    # Connect to a SDM630 using the existing connection\n    >>> device_2 = sdm_modbus.SDM630(parent=device_1, unit=2)\n```\n\n### Reading Registers\n\nReading a single input register by name:\n\n```\n    >>> device.read("voltage")\n    236.89999389648438\n```\n\nRead all input registers by passing the `sdm_modbus.registerType.INPUT` enum to `read_all()`. Leave this blank to read both `INPUT` and `HOLDING` registers:\n\n```\n    >>> device.read_all(sdm_modbus.registerType.INPUT)\n    {\n        "voltage": 238.60000610351562,\n        "current": 7.59499979019165,\n        "power_active": -1673.800048828125,\n        "power_apparent": 1797.5904541015625,\n        "power_reactive": -655.4000244140625,\n        "power_factor": -0.9311425685882568,\n        "phase_angle": 0.0,\n        "frequency": 50.0,\n        "import_energy_active": 1556.35595703125,\n        "export_energy_active": 1345.9210205078125,\n        "import_energy_reactive": 0.014999999664723873,\n        "export_energy_reactive": 4376.02001953125,\n        "total_demand_power_active": 1659.360107421875,\n        "maximum_total_demand_power_active": 3347.26318359375,\n        "import_demand_power_active": 0.0,\n        "maximum_import_demand_power_active": 3347.26318359375,\n        "export_demand_power_active": 1659.360107421875,\n        "maximum_export_demand_power_active": 2109.4541015625,\n        "total_demand_current": 7.531858921051025,\n        "maximum_total_demand_current": 14.968546867370605,\n        "total_energy_active": 2902.277099609375,\n        "total_energy_reactive": 4376.03515625\n    }\n\n    >>> device.read_all(sdm_modbus.registerType.HOLDING)\n    {\n        "demand_time": 1,\n        "demand_period": 60,\n        "relay_pulse_width": 60,\n        "network_parity_stop": 0,\n        "meter_id": 1,\n        "baud": 2,\n        "p1_output_mode": 4,\n        "display_scroll_timing": 0,\n        "p1_divisor": 0,\n        "measurement_mode": 0,\n        "indicator_mode": 0\n    }\n```\n\n### Writing Registers\n\nWriting to holding registers is also possible. Setting a new baud rate, for example:\n\n```\n    >>> device.write("baud", 2)\n    WriteMultipleRegisterResponse (28,2)\n```\n\nYou will need to **enable setup mode on your device** by pressing the setup button for 5 seconds, otherwise you will receive a `Exception Response(134, 6, GatewayNoResponse)` or similar.\n\n### Register Details\n\nIf you need more information about a particular register, to look up the units or enumerations, for example:\n\n```\n    >>> device.registers["voltage"]\n        # address, length, type, datatype, valuetype, name, unit, batching\n        (\n            0,\n            2,\n            <registerType.INPUT: 1>,\n            <registerDataType.FLOAT32: 11>,\n            <class \'float\'>,\n            \'Voltage\',\n            \'V\',\n            1\n        )\n\n    >>> device.registers["p1_divisor"]\n        # address, length, type, datatype, valuetype, name, unit, batching\n        (\n            63760,\n            2,\n            <registerType.HOLDING: 2>,\n            <registerDataType.FLOAT32: 11>,\n            <class \'int\'>,\n            \'P1 Divisor\',\n            [\'0.001kWh/imp\', \'0.01kWh/imp\', \'0.1kWh/imp\', \'1kWh/imp\'],\n            2\n        )\n```\n\n## Contributing\n\nContributions are more than welcome, especially testing on supported units, and adding other Eastron SDM units.',
    'author': 'nmakel',
    'author_email': None,
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/nmakel/sdm_modbus',
    'package_dir': package_dir,
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.7,<4.0',
}


setup(**setup_kwargs)
