diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..ed8ebf583f771da9150c35db3955987b7d757904 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__ \ No newline at end of file diff --git a/src/eddie_endpoint.py b/src/eddie_endpoint.py index 74db006ee6ee883065ac2dbbd0bb6c8d058ab416..abc2c6d6f9dc8d099c597b8ae92e184a6bc5d705 100644 --- a/src/eddie_endpoint.py +++ b/src/eddie_endpoint.py @@ -7,6 +7,7 @@ import aiocoap.resource as resource import aiocoap from aiocoap.util import linkformat from aiocoap import error +from remote_resource import RemoteResource import logging @@ -58,7 +59,17 @@ class EddieEndpoint: async def start_server(self): - self.server_context = await aiocoap.Context.create_server_context(self.root, bind=("::", 0)) + port = 8683 + found_available_port = False + while not found_available_port: + try: + self.server_context = await aiocoap.Context.create_server_context(self.root, bind=("::", port)) + found_available_port = True + except OSError as e: + port += 1 + + if found_available_port: print(f"server bound to port: {port}") + else: print("could not start server") async def discover_resource_directory(self): # resource directory is discovered by sending a request to .well-known/core following a heuristic: @@ -114,6 +125,7 @@ class EddieEndpoint: logging.error(e) return None - logging.debug('Get resoruces response: %s\n%r'%(response.code, response.payload)) + logging.debug('Get resources response: %s\n%r'%(response.code, response.payload)) parsed = link_format_from_message(response) - return parsed \ No newline at end of file + remote_resources = [RemoteResource(link, self.server_context) for link in parsed.links] + return remote_resources \ No newline at end of file diff --git a/src/example_endpoint.py b/src/example_lamp_endpoint.py similarity index 87% rename from src/example_endpoint.py rename to src/example_lamp_endpoint.py index d1d752b5261d46ca4aa1925d61deed60a0f8f3cd..1500c8f67a33afcb2ec4c9aba2c00e24700592f4 100644 --- a/src/example_endpoint.py +++ b/src/example_lamp_endpoint.py @@ -7,16 +7,18 @@ import asyncio from eddie_endpoint import EddieEndpoint import aiocoap import logging +from pprint import pprint logging.getLogger().setLevel(logging.DEBUG) -ENDPOINT_NAME = "eddie-python-node" +ENDPOINT_NAME = "eddie-lamp-node" # This is a simple example of a Eddie resource that mocks a lamp # The code to retrieve lamp status and actually turn on and off # the lamp should be in render_{get/put} class EddieLamp(aiocoap.resource.Resource): def __init__(self): + super().__init__() self.lamp_status = False self.rt = "eddie.lamp" @@ -38,7 +40,9 @@ async def main(): await my_endpoint.publish_resources_to_rd() discovered_resources = await my_endpoint.get_resources_from_rd(resource_type="eddie.lamp") - print("Discovered resources: " + str(discovered_resources)) + print("lamps status: ") + for resource in discovered_resources: + print(resource) # Run forever await asyncio.get_running_loop().create_future() diff --git a/src/example_temp_endpoint.py b/src/example_temp_endpoint.py new file mode 100644 index 0000000000000000000000000000000000000000..93cd5e7238b2e68139f51b002d6b156e42668f77 --- /dev/null +++ b/src/example_temp_endpoint.py @@ -0,0 +1,44 @@ +# +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: Huawei Inc. +# +import asyncio +from eddie_endpoint import EddieEndpoint +import aiocoap +import logging +from pprint import pprint + +logging.getLogger().setLevel(logging.DEBUG) + +ENDPOINT_NAME = "eddie-temp-node" + +class EddieTemp(aiocoap.resource.Resource): + def __init__(self): + super().__init__() + self.lamp_status = False + self.rt = "eddie.temp" + self.temperature = b"23" + + async def render_get(self, request): + return aiocoap.Message(payload=self.temperature) + + +async def main(): + + my_endpoint = EddieEndpoint(ENDPOINT_NAME) + my_endpoint.add_resource(['temp1'], EddieTemp()) + await my_endpoint.start_server() + await my_endpoint.publish_resources_to_rd() + + discovered_resources = await my_endpoint.get_resources_from_rd(resource_type="eddie.lamp") + print("discovered resoruces:") + for resource in discovered_resources: + lamp_status = await resource.render_get(aiocoap.Message()) + print(f"{resource} - lamp status: {lamp_status.payload}") + + # Run forever + await asyncio.get_running_loop().create_future() + +if __name__ == "__main__": + asyncio.run(main()) \ No newline at end of file diff --git a/src/remote_resource.py b/src/remote_resource.py new file mode 100644 index 0000000000000000000000000000000000000000..e5da531396f03d6ee6746292da6a3ad6b2137c3c --- /dev/null +++ b/src/remote_resource.py @@ -0,0 +1,55 @@ +import aiocoap +from aiocoap.util import linkformat + +class RemoteResource(aiocoap.resource.Resource): + def __init__(self, resource_link: linkformat.Link, client_context: aiocoap.Context): + self.client_context = client_context + self.resource_link = resource_link + self.rt = resource_link.rt if resource_link.rt else "eddie.remote" + + def __str__(self) -> str: + return str(self.resource_link) + + async def render_get(self, request): + request = aiocoap.Message(code=aiocoap.GET, uri=self.resource_link.href) + + try: + response = await self.client_context.request(request).response + except Exception as e: + print(e) + return None + + return response + + async def render_post(self, request): + request = aiocoap.Message(code=aiocoap.POST, uri=self.resource_link.href) + + try: + response = await self.client_context.request(request).response + except Exception as e: + print(e) + return None + + return response + + async def render_put(self, request): + request = aiocoap.Message(code=aiocoap.PUT, uri=self.resource_link.href) + + try: + response = await self.client_context.request(request).response + except Exception as e: + print(e) + return None + + return response + + async def render_delete(self, request): + request = aiocoap.Message(code=aiocoap.DELETE, uri=self.resource_link.href) + + try: + response = await self.client_context.request(request).response + except Exception as e: + print(e) + return None + + return response \ No newline at end of file