Metadata-Version: 2.4
Name: openioe
Version: 1.1.3
Summary: Python Library for OpenIoE
Author: OpenIoE contributors
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: paho-mqtt<3,>=2.1

# OpenIoE Python Library

This python sdk for openioe can be used to integrate user python based application with openioe platform.

> 🟩 **Setup** · 🟨 **Configuration** · 🟪 **Device operations** · 🟦 **Reference**

## Table of contents

- [Installation](#installation)
- [Welcome](#welcome)
- [Load your configuration](#load-your-configuration)
- [Read device data](#read-device-data)
- [Write device data](#write-device-data)
- [MQTT publish and subscribe](#mqtt-publish-and-subscribe)
- [Example programs](#example-programs)
  - [Read program](#read-program)
  - [Write program](#write-program)
  - [Publish program](#publish-program)
  - [Subscribe program](#subscribe-program)
  - [Configuration check program](#configuration-check-program)
- [Modules](#modules)
- [Handling errors](#handling-errors)

## Installation

🟩 **Setup**

Install the library and all runtime dependencies, including MQTT support:

```sh
pip install openioe
```

Python 3.10 or newer is required. To update an existing installation:

```sh
python3 -m pip install --upgrade openioe
```

Paho MQTT 2.x (`paho-mqtt>=2.1,<3`) is installed automatically. HTTP operations
use Python's standard library. Build and release tools are development tools and
are installed separately when needed.

## Welcome

Print the SDK welcome message and current package version:

```python
import openioe

openioe.welcome()
```

```text
Welcome to Open IoE Python SDK v1.1.2
```

The version is read from `openioe.__version__`; the greeting updates with the
installed package version. You can also use `from openioe import welcome`.
The function prints the greeting and returns `None`.

## Load your configuration

🟨 **Configuration**

Download accountsecrets.json file from [Accont Setting](https://app.openioe.in/user-management/account-settings)>> Secrets Tab.
Copy accountsecrets.json to `your working folder.`

```python
from openioe import Config
from openioe.devices import Devices

config = Config("accountsecrets.json")
devices = Devices(config=config)
```

You may also use `Config(config_file="accountsecrets.json")`,
`Config.from_json("accountsecrets.json")`, or `Devices(config_file="accountsecrets.json")`.
Relative paths resolve against the current working directory.

A minimal HTTP configuration is:

```json
{
  "base_url": "https://api.openioe.in",
  "api_key": "your-account-api-key",
  "api_version": "v1",
  "timeout": 30,
  "devices": [{
    "idx": 1,
    "device_id": "your-device-id",
    "read_apikey": "your-read-api-key",
    "write_apikey": "your-write-api-key",
    "communication_protocol": "http"
  }]
}
```

`idx` is the integer stored on the device entry, not its list position. Exactly
one entry must match. The library automatically selects `read_apikey` for reads
and `write_apikey` for writes. Keep actual credentials out of version control.

### Provide configuration in Python

Labeled constructor input:

```python
config = Config(
    base_url="https://api.openioe.in",
    api_key="your-account-api-key",
    devices=[{
        "idx": 1,
        "device_id": "your-device-id",
        "read_apikey": "your-read-api-key",
        "write_apikey": "your-write-api-key",
        "communication_protocol": "http",
    }],
)
devices = Devices(config=config)
```

Ordered input uses `base_url`, `api_key`, `api_version`, `timeout`; resource lists
remain keyword arguments:

```python
config = Config("https://api.openioe.in", "your-account-api-key", "v1", 30,
                devices=[{"idx": 1, "device_id": "your-device-id",
                          "read_apikey": "your-read-api-key",
                          "write_apikey": "your-write-api-key"}])
```

`api_version` defaults to `"v1"` and `timeout` to 30 seconds. Do not mix file input
with direct settings. All module constructors accept a shared `Config` instance.

## Read device data

🟪 **HTTP read**

```python
response = devices.readdata(idx=1)
print(response["data"])
```

This POSTs to `/v1/readdata` using the selected device's `device_id` and
`read_apikey`. Omitted `is_bulk` defaults to `False`; omitted timestamps or `None`
are sent as empty strings. Supply a time range when needed:

```python
response = devices.readdata(
    idx=1,
    is_bulk=False,
    from_timestamp="2026-06-02 00:10:04.629315+00",
    to_timestamp="2026-06-02 00:10:04.629315+00",
)
```

The full response dictionary is returned, for example:

```json
{"data": {}, "message": "success"}
```

## Write device data

🟪 **HTTP write**

```python
response = devices.writedata(idx=1, data={"voltage": 230})
print(response)
```

This POSTs to `/v1/writedata`. The request's `device_api_key` is automatically
set to the configured device's **`write_apikey`**. `data` must be a JSON-serializable
dictionary. `data_type` defaults to `"http"` and can be supplied explicitly:

```python
response = devices.writedata(idx=1, data={"voltage": 230}, data_type="http")
```

The full response dictionary is returned. HTTP endpoints use your configured
`base_url` and `api_version`.

## MQTT publish and subscribe

🟪 **MQTT messaging**

MQTT support is included with `pip install openioe`.
Use a device with `communication_protocol: "mqtt"`, `MQTT_CLIENT`,
`MQTT_USERNAME`, `MQTT_PASSWORD`, and a nonempty `MQTT_TOPIC` list. Set the
project's `MQTT_BROKER` and, if needed, `MQTT_PORT`. See the
[full example configuration](examples/config.example.json).

```python
result = devices.publish(idx=1, data={"voltage": 230}, topic="data/monitor", qos=1)
print(result)

messages = devices.subscribe(idx=1, topic="data/control", num_messages=1)
for message in messages:
    print(message["topic"], message["payload"].decode("utf-8"))
```

| Setting       | Behavior                                                                                                                                     |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Topic         | Must match a configured `MQTT_TOPIC`. Omit for publish only if one topic exists; omit for subscribe to receive from all configured topics. |
| Payload       | Publish accepts dict/list (JSON encoded), string, bytes, or bytearray. Subscribe returns raw payload bytes.                                  |
| QoS           | `qos=0` by default; accepts 0, 1, or 2. QoS 0 does not confirm broker delivery.                                                            |
| Retain        | Publish defaults to `retain=False`.                                                                                                        |
| Message count | Subscribe defaults to `num_messages=1`, then disconnects.                                                                                  |
| Client IDs    | Publish uses `{MQTT_CLIENT}_python_pub`; subscribe uses `{MQTT_CLIENT}_python_sub`.                                                      |
| Timeout       | Uses `config.timeout`; subscribe raises `TimeoutError` if the requested batch does not arrive.                                           |
| TLS           | Set `tls=True`; uses PEM `Server_CA` if provided, otherwise system trust.                                                                |

Both methods connect for the operation and disconnect afterward. Subscribe blocks
until its message count is reached or it times out. Publish returns `topic`, `mid`,
`qos`, and `retain`; each received message contains `topic`, `payload`, `qos`, and
`retain`. MQTT authenticates with its username/password rather than HTTP API keys.
Avoid simultaneous publishers for the same device or simultaneous subscribers for
the same device, since each role shares a client ID. Publish and subscribe use
different IDs and can run together.

TLS does not turn on automatically when `Server_CA` exists. The configured port
is always respected; if omitted, the default is 1883 or 8883 with TLS. The example
certificate placeholder must be replaced before use with TLS, or omitted to use
system trust.

## Example programs

🟩 **Run programs from `examples/devices`**

Install with `pip install openioe`. Place your exported configuration in
`examples/devices` with the filename used by these programs, or edit their paths.
The read, write, publish, and subscribe programs select `idx=9`; change this to
your device's configured index. MQTT topics must match your configuration.

Run these commands from the examples directory:

The code below matches the existing example files.

### Read program

Source: [deviceread.py](examples/devices/deviceread.py)

```python
from openioe import Config
from openioe.devices import Devices

# Resolve the example file relative to this script, from any working directory.
devices = Devices(config=Config("account-secrets-venkataswamyr-2026-10-25.json"))
response = devices.readdata(9)
print(response)
```

Run:

```sh
python3 deviceread.py
```

### Write program

Source: [devicewrite.py](examples/devices/devicewrite.py)

```python
from openioe import Config
from openioe.devices import Devices

devices = Devices(config=Config("account-secrets-venkataswamyr-2026-10-25.json"))
response = devices.writedata(idx=9, 
                             data={'2026-10-19T00:36:10.244Z': {'SoC': 94, 'Current': 0.3, 'Voltage': 4.13}}, 
                             data_type="mqtt")
print(response)
```

Run:

```sh
python3 devicewrite.py
```

### Publish program

Source: [devicepublish.py](examples/devices/devicepublish.py)

```python
from openioe import Config
from openioe.devices import Devices

devices = Devices(config=Config("account-secrets-venkataswamyr-2026-10-25.json"))
print(devices.publish(9, {'SoC': 99, 'Current': 0.2, 'Voltage': 4.13}, topic="data/monitor", tls=False))
```

Run:

```sh
python3 devicepublish.py
```

### Subscribe program

Source: [devicesubscribe.py](examples/devices/devicesubscribe.py)

```python
from openioe import Config
from openioe.devices import Devices

devices = Devices(config=Config("account-secrets-venkataswamyr-2026-10-25.json"))
while True:
    for message in devices.subscribe(9, topic="data/monitor", num_messages=1, tls=False):
        print(message['topic'], message['payload'].decode('utf-8', errors='replace'))
```

Run:

```sh
python3 devicesubscribe.py
```

### Configuration check program

Source: [devices1.py](examples/devices/devices1.py)

```python
from pathlib import Path

from openioe import Config
from openioe.devices import Devices

# Resolve the example file relative to this script, from any working directory.
config = Config(Path(__file__).resolve().with_name("account-secrets-venkataswamyr-2026-10-25.json"))
devices = Devices(config=config)
print(devices)
```

Run:

```sh
python3 devices1.py
```

The read, write, publish, and subscribe examples make live network calls.
The write example uses `write_apikey` and sends its timestamp-keyed data through
HTTP `/v1/writedata` with `data_type="mqtt"`. The subscribe example loops until
interrupted with Ctrl+C or until an exception such as `TimeoutError` occurs.
Each subscription call waits for one message using the configured timeout.

Publish uses `{MQTT_CLIENT}_python_pub`; subscribe uses
`{MQTT_CLIENT}_python_sub`. To try both, start the subscriber in one terminal
and the publisher in another. Set `tls=True` and configure the correct broker
port and CA certificate when TLS is required.

`devices1.py` loads configuration relative to its script and constructs the client
without network calls. The other examples use paths relative to the working
directory, which is why the commands above run from `examples/devices`.

## Modules

🟦 **Available modules**

| Module                     | Class              | Current availability                                     |
| -------------------------- | ------------------ | -------------------------------------------------------- |
| `openioe.auth`           | `Auth`           | Configuration entry point for authentication integration |
| `openioe.devices`        | `Devices`        | HTTP read/write and MQTT publish/subscribe               |
| `openioe.dataset`        | `Dataset`        | Configuration entry point for datasets                   |
| `openioe.ai`             | `AI`             | Configuration entry point for AI workflows               |
| `openioe.boards`         | `Boards`         | Configuration entry point for boards                     |
| `openioe.edge`           | `Edge`           | Configuration entry point for edge nodes                 |
| `openioe.digitaltwins`   | `DigitalTwins`   | Configuration entry point for digital twins              |
| `openioe.usermanagement` | `UserManagement` | Configuration entry point for users and roles            |

```python
from openioe.edge import Edge
from openioe.edge.ota import OTA

edge = Edge(config=config)
ota = OTA(config=config)
```

OTA is a nested package entry point; firmware transfer is not implemented.
Indexed AI model and edge firmware objects are preserved in the configuration.
See the [developer reference](ReadmeDev.md) for the complete format and module examples.


