Skip to content

Commit

Permalink
Refactored Comments.
Browse files Browse the repository at this point in the history
  • Loading branch information
mdornaus committed Mar 15, 2023
1 parent de658f3 commit 99e4f39
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 164 deletions.
191 changes: 89 additions & 102 deletions DashboardClient/DashboardClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,33 +35,28 @@ namespace Umati
if(!childNodes.empty()) {
auto child = childNodes.front();
std::shared_ptr<const ModelOpcUa::PlaceholderNode> placeholderNode = std::dynamic_pointer_cast<const ModelOpcUa::PlaceholderNode>(child);
if(placeholderNode == nullptr) {
} else {
auto browseResults = m_pDashboardDataClient->Browse(refreshNodeId, child->ReferenceType, child->SpecifiedTypeNodeId);
//Check if Instances are still in browsresult
std::list<ModelOpcUa::PlaceholderElement> instances = placeholderNode->getInstances();
std::list<ModelOpcUa::PlaceholderElement> missingElements;
for(std::list<ModelOpcUa::PlaceholderElement>::iterator it = instances.begin(); it != instances.end(); it++) {
bool found = false;
ModelOpcUa::NodeId_t nodeId = it->pNode->NodeId;
for(auto &browseResult : browseResults) {
if(browseResult.NodeId == nodeId) {
found = true;
break;
}
}
if(!found) {
LOG(INFO) << "Deleted Node: " << it -> pNode ->NodeId;
missingElements.push_back(*it);
}
if(placeholderNode == nullptr) { return; }
auto browseResults = m_pDashboardDataClient->Browse(refreshNodeId, child->ReferenceType, child->SpecifiedTypeNodeId);
//Check if Instances are still in browsresult
std::list<ModelOpcUa::PlaceholderElement> instances = placeholderNode->getInstances();
std::list<ModelOpcUa::PlaceholderElement> missingElements;
for(auto& el : instances) {
bool found = false;
ModelOpcUa::NodeId_t nodeId = el.pNode->NodeId;
if(std::any_of(browseResults.begin(), browseResults.end(),[nodeId](ModelOpcUa::BrowseResult_t br){ return br.NodeId == nodeId;})) {
found = true;
break;
}
//Remove and Unsubscribe the elements
for(std::list<ModelOpcUa::PlaceholderElement>::iterator it = missingElements.begin(); it != missingElements.end();it++) {
std::shared_ptr<ModelOpcUa::PlaceholderNode> placeholderNodeUnconst = std::const_pointer_cast<ModelOpcUa::PlaceholderNode>(placeholderNode);
placeholderNodeUnconst->removeInstance(*it);
deleteAndUnsubscribeNode(*it);
if(!found) {
missingElements.push_back(el);
}
}
//Remove and Unsubscribe the elements
for(auto& el : missingElements) {
std::shared_ptr<ModelOpcUa::PlaceholderNode> placeholderNodeUnconst = std::const_pointer_cast<ModelOpcUa::PlaceholderNode>(placeholderNode);
placeholderNodeUnconst->removeInstance(el);
deleteAndUnsubscribeNode(el);
}
}
}
//Hotfix clear subscription cache.
Expand All @@ -70,32 +65,28 @@ namespace Umati
void DashboardClient::deleteAndUnsubscribeNode(ModelOpcUa::PlaceholderElement placeHolderElement) {
std::shared_ptr<const ModelOpcUa::SimpleNode> element = placeHolderElement.pNode;
const std::list<std::shared_ptr<const ModelOpcUa::Node>> children = element->ChildNodes;
for(auto it = children.begin(); it != children.end();it++) {
std::shared_ptr<const ModelOpcUa::Node> node = *it;
for(auto& el : children) {
std::shared_ptr<const ModelOpcUa::Node> node = el;
std::shared_ptr<const ModelOpcUa::SimpleNode> simpleNode = std::dynamic_pointer_cast<const ModelOpcUa::SimpleNode>(node);
if(simpleNode != nullptr) {
const ModelOpcUa::SimpleNode simpleN = *simpleNode;
deleteAndUnsubscribeNode(simpleN);
} else {
std::shared_ptr<const ModelOpcUa::PlaceholderNode> placeHolderNode = std::dynamic_pointer_cast<const ModelOpcUa::PlaceholderNode>(node);
if(placeHolderNode != nullptr) {
std::list<ModelOpcUa::PlaceholderElement> instances = placeHolderNode->getInstances();
for(std::list<ModelOpcUa::PlaceholderElement>::iterator it = instances.begin(); it != instances.end(); it++) {
deleteAndUnsubscribeNode(*it);
}

if(placeHolderNode == nullptr) { continue;}
std::list<ModelOpcUa::PlaceholderElement> instances = placeHolderNode->getInstances();
for(auto& el : instances) {
deleteAndUnsubscribeNode(el);
}
}
}
LOG(INFO) << "Erase NodeId :" << element->NodeId;
browsedNodes.erase(element->NodeId);
browsedSimpleNodes.erase(element->NodeId);

}
void DashboardClient::deleteAndUnsubscribeNode(const ModelOpcUa::SimpleNode simpleNode) {
const std::list<std::shared_ptr<const ModelOpcUa::Node>> children = simpleNode.ChildNodes;
for(auto it = children.begin(); it != children.end();it++) {
std::shared_ptr<const ModelOpcUa::Node> node = *it;
for(auto node : children) {
std::shared_ptr<const ModelOpcUa::SimpleNode> simpleNode = std::dynamic_pointer_cast<const ModelOpcUa::SimpleNode>(node);
if(simpleNode != nullptr) {
const ModelOpcUa::SimpleNode simpleN = *simpleNode;
Expand All @@ -111,88 +102,84 @@ namespace Umati
}
}
}
LOG(INFO) << "Erase NodeId :" << simpleNode.NodeId;
browsedNodes.erase(simpleNode.NodeId);
browsedSimpleNodes.erase(simpleNode.NodeId);
}
void DashboardClient::subscribeEvents() {
auto ecbf = [](IDashboardDataClient::StructureChangeEvent sce, void* context) {
DashboardClient* pDashboardClient = static_cast<DashboardClient*> (context);
if(pDashboardClient != nullptr) {
LOG(INFO) << "Event Callback" << pDashboardClient;
if(sce.nodeAdded || sce.referenceAdded) {
pDashboardClient->updateAddDataSet(sce.refreshNode);
pDashboardClient->Publish();
}
if(sce.nodeDeleted || sce.referenceDeleted) {
pDashboardClient->updateDeleteDataSet(sce.refreshNode);
pDashboardClient->Publish();
auto ecbf = [this](IDashboardDataClient::StructureChangeEvent sce) {
if(sce.nodeAdded || sce.referenceAdded) {
std::thread t([this, sce](){
this->updateAddDataSet(sce.refreshNode);
this->Publish();
});
t.detach();
}
if(sce.nodeDeleted || sce.referenceDeleted) {
std::thread t([this, sce](){
this -> updateDeleteDataSet(sce.refreshNode);
if(sce.nodeDeleted == true) {
auto search = browsedSimpleNodes.find(sce.refreshNode);
if(search != browsedSimpleNodes.end()) {
std::shared_ptr<const ModelOpcUa::SimpleNode> simpleNode = search->second;
this->deleteAndUnsubscribeNode(*simpleNode);
}
}
this -> Publish();
});
t.detach();
}
};
m_pDashboardDataClient->SubscribeEvent(ecbf, this);
m_pDashboardDataClient->SubscribeEvent(ecbf);
}
void DashboardClient::updateAddDataSet(ModelOpcUa::NodeId_t refreshNodeId) {
LOG(INFO) << "Update Add DataSet";
if(!m_dataSets.empty()) {
std::shared_ptr<Umati::Dashboard::DashboardClient::DataSetStorage_t> dataSet = m_dataSets.front();
auto search = browsedSimpleNodes.find(refreshNodeId);
if( search != browsedSimpleNodes.end()) {
std::shared_ptr<const ModelOpcUa::SimpleNode> simpleNode = search->second;
auto childNodes = simpleNode->ChildNodes;
if(!childNodes.empty()) {
auto child = childNodes.front();
std::shared_ptr<const ModelOpcUa::PlaceholderNode> placeholderNode = std::dynamic_pointer_cast<const ModelOpcUa::PlaceholderNode>(child);
if(placeholderNode == nullptr) {
} else {
LOG(INFO) << "Start Browsing Jobs";
auto browseResults = m_pDashboardDataClient->Browse(refreshNodeId, child->ReferenceType,
child->SpecifiedTypeNodeId);
LOG(INFO) << "End Browsing Jobs";
for (auto &browseResult : browseResults) {
if (browseResult.TypeDefinition.Id == NodeId_BaseObjectType.Id) {
auto ifs = m_pDashboardDataClient->Browse(browseResult.NodeId,
Dashboard::IDashboardDataClient::BrowseContext_t::HasInterface());
browseResult.TypeDefinition = ifs.front().NodeId;
LOG(INFO) << "Updated TypeDefinition of " << browseResult.BrowseName.Name << " to " << browseResult.TypeDefinition
<< " because the node implements an interface";
}

auto possibleType = m_pTypeReader->m_typeMap->find(browseResult.TypeDefinition); // use subtype
if (possibleType != m_pTypeReader->m_typeMap->end())
{
if(browsedNodes.find(browseResult.NodeId) == browsedNodes.end()) {
LOG(INFO) << "Added Job:" << browseResult.NodeId;
//std::lock_guard<std::recursive_mutex> l(*(m_pDashboardDataClient->getClientMutex()));
auto sharedPossibleType = possibleType->second;
ModelOpcUa::PlaceholderElement plElement;
plElement.BrowseName = browseResult.BrowseName;
plElement.pNode = TransformToNodeIds(browseResult.NodeId, sharedPossibleType);
plElement.TypeDefinition = browseResult.TypeDefinition;
//Const cast
std::shared_ptr<ModelOpcUa::PlaceholderNode> placeholderNodeUnconst = std::const_pointer_cast<ModelOpcUa::PlaceholderNode>(placeholderNode);
placeholderNodeUnconst->addInstance(plElement);
LOG(INFO) << "Start Subscription";
subscribeValues(plElement.pNode, dataSet->values, dataSet->values_mutex);
//std::lock_guard<std::recursive_mutex> l(m_dataSetMutex);
LOG(INFO) << "End Subcription";
}
else {
LOG(INFO) << "Allready found Job";
}
}
if(m_dataSets.empty()) {
return;
}
std::shared_ptr<Umati::Dashboard::DashboardClient::DataSetStorage_t> dataSet = m_dataSets.front();
auto search = browsedSimpleNodes.find(refreshNodeId);
if(search == browsedSimpleNodes.end()) {
return;
}
std::shared_ptr<const ModelOpcUa::SimpleNode> simpleNode = search->second;
auto childNodes = simpleNode->ChildNodes;
if(!childNodes.empty()) {
auto child = childNodes.front();
std::shared_ptr<const ModelOpcUa::PlaceholderNode> placeholderNode = std::dynamic_pointer_cast<const ModelOpcUa::PlaceholderNode>(child);
if(placeholderNode == nullptr) {
} else {
auto browseResults = m_pDashboardDataClient->Browse(refreshNodeId, child->ReferenceType,
child->SpecifiedTypeNodeId);
for (auto &browseResult : browseResults) {
if (browseResult.TypeDefinition.Id == NodeId_BaseObjectType.Id) {
auto ifs = m_pDashboardDataClient->Browse(browseResult.NodeId,
Dashboard::IDashboardDataClient::BrowseContext_t::HasInterface());
browseResult.TypeDefinition = ifs.front().NodeId;
LOG(INFO) << "Updated TypeDefinition of " << browseResult.BrowseName.Name << " to " << browseResult.TypeDefinition
<< " because the node implements an interface";
}

auto possibleType = m_pTypeReader->m_typeMap->find(browseResult.TypeDefinition); // use subtype
if (possibleType != m_pTypeReader->m_typeMap->end())
{
if(browsedNodes.find(browseResult.NodeId) == browsedNodes.end()) {
auto sharedPossibleType = possibleType->second;
ModelOpcUa::PlaceholderElement plElement;
plElement.BrowseName = browseResult.BrowseName;
plElement.pNode = TransformToNodeIds(browseResult.NodeId, sharedPossibleType);
plElement.TypeDefinition = browseResult.TypeDefinition;
//Const cast
std::shared_ptr<ModelOpcUa::PlaceholderNode> placeholderNodeUnconst = std::const_pointer_cast<ModelOpcUa::PlaceholderNode>(placeholderNode);
placeholderNodeUnconst->addInstance(plElement);
subscribeValues(plElement.pNode, dataSet->values, dataSet->values_mutex);
}
}
}
}
}
}
bool DashboardClient::containsNodeId(ModelOpcUa::NodeId_t nodeId) {
if(browsedNodes.find(nodeId) != browsedNodes.end()) {
return true;
} else {
return false;
}
return (browsedNodes.find(nodeId) != browsedNodes.end());
}


Expand Down Expand Up @@ -553,7 +540,7 @@ namespace Umati
std::map<std::shared_ptr<const ModelOpcUa::Node>, nlohmann::json> &valueMap,
std::mutex &valueMap_mutex)
{
// LOG(INFO) << "subscribeValues " << pNode->NodeId.Uri << ";" << pNode->NodeId.Id;
//LOG(INFO) << "subscribeValues " << pNode->NodeId.Uri << ";" << pNode->NodeId.Id;

// Only Mandatory/Optional variables
if (isMandatoryOrOptionalVariable(pNode))
Expand Down Expand Up @@ -655,7 +642,7 @@ namespace Umati
{
for(auto value : m_subscribedValues){
if(value && value.get()->getNodeId() == pNode.get()->NodeId) {
LOG(INFO) << "Allready Subscribed" << value.get()->getNodeId();
//LOG(INFO) << "Allready Subscribed" << value.get()->getNodeId();
return;
}
}
Expand Down
2 changes: 1 addition & 1 deletion DashboardClient/DashboardClient.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ namespace Umati {
bool containsNodeId(ModelOpcUa::NodeId_t nodeId);
void updateAddDataSet(ModelOpcUa::NodeId_t nodeId);
void updateDeleteDataSet(ModelOpcUa::NodeId_t nodeId);
void deleteAndUnsubscribeNode(const ModelOpcUa::SimpleNode nodeId);


protected:
Expand Down Expand Up @@ -142,7 +143,6 @@ namespace Umati {
const std::shared_ptr<ModelOpcUa::StructureNode> &pChild) const;

void deleteAndUnsubscribeNode(ModelOpcUa::PlaceholderElement placeHolderElement);
void deleteAndUnsubscribeNode(const ModelOpcUa::SimpleNode nodeId);
};
}
}
23 changes: 13 additions & 10 deletions DashboardClient/IDashboardDataClient.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@

#pragma once

#include <open62541/client_highlevel.h>
#include <nlohmann/json.hpp>
#include <ModelOpcUa/ModelDefinition.hpp>
#include <functional>
#include <mutex>
#include "NodeIdsWellKnown.hpp"

namespace Umati
Expand Down Expand Up @@ -42,7 +40,7 @@ namespace Umati
* This callback is triggered if a the data of an item changes.
*/
typedef std::function<void(nlohmann::json value)> newValueCallbackFunction_t;
typedef std::function<void(StructureChangeEvent sce, void* context)> eventCallbackFunction_t;
typedef std::function<void(StructureChangeEvent sce)> eventCallbackFunction_t;

virtual ~IDashboardDataClient() = default;

Expand Down Expand Up @@ -232,8 +230,17 @@ namespace Umati

class EventSubscriptionHandle {
public:
EventSubscriptionHandle(){};
EventSubscriptionHandle(int32_t clientHandle, int32_t subscriptionId) : m_clientHandle(clientHandle), m_subscriptionId(subscriptionId){};
~EventSubscriptionHandle(){};
void unsubscribe() { m_unsubscribed = true; }
bool isUnsubscribed() {return m_unsubscribed;}
int32_t getClientHandle() { return m_clientHandle;}
int32_t getSubscriptionId() { return m_subscriptionId;}

private:
bool m_unsubscribed = false;
int32_t m_clientHandle;
int32_t m_subscriptionId;
};

virtual std::string readNodeBrowseName(const ModelOpcUa::NodeId_t &nodeId) = 0;
Expand All @@ -244,8 +251,8 @@ namespace Umati
virtual std::shared_ptr<ValueSubscriptionHandle> Subscribe(ModelOpcUa::NodeId_t nodeId, newValueCallbackFunction_t callback) = 0;
virtual void Unsubscribe(std::vector<int32_t> monItemIds, std::vector<int32_t> clientHandles) = 0;

virtual std::shared_ptr<EventSubscriptionHandle> SubscribeEvent(eventCallbackFunction_t ecbf, void* context) = 0;
virtual void UnsubscribeEvent() = 0;
virtual std::shared_ptr<EventSubscriptionHandle> SubscribeEvent(eventCallbackFunction_t ecbf) = 0;
virtual void UnsubscribeEvent(std::shared_ptr<Dashboard::IDashboardDataClient::EventSubscriptionHandle> eventSubscriptionHandle) = 0;

virtual std::vector<nlohmann::json> ReadeNodeValues(std::list<ModelOpcUa::NodeId_t> nodeIds) = 0;

Expand All @@ -254,10 +261,6 @@ namespace Umati
/// Verify that the connection and session are ok
virtual bool VerifyConnection() = 0;

virtual std::shared_ptr<UA_Client> getUaClient() = 0;

virtual std::recursive_mutex* getClientMutex() = 0;

};
} // namespace Dashboard
} // namespace Umati
1 change: 0 additions & 1 deletion DashboardOpcUaClient.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ class DashboardOpcUaClient {
void addSubscriptionToModelChangeEvent();
void StartMachineObserver();
void Iterate();
std::map<uint, std::string> m_namespaces;

protected:
std::function<void()> m_issueReset;
Expand Down
4 changes: 2 additions & 2 deletions MachineObserver/DashboardMachineObserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace Umati

void DashboardMachineObserver::PublishAll()
{
LOG(INFO) << "Publish";
LOG(TRACE) << "Publish";
{
std::unique_lock<decltype(m_dashboardClients_mutex)> ul(m_dashboardClients_mutex);
for (const auto &pDashClient : m_dashboardClients)
Expand Down Expand Up @@ -71,7 +71,7 @@ namespace Umati
int cnt = 0;
while (this->m_running)
{
if ((cnt % 100) == 0 || cnt == 0)
if ((cnt % 100) == 0)
{
this->UpdateMachines();
}
Expand Down
9 changes: 3 additions & 6 deletions ModelOpcUa/src/ModelOpcUa/ModelInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,9 @@ namespace ModelOpcUa {
return this->Instances;
}
void PlaceholderNode::removeInstance(const PlaceholderElement &instance) {
for(std::list<PlaceholderElement>::iterator it = this->Instances.begin(); it != this->Instances.end(); it++ ) {
if(it->pNode->NodeId == instance.pNode->NodeId) {
this->Instances.erase(it);
break;
}
}
Instances.remove_if([instance](PlaceholderElement const placeholderElement) {
return placeholderElement.pNode->NodeId == instance.pNode->NodeId;
});
}

Node::Node(const NodeDefinition &nodeDefinition, std::list<std::shared_ptr<const Node>> childNodes)
Expand Down
Loading

0 comments on commit 99e4f39

Please sign in to comment.