--- /dev/null
+from graphit_pin import PCF8574Output, PCF8574Input, GPIOInputPin
+
+
+async def process_configuration(conf, out_queue):
+
+ def callback_factory(pin_name):
+ settable = pins[pin_name].settable
+
+ def callback(value):
+ out_queue.put_nowait({'event': 'pinstate', 'pin': pin_name,
+ 'settable': settable, 'value': value,
+ 'changed': True})
+ return callback
+ pins = {}
+ 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))
+ return pins
import sys
import json
-import websockets
-from graphit_pin import PCF8574Output, PCF8574Input, GPIOInputPin
+import asyncio
-pins = {}
-out_queue = asyncio.Queue()
+from .config import process_configuration
+from .websocket import setup_websocket
-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 setup():
+ pins = {}
+ out_queue = asyncio.Queue()
+ with open(sys.argv[1]) as json_data:
+ conf = json.load(json_data)
+ pins = await process_configuration(conf, out_queue)
+ await setup_websocket(pins, out_queue)
-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_until_complete(setup())
asyncio.get_event_loop().run_forever()
--- /dev/null
+import functools
+import socket
+import json
+import asyncio
+import websockets
+
+
+async def process_command(command, pins, out_queue):
+ if command['command'] == 'setpin':
+ if command['pin'] in pins and pins[command['pin']].settable:
+ pins[command['pin']].value = command['value']
+ elif command['command'] == 'getpin':
+ if command['pin'] in pins:
+ pin = pins[command['pin']]
+ await 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]
+ await out_queue.put({'event': 'pinstate', 'pin': pin_name,
+ 'settable': pin.settable, 'value': pin.value,
+ 'changed': False})
+
+
+async def command_handler(websocket, path, pins, out_queue):
+ async for message in websocket:
+ command = json.loads(message)
+ await process_command(command, pins, out_queue)
+
+
+async def event_handler(websocket, path):
+ while True:
+ event = await out_queue.get()
+ message = json.dumps(event)
+ await websocket.send(message)
+ out_queue.task_done()
+
+
+async def handler(pins, out_queue, websocket, path):
+ command_task = asyncio.create_task(command_handler(websocket, path,
+ pins, out_queue))
+ event_task = asyncio.create_task(event_handler(websocket, path))
+ done, pending = await asyncio.wait(
+ [command_task, event_task],
+ return_when=asyncio.FIRST_COMPLETED,
+ )
+ for task in pending:
+ task.cancel()
+
+
+def get_ip():
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ try:
+ # doesn't even have to be reachable
+ s.connect(('10.255.255.255', 1))
+ ip = s.getsockname()[0]
+ except Exception:
+ ip = '127.0.0.1'
+ finally:
+ s.close()
+ return ip
+
+
+async def setup_websocket(pins, out_queue):
+ parameterised_handler = functools.partial(handler, pins, out_queue)
+ await websockets.serve(parameterised_handler, get_ip(), 80)
--- /dev/null
+import sys
+import json
+import asyncio
+import websockets
+
+
+async def test_commands(websocket):
+ commands = [{'command': 'getallpins'},
+ {'command': 'setpin', 'pin': 'A2-8', 'value': True},
+ {'command': 'setpin', 'pin': 'A2-8', 'value': True},
+ {'command': 'setpin', 'pin': 'A2-8', 'value': False},
+ {'command': 'getpin', 'pin': 'T2-16'}]
+ for command in commands:
+ message = json.dumps(command)
+ await websocket.send(message)
+ print(f"Sent Command: {message}")
+
+
+async def receive_events(websocket):
+ async for message in websocket:
+ print(f"Recvd. Event: {message}")
+
+
+async def main(hostname):
+ async with websockets.connect(f"ws://{hostname}:80") as websocket:
+ command_task = asyncio.create_task(test_commands(websocket))
+ event_task = asyncio.create_task(receive_events(websocket))
+ done, pending = await asyncio.wait(
+ [command_task, event_task],
+ return_when=asyncio.BOTH_COMPLETED,
+ )
+ for task in pending:
+ task.cancel()
+
+
+if __name__ == '__main__':
+ try:
+ asyncio.get_event_loop().run_until_complete(main(sys.argv[1]))
+ except KeyboardInterrupt:
+ pass