У модулей ввода-вывода MOXA ioLogik серии E1200 сущесвует HTTP RESTful API. Но в официальной документации оно освещается поверхностно. Так что пришлось разбираться методом проб и ошибок.

В статье используются следущющие обозначения:

  • <IP-адрес> – IP-адрес устройства, например 192.168.1.93.
  • <канал X> – номер канала от 0 до 7 для выходов (каналы DIO0...DIO7). Или от 0 до 15 для входов (каналы DI0...DI15).
  • <состояние> – число 0 (состояние OFF) или 1 (состояние ON).

Физически у E1212 всего 15 каналов обозначенных DI0...DI7 и DIO0...DIO7. Каналы DIx – могут быть только входами. Каналы DIOx могут работать как в режиме входа так и в режиме выхода. Режим меняется с помощью перемычки на плате.

Если канал DIO0 настроить в режим входа, то он становится DI8. Соответственно канал DIO7 превращается в DI15, то есть в этом случае в запросах должно фигурировать число 15.

Устройство принимает два типа запросов:

  • Чтение информации. Используется HTTP-метод GET.
  • Запись информации. Используется HTTP-метод PUT.

У устройства есть требование к заголовкам HTTP-запросов.

Для GET-запроса достаточно одного заголовка:

Имя Значение
Accept vdn.dac.v1

Для PUT-запроса – три заголовка:

Имя Значение
Accept vdn.dac.v1
Content-Type application/json
Content-Length Размер тела запроса в байтах

Получение состояния входа

HTTP-метод: GET.

URL:

http://<IP-адрес>/api/slot/0/io/di/<канал X>/diStatus

Ответ приходит в формате JSON:

{
    "slot":0,
    "io": {
        "di": {
            "<канал X>": {
                "diStatus": <состояние>
            }
        }
    }
}

Пример получения состояния канала DI3 с помощью утилиты curl:

curl -X GET \
    -H "Accept: vdn.dac.v1;" \
    "http://192.168.1.93/api/slot/0/io/di/3/diStatus"

Ответ:

{"slot":0,"io":{"di":{"3":{"diStatus":0}}}}

Для получения состояния DI15 нужно послать запрос "/api/slot/0/io/di/15/diStatus". Но если канал не настроен в режим входа, но устройство вернет код 404 (Not Found).

Получение состояния выхода

HTTP-метод: GET.

URL:

http://<IP-адресс>/api/slot/0/io/do/<канал X>/doStatus

Получение состояния выходов аналогично получению состояния входов, только в запросе и в ответе используются слова "do" и "doStatus" вместо "di" и "diStatus".

Получение состояния всех входов и выходов

HTTP-метод: GET.

URL для входов:

http://<IP-адресс>/api/slot/0/io/di

URL для выходов:

http://<IP-адресс>/api/slot/0/io/do

Пример ответа для входов:

{
    "slot": 0,
    "io": {
        "di": [
            {
                "diIndex": 0,
                "diMode": 0,
                "diStatus": 0
            },
            {
                "diIndex": 1,
                "diMode": 0,
                "diStatus": 0
            },
            {
                "diIndex": 2,
                "diMode": 0,
                "diStatus": 0
            },
            {
                "diIndex": 3,
                "diMode": 0,
                "diStatus": 0
            },
            {
                "diIndex": 4,
                "diMode": 0,
                "diStatus": 0
            },
            {
                "diIndex": 5,
                "diMode": 0,
                "diStatus": 0
            },
            {
                "diIndex": 6,
                "diMode": 0,
                "diStatus": 0
            },
            {
                "diIndex": 7,
                "diMode": 0,
                "diStatus": 0
            },
            {
                "diIndex": 15,
                "diMode": 0,
                "diStatus": 0
            }
        ]
    }
}

Где:

  • diIndex – номер канала.
  • diStatus – состояние канала.
  • diMode – режим работы входа. 0 – обычный вход. 1 – счетчик.

В режиме счетчика возвращаются дополнительные поля:

{
    "diIndex": 0,
    "diMode": 1,
    "diCounterValue": 0,
    "diCounterStatus": 0,
    "diCounterReset": 0,
    "diCounterOverflowFlag": 0,
    "diCounterOverflowClear": 0
}

В случае выхода ответ будет аналогичен. Пример для выхода DIO0:

{
    "doIndex": 0,
    "doMode": 0,
    "doStatus": 0
}

Здесь doMode в значении 0 означает обычный выход, а в значении 1 – режим генерации импульсов.

В режиме генерации импульсов возвращаются дополнительные поля:

{
    "doIndex": 0,
    "doMode": 1,
    "doPulseStatus": 0,
    "doPulseCount": 0,
    "doPulseOnWidth": 1,
    "doPulseOffWidth": 1
}

Установка состояния выхода (DIOx)

HTTP-метод: PUT.

URL:

http://<IP-адрес>/api/slot/0/io/do/<канал X>/doStatus

Тело запроса (JSON):

{
    "slot": 0,
    "io": {
        "do": {
            "<канал X>": {
                "doStatus": <состояние>
            }
        }
    }
}

Пример уставновки состояния канала DIO2 в ON с помощью утилиты curl:

curl -X PUT \
    -H "Accept: vdn.dac.v1; Content-Type: application/json;" \
    -d '{"slot": 0, "io": {"do": {"2": {"doStatus": 1}}}}' \
    "http://192.168.1.93/api/slot/0/io/do/2/doStatus"

Номера каналов в URL и теле запроса должны совпадать. Если они будут различаться, то устройство вернет код 400 (Bad Request) и в теле ответа информацию об ошибке в формате JSON:

{
    "error": {
        "message": "A required channel index was not specified in the request body.",
        "code":204
    }
}

В случае успешного выполения запроса, устройство возвращает код 200, без тела.

Установка состояния канала на Python

import requests

headers = {
    'Accept': 'vdn.dac.v1',
}

data = {
    'slot': 0,
    'io': {
        'do': {
            '2': {
                'doStatus': 1
            }
        }
    }
} 

response = requests.put('http://192.168.1.93/api/slot/0/io/do/2/doStatus', headers=headers, json=data)
print(response.status_code)

Заголовки Content-Length и Content-Type добавляются автоматически.

Заключение

Постарался описать суть HTTP API для устройств MOXA. Дальнейшее самостоятельное исследование должно быть проще.

Полный список запросов можно найти в официальной документации.

В статье рассмотрены только самые часто используемые: для чтения входов и записи выходов.