dynamically adding a resource to a python coap server with coapthon library

925 views Asked by At

I am trying to build a coap server, in which I can add a new resource without the need to stop the server, recode it and restart .my server is suppossed to host two types of resources, "sensors(Sens-Me)" and "Actuators(Act-Me)" . I want that if I press the A key, a new instance of actuator should be added to the server, likewise If i Press S for Sensor .Below is my code :

from coapthon.resources.resource import Resource
from coapthon.server.coap import CoAP


class Sensor(Resource):

   def __init__(self,name="Sensor",coap_server=None):
    super(Sensor,self).__init__(name,coap_server,visible=True,observable=True,allow_children=True)
    self.payload = "This is a new sensor"
    self.resource_type = "rt1"
    self.content_type = "application/json"
    self.interface_type = "if1"
    self.var = 0

   def render_GET(self,request):
       self.payload = "new sensor value ::{}".format(str(int(self.var+1)))
       self.var +=1
   return self

class Actuator(Resource):
def __init__(self,name="Actuator",coap_server=None):
   super(Actuator,self).__init__(name,coap_server,visible=True,observable=True)
   self.payload="This is an actuator"
   self.resource_type="rt1"
def render_GET(self,request):
   return self

class CoAPServer(CoAP):
  def __init__(self, host, port, multicast=False):
    CoAP.__init__(self,(host,port),multicast)
        self.add_resource('sens-Me/',Sensor())
        self.add_resource('act-Me/',Actuator())
    print "CoAP server started on {}:{}".format(str(host),str(port))
    print self.root.dump()


def main():
  ip = "0.0.0.0"
  port = 5683
  multicast=False
  server = CoAPServer(ip,port,multicast)
  try:
    server.listen(10)
            print "executed after listen"
  except KeyboardInterrupt:
    server.close()

if __name__=="__main__":
 main()
1

There are 1 answers

1
eugene-nikolaev On BEST ANSWER

I am not sure what exactly do you want to do. Is it just to replace a resource on the same route or add a new one?

Replace a resource

It is not possible according to the current coapthon version source:

https://github.com/Tanganelli/CoAPthon/blob/b6983fbf48399bc5687656be55ac5b9cce4f4718/coapthon/server/coap.py#L279

 try:
    res = self.root[actual_path]
 except KeyError:
   res = None
 if res is None:
   if len(paths) != i:
       return False
   resource.path = actual_path
       self.root[actual_path] = resource 

Alternatively, you can solve it in scope of request. Say, have a registry of handlers which are used by resources and can be changed on a user input event. Well, you'll not be able to add new routes.

If you absolutely need that feature, you may request it from a developer or contribute to that project.

Add a new resource

I have extended your snippet a little bit. I have a little experience in Python so I an not sure I've made everything properly, but it works. There is a separate thread polling the user input and adding the same resource. Add the needed code there.

from coapthon.resources.resource import Resource
from coapthon.server.coap import CoAP
from threading import Thread
import sys

class Sensor(Resource):
  def __init__(self,name="Sensor",coap_server=None):
    super(Sensor,self).__init__(name,coap_server,visible=True,observable=True,allow_children=True)
    self.payload = "This is a new sensor"
    self.resource_type = "rt1"
    self.content_type = "application/json"
    self.interface_type = "if1"
    self.var = 0

  def render_GET(self,request):
    self.payload = "new sensor value ::{}".format(str(int(self.var+1)))
    self.var +=1
    return self

class Actuator(Resource):
  def __init__(self,name="Actuator",coap_server=None):
    super(Actuator,self).__init__(name,coap_server,visible=True,observable=True)
    self.payload="This is an actuator"
    self.resource_type="rt1"
  def render_GET(self,request):
    return self

class CoAPServer(CoAP):
  def __init__(self, host, port, multicast=False):
    CoAP.__init__(self,(host,port),multicast)
    self.add_resource('sens-Me/',Sensor())
    self.add_resource('act-Me/',Actuator())
    print "CoAP server started on {}:{}".format(str(host),str(port))
    print self.root.dump()

def pollUserInput(server):
  while 1:
    user_input = raw_input("Some input please: ")
    print user_input
    server.add_resource('sens-Me2/', Sensor())

def main():
  ip = "0.0.0.0"
  port = 5683
  multicast=False

  server = CoAPServer(ip,port,multicast)
  thread = Thread(target = pollUserInput, args=(server,))
  thread.setDaemon(True)
  thread.start()

  try:
    server.listen(10)
    print "executed after listen"
  except KeyboardInterrupt:
    print server.root.dump()
    server.close()
    sys.exit()

if __name__=="__main__":
  main()