from __future__ import absolute_import
from editors.ConfTreeNodeEditor import ConfTreeNodeEditor
from PLCControler import LOCATION_CONFNODE, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT
from .mqtt_client_gen import MQTTClientPanel, MQTTClientModel, MQTT_IEC_types, authParams
import util.paths as paths
# assumes that "build" directory was created in paho.mqtt.c source directory,
# and cmake build was invoked from this directory
PahoMqttCLibraryPath = paths.ThirdPartyPath("paho.mqtt.c", "build", "src")
frozen_path = paths.ThirdPartyPath("frozen")
paths.ThirdPartyPath("paho.mqtt.c", "build"), # VersionInfo.h
paths.ThirdPartyPath("paho.mqtt.c", "src"),
class MQTTClientEditor(ConfTreeNodeEditor):
(_("MQTT Client"), "CreateMQTTClient_UI"),
(_("Info"), "CreateInfo_UI")]
self.Controler.GetCTRoot().logger.write(msg)
def CreateMQTTClient_UI(self, parent):
self.MQTTClient_UI = MQTTClientPanel(
self.Controler.GetModelData(),
return self.MQTTClient_UI
def CreateInfo_UI(self, parent):
location_str = "_".join(map(str, self.Controler.GetCurrentLocation()))
information=("Connection status GLOBAL VAR is:\n\n\tMQTT_STATUS_"+location_str
self.Info_UI = wx.StaticText(parent, label = information)
self.MQTTClient_UI.RefreshView()
return ConfTreeNodeEditor.RefreshView(self)
class MQTTClient(object):
XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="MQTTClient">
<xsd:element name="AuthType" minOccurs="0">
<xsd:choice minOccurs="0">
<xsd:element name="x509">
<xsd:attribute name="Client_certificate" type="xsd:string" use="optional" default="KeyStore.pem"/>
<xsd:attribute name="Broker_certificate" type="xsd:string" use="optional" default="TrustStore.pem"/>
<xsd:attribute name="Verify_hostname" type="xsd:boolean" use="optional" default="true"/>
<xsd:attribute name="Secret" type="xsd:string" use="optional" default=""/>
<xsd:attribute name="ID" type="xsd:string" use="optional" default=""/>
<xsd:element name="UserPassword">
<xsd:attribute name="User" type="xsd:string" use="optional"/>
<xsd:attribute name="Password" type="xsd:string" use="optional"/>
<xsd:attribute name="Use_MQTT_5" type="xsd:boolean" use="optional" default="true"/>
<xsd:attribute name="Broker_URI" type="xsd:string" use="optional" default="ws://localhost:1883"/>
<xsd:attribute name="Client_ID" type="xsd:string" use="optional" default=""/>
EditorType = MQTTClientEditor
self.modeldata = MQTTClientModel(self.Log, self.CTNMarkModified)
filepath = self.GetFileName()
if os.path.isfile(filepath):
self.modeldata.LoadCSV(filepath)
self.GetCTRoot().logger.write(msg)
datatype_candidates = self.GetCTRoot().GetDataTypes(basetypes=False, only_locatables=True)
return datatype_candidates
def GetDataTypeInfos(self, typename):
return self.GetCTRoot().GetDataTypeInfos(tagname)
attr=self.GetParamsAttributes("MQTTClient."+path)
AuthType = cfg("AuthType")
clientID=cfg("Client_ID"),
UseMQTT5=cfg("Use_MQTT_5"))
paramList = authParams.get(AuthType, None)
for name,default in paramList:
# Translate internal config naming into user config naming
displayed_name = {"KeyStore" : "Client_certificate",
"TrustStore" : "Broker_certificate",
"Verify" : "Verify_hostname"}.get(name, name)
value = cfg("AuthType." + displayed_name)
if value == "" or value is None:
# cryptomaterial is expected to be in project's user provided file directory
# User input may contain char incompatible with C string literal escaping
if name in ["User","Password","TrustStore","KeyStore","Broker_URI","Client_ID"]:
value = re.sub(r'([\"\\])', r'\\\1', value)
return os.path.join(self.CTNPath(), 'selected.csv')
def OnCTNSave(self, from_project_path=None):
self.modeldata.SaveCSV(self.GetFileName())
def CTNGenerate_C(self, buildpath, locations):
current_location = self.GetCurrentLocation()
locstr = "_".join(map(str, current_location))
c_path = os.path.join(buildpath, "mqtt_client__%s.c" % locstr)
#include "iec_types_all.h"
config = self.GetConfig()
c_code += self.modeldata.GenerateC(c_path, locstr, config, self.GetDataTypeInfos)
with open(c_path, 'w') as c_file:
if config["AuthType"] == "x509":
static_lib = "libpaho-mqtt3cs.a"
libs = ['-lssl', '-lcrypto']
static_lib = "libpaho-mqtt3c.a"
LDFLAGS = [' "' + os.path.join(PahoMqttCLibraryPath, static_lib) + '"'] + libs
CFLAGS = ' '.join(['-I"' + path + '"' for path in MqttCIncludePaths])
# TODO: add frozen only if using JSON
frozen_c_path = os.path.join(frozen_path, "frozen.c")
return [(c_path, CFLAGS), (frozen_c_path, CFLAGS)], LDFLAGS, True
def GetVariableLocationTree(self):
current_location = self.GetCurrentLocation()
locstr = "_".join(map(str, current_location))
name = self.BaseParams.getName()
for row in self.modeldata["output"]:
Topic, QoS, _Retained, iec_type, iec_number = row
entries.append((Topic, QoS, iec_type, iec_number, "Q", LOCATION_VAR_OUTPUT))
for row in self.modeldata["input"]:
Topic, QoS, iec_type, iec_number = row
entries.append((Topic, QoS, iec_type, iec_number, "I", LOCATION_VAR_INPUT))
for Topic, QoS, iec_type, iec_number, iec_dir_prefix, loc_type in entries:
_C_type, iec_size_prefix = MQTT_IEC_types.get(iec_type,(None,""))
c_loc_name = "__" + iec_dir_prefix + iec_size_prefix + locstr + "_" + str(iec_number)
"size": {"X":1, "B":8, "W":16, "D":32, "L":64, "":None}[iec_size_prefix],
"location": "%" + iec_dir_prefix + iec_size_prefix + ".".join([str(i) for i in current_location]) + "." + str(iec_number),
"type": LOCATION_CONFNODE,
"location": ".".join([str(i) for i in current_location]) + ".x",
def CTNGlobalInstances(self):
location_str = "_".join(map(str, self.GetCurrentLocation()))
return [("MQTT_STATUS_"+location_str, "INT", ""),