~martijnbraam/pyatem

ref: 88b359c4b1ad475fb5eeb193e2b17ae181da2b18 pyatem/docs/proxy.rst -rw-r--r-- 5.9 KiB
88b359c4Martijn Braam proxy: mqtt: show writable state in status line 6 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
The proxy server module
=======================

OpenSwitcher provides a proxy server application on top of the ATEM python library. It is designed to easily
interface with one or more ATEM switchers using different protocols that are easier to implement for small
tools. It also aims to provide an ATEM emulation layer in the future so more official and unofficial clients
can be connected to the same hardware than the low connection limit in the hardware itself.

Configuration
-------------

The proxy is configured with a toml configuration file. It defines which hardware it should connect to and which
protocol frontends it should host.

.. code-block:: toml

    [[hardware]]
    id = "mini"
    label = "Atem Mini"
    address = "192.168.2.84"

    [[hardware]]
    id = "mini2"
    label = "Local switcher"
    address = "usb"

    [[frontend]]
    type = "http-api"
    bind = ":8080"
    auth = true
    username = "bob"
    password = "hunter2"
    hardware = "mini,mini2"

    [[frontend]]
    type = "status"
    bind = "127.0.0.1:8082"
    auth = false


For every device there needs to be a `[[hardware]]` section that describes the address to connect to, the internal
id and a display label.

The frontends are described in `[[frontend]]` sections and instead of `id` fields their unique identification is
the `bind` field which sets the port and optionally the IP to bind the protcol to.

Frontend sections
^^^^^^^^^^^^^^^^^

The required keys for the frontend sections are `type`, `bind`, `auth` and `hardware`. If `auth` is enabled then
the `username` and `password` argument are also required.

The `auth` setting enables HTTP basic authentication on the webserver for that specific protocol.

The `hardware` argument is a comma seperated list of hardware ids that are exposed in that specific frontend.

The status frontend
^^^^^^^^^^^^^^^^^^^

The status frontend is a webserver that provides only a single page, a html view of the connected hardware with their
status and a list of the frontend configurations that are enabled.

.. image:: images/proxy-status.png
   :width: 600
   :alt: Screenshot of the webpage generated by the status frontend

.. code-block:: toml

    [[frontend]]
    type = "status"
    bind = "127.0.0.1:8082"
    auth = false
    hardware = "mini"


The HTTP API frontend
^^^^^^^^^^^^^^^^^^^^^

The HTTP API frontend will host an api that allows querying the mixer state as JSON objects. It also allows sending
commands by sending POST requests with either a query string, form-encoded data or json encoded data.

.. code-block:: toml

    [[frontend]]
    type = "http-api"
    bind = "127.0.0.1:8080"
    auth = true
    username = "admin"
    password = "verysecure"
    hardware = "mini,secondswitcher,constellation"


A list of the exposed hardware can be retrieved by sending a GET to /

.. code-block:: shell-session

    $ curl http://localhost:8080/
    {
      "hardware": [
        {
          "id": "mini",
          "status": "connected (ATEM Mini Pro fw 2.30)"
        }
      ]
    }

To get data, send a GET request to `/{hardware}/{field}`. The field in this case is the same as the class names
in the API documentation for fields but with the camelcasing replaced with dashes and the word "Field" removed.

To query for a `ProductNameField` the name would be `product-name`, to get the product name of a device with
the `id` set to `mini` you'd send this request:

.. code-block:: shell-session

    $ curl http://localhost:8080/mini/product-name
    {
      "name": "ATEM Mini Pro"
    }


To send a command to the device the same transform applies, but a POST request is sent instead.

.. code-block:: shell-session

   # Send as query in the url
   $ curl -X POST "http://localhost:8080/mini/program-input?index=0&source=2"

   # Send as application/x-www-form-urlencoded
   $ curl -X POST "http://localhost:8080/mini/program-input" -d "index=0&source=2"

   # Send as json
   $ curl -X POST "http://localhost:8080/mini/program-input" -d '{"index": 0, "source": 2}' -H "Content-Type: application/json"

The TCP frontend
^^^^^^^^^^^^^^^^

The TCP frontend is a custom protocol implementation. The TCP protocol works between the OpenSwitcher proxy and the OpenSwitcher
application and is basically the simplified atem USB protocol tunneled over TCP. It also adds authentication and device
multiplexing. Using this protocol it's possible to control any amount of hardware switcheres over a single TCP port and
have as many clients connected as required.

.. code-block:: toml

    [[frontend]]
    type = "tcp"
    bind = "127.0.0.1:8084"
    auth = true
    username = "admin"
    password = "verysecure"
    hardware = "mini,secondswitcher,constellation"

The pyatem library can connect to this frontend by passing an URL to it:

.. code-block:: url

    tcp://username:password@myproxyserver:8084/secondswitcher

The hardware list is also send to clients in the connection phase. The protocol is designed so clients can show
a popup for authentication when it's enabled and show a device selection popup with the labels set in the hardware
section.

The MQTT frontend
^^^^^^^^^^^^^^^^^

The MQTT frontend will connect to an MQTT server and will sync the hardware state to a topic.


.. code-block:: toml

    [[frontend]]
    type = "mqtt"
    connect = "localhost:1883"
    auth = false
    hardware = "mini"
    topic = "atem/{hardware}/{field}"

The proxy will send a new message the the configured MQTT topic every time the state of one of the connected
switchers changes. There's also a special field generated called `status` that contains the connection state
to the hardware on the other side of the proxy.

The `topic` setting defines which topic the messages will go to. In this path you can use the `hardware` variable which
will be the label of the switcher that generated the event and the `field` variable which will be the name of the
changed field in the same format as the `The HTTP API frontend`_ above.