Initial commit
authorBenjamin Braatz <bb@bbraatz.eu>
Tue, 12 Jan 2021 05:58:33 +0000 (06:58 +0100)
committerBenjamin Braatz <bb@bbraatz.eu>
Tue, 12 Jan 2021 05:58:33 +0000 (06:58 +0100)
.gitignore [new file with mode: 0644]
LICENSE [new file with mode: 0644]
README.md [new file with mode: 0644]
conf.json [new file with mode: 0644]
graphit_controlpi/__init__.py [new file with mode: 0644]
graphit_controlpi/main.py [new file with mode: 0644]
setup.py [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..c18dd8d
--- /dev/null
@@ -0,0 +1 @@
+__pycache__/
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..86da0a6
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2020 Graph-IT GmbH
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..0f2de5d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# Main Module for Machine Control Pi
+
diff --git a/conf.json b/conf.json
new file mode 100644 (file)
index 0000000..f60ebe7
--- /dev/null
+++ b/conf.json
@@ -0,0 +1,53 @@
+{ "i/o cards":
+  [ { "name": "A1",
+      "type": "output",
+      "address": 56,
+      "pins":
+      [ [ "A1-1", "T1-1" ], [ "A1-2", "T1-2" ],
+        [ "A1-3", "T1-3" ], [ "A1-4", "T1-4" ],
+        [ "A1-5", "T1-5" ], [ "A1-6", "T1-6" ],
+        [ "A1-7", "T1-7" ], [ "A1-8", "T1-8" ] ] },
+    { "name": "A2",
+      "type": "output",
+      "address": 57,
+      "pins":
+      [ [ "A2-1", "T1-9" ], [ "A2-2", "T1-10" ],
+        [ "A2-3", "T1-11" ], [ "A2-4", "T1-12" ],
+        [ "A2-5", "T1-13" ], [ "A2-6", "T1-14" ],
+        [ "A2-7", "T1-15" ], [ "A2-8", "T1-16" ] ] },
+    { "name": "E1",
+      "type": "input",
+      "address": 32,
+      "interrupt pin": 4,
+      "pins":
+      [ [ "E1-1", "T1-18" ], [ "E1-2", "T1-19" ],
+        [ "E1-3", "T1-20" ], [ "E1-4", "T1-21" ],
+        [ "E1-5", "T1-22" ], [ "E1-6", "T1-23" ],
+        [ "E1-7", "T1-24" ], [ "E1-8", "T1-25" ] ] },
+    { "name": "E2",
+      "type": "input",
+      "address": 33,
+      "interrupt pin": 17,
+      "pins":
+      [ [ "E2-1", "T1-26" ], [ "E2-2", "T1-27" ],
+        [ "E2-3", "T1-28" ], [ "E2-4", "T1-29" ],
+        [ "E2-5", "T1-30" ], [ "E2-6", "T1-31" ],
+        [ "E2-7", "T1-32" ], [ "E2-8", "T1-33" ] ] },
+    { "name": "E3",
+      "type": "input",
+      "address": 34,
+      "interrupt pin": 27,
+      "pins":
+      [ [ "E3-1", "T2-1" ], [ "E3-2", "T2-2" ],
+        [ "E3-3", "T2-3" ], [ "E3-4", "T2-4" ],
+        [ "E3-5", "T2-5" ], [ "E3-6", "T2-6" ],
+        [ "E3-7", "T2-7" ], [ "E3-8", "T2-8" ] ] },
+    { "name": "E4",
+      "type": "input",
+      "address": 35,
+      "interrupt pin": 22,
+      "pins":
+      [ [ "E4-1", "T2-9" ], [ "E4-2", "T2-10" ],
+        [ "E4-3", "T2-11" ], [ "E4-4", "T2-12" ],
+        [ "E4-5", "T2-13" ], [ "E4-6", "T2-14" ],
+        [ "E4-7", "T2-15" ], [ "E4-8", "T2-16" ] ] } ] }
diff --git a/graphit_controlpi/__init__.py b/graphit_controlpi/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/graphit_controlpi/main.py b/graphit_controlpi/main.py
new file mode 100644 (file)
index 0000000..923ea75
--- /dev/null
@@ -0,0 +1,86 @@
+import sys
+import json
+import websockets
+from graphit_pin import PCF8574Output, PCF8574Input, GPIOInputPin
+
+pins = {}
+out_queue = asyncio.Queue()
+
+
+def process_configuration(conf):
+
+    def callback_factory(pin_name):
+        settable = pins[pin_name].settable
+
+        def callback(value):
+            out_queue.put({'event': 'pinstate', 'pin': pin_name,
+                           'settable': settable, 'value': value,
+                           'changed': True})
+        return callback
+
+    if 'i/o cards' in conf:
+        for card_conf in conf['i/o cards']:
+            card = None
+            if card_conf['type'] == 'output':
+                card = PCF8574Output(card_conf['address'])
+            elif card_conf['type'] == 'input':
+                card = PCF8574Input(card_conf['address'],
+                                    GPIOInputPin(card_conf['interrupt pin'],
+                                                 up=True))
+            if card is not None:
+                for i in range(8):
+                    pin = card.getPin(i)
+                    pin_names = card_conf['pins'][i]
+                    for pin_name in pin_names:
+                        pins[pin_name] = pin
+                        pin.on('change', callback_factory(pin_name))
+
+
+async def process_command(command):
+    if command['command'] == 'setpin':
+        if command['pin'] in pins:
+            pins[command['pin']].value = command['value']
+    elif command['command'] == 'getpin':
+        if command['pin'] in pins:
+            pin = pins[command['pin']]
+            out_queue.put({'event': 'pinstate', 'pin': command['pin'],
+                           'settable': pin.settable, 'value': pin.value,
+                           'changed': False})
+    elif command['command'] == 'getallpins':
+        for pin_name in pins:
+            pin = pins[pin_name]
+            out_queue.put({'event': 'pinstate', 'pin': pin_name,
+                           'settable': pin.settable, 'value': pin.value,
+                           'changed': False})
+
+
+async def command_handler(websocket, path):
+    async for message in websocket:
+        command = json.loads(message)
+        await process_command(command)
+
+
+async def event_handler(websocket, path):
+    while True:
+        event = await out_queue.get()
+        message = json.dumps(event)
+        await websocket.send(message)
+
+
+async def handler(websocket, path):
+    command_task = asyncio.ensure_future(command_handler(websocket, path))
+    event_task = asyncio.ensure_future(event_handler(websocket, path))
+    done, pending = await asyncio.wait(
+        [command_task, event_task],
+        return_when=asyncio.FIRST_COMPLETED,
+    )
+    for task in pending:
+        task.cancel()
+
+if __name__ == '__main__':
+    with open(sys.argv[1]) as json_data:
+        conf = json.load(json_data)
+        process_configuration(conf)
+    start_server = websockets.serve(handler, 'localhost', 5678)
+    asyncio.get_event_loop().run_until_complete(start_server)
+    asyncio.get_event_loop().run_forever()
diff --git a/setup.py b/setup.py
new file mode 100644 (file)
index 0000000..cf9e697
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,28 @@
+import setuptools
+
+with open("README.md", "r") as readme_file:
+    long_description = readme_file.read()
+
+setuptools.setup(
+    name="graphit-controlpi",
+    version="0.2.0",
+    author="Graph-IT GmbH",
+    author_email="info@graph-it.com",
+    description="Main Module for Machine Control Pi",
+    long_description=long_description,
+    long_description_content_type="text/markdown",
+    url="http://docs.graph-it.com/graphit/controlpi-py",
+    packages=setuptools.find_packages(),
+    setup_requires=[
+        "wheel"
+    ],
+    install_requires=[
+        "websockets",
+        "graphit-pin @ git+git://git.graph-it.com/graphit/pin-py.git",
+    ],
+    classifiers=[
+        "Programming Language :: Python",
+        "License :: OSI Approved :: MIT License",
+        "Operating System :: OS Independent",
+    ],
+)