Jun-25-2018, 01:26 PM
Setting the stage for the questions. I am going to explain a lot here and from now on as I ask different python questions I will just link back to here.
I am trying to write a component for Home Assistant. This is my first python project. I am very versed with .NET especially VB.NET. The module will be called form another python program. It uses websocket to talk to a Almond+ API. Right now I have it boiled down to where a CLI can exercise the functions. One other note, the Almond+ is a device that has been sunset. It main function was a WiFi router. But it also had zwave and zigbee radios. This means it could do home automation. With the Almond+ api you can command devices and receive events when states changes. A command example would to switch a state (turn on a light switch). And a event example would be when someone turn on/off a switch and the A+ api would send an event.
Back ground information that is mostly FYI but I am including it because it might be used as references.
Link to Securifi who made the Almond+ https://www.securifi.com/
Link to Almond+ api https://wiki.securifi.com/index.php/Webs...umentation
Link to Home Assistant https://www.home-assistant.io/
Link to project Github https://github.com/penright/pyalmondplus
The api is mostly be a wrapper to the Almond+. It will also track devices in the HA world is called entities.
I had a successful "hello world" api that connect and received a device list.
The api code is in pyalmondplus.py. So from now on, unless noted, when I refer to the api it is the one I am creating. Then to test the api the user can type in a CLI. That code is in cli.py.
Enough background, if you are being link here from another question, this is all of the background information.
So the bottom, coming from a different language, and from what I have read. I think my issue is (and what I am trying to do) revolves around understanding the "GIL"
and (Parallel vs. Concurrent). I am/was expecting "Parallel" and the examples I been reading are "Concurrent". I played with asycio and threads. I want the almondplus.py class "start()" to "kickoff the self.receive()" and return with the api waiting for the receive.
So I expect or maybe better said, I want the output to be "Start 1", "Start 2", "receive started", "Receiver running"
If I use a self.loop.run_(forever or until) I get the "receive started" but not the "Receiver running", because the loop.run_* is blocking. Without it the receiver is never kicked off. Thanks in advance.
Here is the cli code
I am trying to write a component for Home Assistant. This is my first python project. I am very versed with .NET especially VB.NET. The module will be called form another python program. It uses websocket to talk to a Almond+ API. Right now I have it boiled down to where a CLI can exercise the functions. One other note, the Almond+ is a device that has been sunset. It main function was a WiFi router. But it also had zwave and zigbee radios. This means it could do home automation. With the Almond+ api you can command devices and receive events when states changes. A command example would to switch a state (turn on a light switch). And a event example would be when someone turn on/off a switch and the A+ api would send an event.
Back ground information that is mostly FYI but I am including it because it might be used as references.
Link to Securifi who made the Almond+ https://www.securifi.com/
Link to Almond+ api https://wiki.securifi.com/index.php/Webs...umentation
Link to Home Assistant https://www.home-assistant.io/
Link to project Github https://github.com/penright/pyalmondplus
The api is mostly be a wrapper to the Almond+. It will also track devices in the HA world is called entities.
I had a successful "hello world" api that connect and received a device list.
The api code is in pyalmondplus.py. So from now on, unless noted, when I refer to the api it is the one I am creating. Then to test the api the user can type in a CLI. That code is in cli.py.
Enough background, if you are being link here from another question, this is all of the background information.
So the bottom, coming from a different language, and from what I have read. I think my issue is (and what I am trying to do) revolves around understanding the "GIL"
and (Parallel vs. Concurrent). I am/was expecting "Parallel" and the examples I been reading are "Concurrent". I played with asycio and threads. I want the almondplus.py class "start()" to "kickoff the self.receive()" and return with the api waiting for the receive.So I expect or maybe better said, I want the output to be "Start 1", "Start 2", "receive started", "Receiver running"
If I use a self.loop.run_(forever or until) I get the "receive started" but not the "Receiver running", because the loop.run_* is blocking. Without it the receiver is never kicked off. Thanks in advance.
Here is the cli code
# -*- coding: utf-8 -*-
"""Console script for pyalmondplus."""
import sys
import time
import asyncio
import click
import pyalmondplus.api
@click.command()
@click.option('--url', default='')
def start_api(url):
"""Console script for pyalmondplus."""
print("start_api started")
almond_devices = pyalmondplus.api.PyAlmondPlus(url)
almond_devices.start()
print("Connected to Almond+")
do_commands(url)
return 0
def do_commands(url):
#click.echo("Connecting to " + url)
while True:
time.sleep(3)
while True:
value = click.prompt("What next: ")
print("command is: " + value)
if value == "stop":
break
def main():
print("test")
print("Setting up loop")
loop = asyncio.get_event_loop()
print("Starting loop")
asyncio.get_event_loop().run_until_complete(start_api())
print("loop started")
# #main()
# #sys.exit(main())
print("Finishing")And here is the api (almondplus.py)# -*- coding: utf-8 -*-
import asyncio
import websockets
import json
class PyAlmondPlus:
def __init__(self, api_url, event_callback=None):
self.api_url = api_url
self.ws = None
self.loop = asyncio.get_event_loop()
self.receive_task = None
self.event_callback = event_callback
async def connect(self):
print("connecting")
if self.ws is None:
print("opening socket")
self.ws = await websockets.connect(self.api_url)
print(self.ws)
async def disconnect(self):
pass
async def send(self, message):
pass
async def receive(self):
print("receive started")
if self.ws is None:
await self.connect()
recv_data = await self.ws.recv()
print(recv_data)
await self.receive()
def start(self):
print("Start 1")
asyncio.ensure_future(self.receive(), loop=self.loop)
print("Start 2")
self.loop.run_forever()
print("Receiver running")
def stop(self):
pass
