mqtt/library.py
changeset 4081 86fbb3991af6
child 4099 97e93962be0c
equal deleted inserted replaced
4080:803d4e64cc68 4081:86fbb3991af6
       
     1 # mqtt/client.py
       
     2 
       
     3 from __future__ import absolute_import
       
     4 
       
     5 import os
       
     6 
       
     7 from POULibrary import POULibrary
       
     8 import util.paths as paths
       
     9 
       
    10 mqtt_python_lib_code = """
       
    11 def MQTT_publish(clientname, topic, payload, QoS = 1, Retained = False):
       
    12     c_function_name = "__mqtt_python_publish_" + clientname
       
    13     c_function = getattr(PLCBinary, c_function_name)
       
    14     c_function.restype = ctypes.c_int # error or 0
       
    15     c_function.argtypes = [
       
    16         ctypes.c_char_p,  # topic
       
    17         ctypes.c_char_p,  # data
       
    18         ctypes.c_uint32,  # datalen
       
    19         ctypes.c_uint8,   # QoS
       
    20         ctypes.c_uint8,   # Retained
       
    21     ]
       
    22     res = c_function(topic, payload, len(payload), QoS, Retained)
       
    23     return res
       
    24 
       
    25 # C per client CallBack type for __mqtt_python_subscribe_{name}
       
    26 c_cb_type = ctypes.CFUNCTYPE(ctypes.c_int,                   # return
       
    27                              ctypes.c_char_p,                # topic
       
    28                              ctypes.POINTER(ctypes.c_char),  # data
       
    29                              ctypes.c_uint32)                # data length
       
    30 
       
    31 # CallBacks management
       
    32 # - each call to MQTT_subscribe registers a callback
       
    33 MQTT_subscribers_cbs = {}
       
    34 
       
    35 # - one callback registered to C side per client
       
    36 MQTT_client_cbs = {}
       
    37 
       
    38 def per_client_cb_factory(client):
       
    39     def per_client_cb(topic, dataptr, datalen):
       
    40         payload = ctypes.string_at(dataptr, datalen)
       
    41         subscriber = MQTT_subscribers_cbs[client].get(topic, None)
       
    42         if subscriber:
       
    43             subscriber(topic, payload)
       
    44             return 0
       
    45         return 1
       
    46     return per_client_cb
       
    47     
       
    48 def MQTT_subscribe(clientname, topic, cb, QoS = 1):
       
    49     global MQTT_client_cbs, MQTT_subscribers_cbs
       
    50     c_function_name = "__mqtt_python_subscribe_" + clientname
       
    51     c_function = getattr(PLCBinary, c_function_name)
       
    52     c_function.restype = ctypes.c_int # error or 0
       
    53     c_function.argtypes = [
       
    54         ctypes.c_char_p,  # topic
       
    55         ctypes.c_uint8]   # QoS
       
    56 
       
    57     MQTT_subscribers_cbs.setdefault(clientname, {})[topic] = cb
       
    58 
       
    59     c_cb = MQTT_client_cbs.get(clientname, None)
       
    60     if c_cb is None:
       
    61         c_cb = c_cb_type(per_client_cb_factory(clientname))
       
    62         MQTT_client_cbs[clientname] = c_cb
       
    63         register_c_function = getattr(PLCBinary, "__mqtt_python_callback_setter_"+clientname )
       
    64         register_c_function.argtypes = [c_cb_type]
       
    65         register_c_function(c_cb)
       
    66 
       
    67     res = c_function(topic, QoS)
       
    68     return res
       
    69 
       
    70 """
       
    71 
       
    72 class MQTTLibrary(POULibrary):
       
    73     
       
    74     def GetLibraryPath(self):
       
    75         return paths.AbsNeighbourFile(__file__, "pous.xml")
       
    76 
       
    77     def Generate_C(self, buildpath, varlist, IECCFLAGS):
       
    78 
       
    79         runtimefile_path = os.path.join(buildpath, "runtime_00_mqtt.py")
       
    80         runtimefile = open(runtimefile_path, 'w')
       
    81         runtimefile.write(mqtt_python_lib_code)
       
    82         runtimefile.close()
       
    83         return ((["mqtt"], [], False), "",
       
    84                 ("runtime_00_mqtt.py", open(runtimefile_path, "rb")))