Skip to content
This repository was archived by the owner on Jul 18, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,10 @@ Configuration Parameters

*Default*: 1

* `EnableSourceDeviceModels` -

*Default*: false

#### Configuration Pameters for TLS (https) Support ####

The following parameters must be present to enable https requests. If there is no password on the certificate, `TlsCertificatePassword` may be omitted.
Expand Down
6 changes: 1 addition & 5 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ configuration:
#C:\ - x86

cache:
- c:\.conan2\ -> **\conanfile.py
- c:\conan2\ -> **\conanfile.py
- C:\Users\appveyor\.conan2 -> **\conanfile.py
- /home/appveyor/.conan2 -> **/conanfile.py
- /Users/appveyor/.conan2 -> **/conanfile.py

Expand All @@ -43,10 +42,7 @@ before_build:
- cmd: |-
set PATH=C:\Python39-x64\;C:\Python39-x64\Scripts;C:\Ruby30\bin;%PATH%
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
if not exist C:\conan mkdir C:\conan
if %SHARED%==True (set CONAN_PROFILE=conan/profiles/vs64shared) else (set CONAN_PROFILE=conan/profiles/vs64)
set CONAN_USER_HOME=C:\conan
rem set CPACK=True
pip install conan
conan profile detect -f

Expand Down
19 changes: 19 additions & 0 deletions demo/agent/Devices.xml
Original file line number Diff line number Diff line change
Expand Up @@ -897,9 +897,28 @@
<Maximum>7000</Maximum>
<Minimum>1</Minimum>
</Specification>
<ProcessSpecification id="proc" type="TEMPERATURE" units="CELSIUS"/>
</Specifications>
</Configuration>
<DataItems>
<DataItem id="tempspec" type="SPECIFICATION_LIMIT" category="EVENT" name="templimit" representation="DATA_SET">
<Definition>
<EntryDefinitions>
<EntryDefinition key="UPPER_LIMIT" type="TEMPERATURE" units="CELSIUS"/>
<EntryDefinition key="NOMINAL" type="TEMPERATURE" units="CELSIUS"/>
<EntryDefinition key="LOWER_LIMIT" type="TEMPERATURE" units="CELSIUS"/>
</EntryDefinitions>
</Definition>
<Relationships>
<SpecificationRelationship type="LIMIT" idRef="proc"/>
<DataItemRelationship type="OBSERVATION" idRef="temp"/>
</Relationships>
</DataItem>
<DataItem id="temp" type="TEMPERATURE" category="SAMPLE">
<Relationships>
<DataItemRelationship type="LIMIT" idRef="tempspec"/>
</Relationships>
</DataItem>
<DataItem type="POSITION" subType="ACTUAL" id="Zabs" category="SAMPLE" units="MILLIMETER" coordinateSystemIdRef="machcoord"/>
<DataItem type="POSITION" subType="ACTUAL" id="Zpos" category="SAMPLE" units="MILLIMETER" coordinateSystemIdRef="workcoord"/>
<DataItem type="POSITION" id="Ztravel" category="CONDITION"/>
Expand Down
36 changes: 28 additions & 8 deletions src/mtconnect/agent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,29 @@ namespace mtconnect {
}
}

void Agent::loadDevice(const string &deviceXml, const optional<string> source)
void Agent::loadDeviceXml(const string &deviceXml, const optional<string> source)
{
try
{
auto printer = dynamic_cast<printer::XmlPrinter *>(m_printers["xml"].get());
auto device = m_xmlParser->parseDevice(deviceXml, printer);
loadDevice(device, source);
}
catch (runtime_error &e)
{
LOG(error) << "Error loading device: " << deviceXml;
LOG(error) << "Error detail: " << e.what();
cerr << e.what() << endl;
}
catch (exception &f)
{
LOG(error) << "Error loading device: " << deviceXml;
LOG(error) << "Error detail: " << f.what();
cerr << f.what() << endl;
}
}

void Agent::loadDevice(DevicePtr device, const optional<string> source)
{
if (!IsOptionSet(m_options, config::EnableSourceDeviceModels))
{
Expand All @@ -400,9 +422,6 @@ namespace mtconnect {
m_context.pause([=](config::AsyncContext &context) {
try
{
auto printer = dynamic_cast<printer::XmlPrinter *>(m_printers["xml"].get());
auto device = m_xmlParser->parseDevice(deviceXml, printer);

if (device)
{
bool changed = receiveDevice(device, true);
Expand All @@ -421,18 +440,19 @@ namespace mtconnect {
}
else
{
LOG(error) << "Cannot parse device xml: " << deviceXml;
LOG(error) << "Cannot parse device xml: " << *device->getComponentName() << " with uuid "
<< *device->getUuid();
}
}
catch (runtime_error &e)
{
LOG(error) << "Error loading device: " + deviceXml;
LOG(error) << "Error loading device: " << *device->getComponentName();
LOG(error) << "Error detail: " << e.what();
cerr << e.what() << endl;
}
catch (exception &f)
{
LOG(error) << "Error loading device: " + deviceXml;
LOG(error) << "Error loading device: " << *device->getComponentName();
LOG(error) << "Error detail: " << f.what();
cerr << f.what() << endl;
}
Expand Down Expand Up @@ -1426,7 +1446,7 @@ namespace mtconnect {

if (command == "devicemodel")
{
loadDevice(value, source);
loadDeviceXml(value, source);
}
else if (device)
{
Expand Down
11 changes: 8 additions & 3 deletions src/mtconnect/agent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,11 +271,16 @@ namespace mtconnect {
/// @return true if successful
bool reloadDevices(const std::string &deviceFile);

/// @brief receive a single device from a source
/// @param[in] deviceXml the device xml as a string
/// @param[in] source the source loading the device
void loadDevice(DevicePtr device, const std::optional<std::string> source = std::nullopt);

/// @brief receive and parse a single device from a source
/// @param[in] deviceXml the device xml as a string
/// @param[in] source the source loading the device
void loadDevice(const std::string &deviceXml,
const std::optional<std::string> source = std::nullopt);
void loadDeviceXml(const std::string &deviceXml,
const std::optional<std::string> source = std::nullopt);

/// @name Message when source has connected and disconnected
///@{
Expand Down Expand Up @@ -574,7 +579,7 @@ namespace mtconnect {
void deliverConnectStatus(entity::EntityPtr, const StringList &devices,
bool autoAvailable) override;
void deliverCommand(entity::EntityPtr) override;
void deliverDevice(DevicePtr device) override { m_agent->receiveDevice(device); }
void deliverDevice(DevicePtr device) override { m_agent->loadDevice(device); }

void sourceFailed(const std::string &identity) override { m_agent->sourceFailed(identity); }

Expand Down
9 changes: 8 additions & 1 deletion src/mtconnect/configuration/agent_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,14 @@ namespace mtconnect::configuration {

GetOptions(block.second, adapterOptions, options);
AddOptions(block.second, adapterOptions,
{{configuration::Url, string()}, {configuration::Device, string()}});
{{configuration::Url, string()},
{configuration::Device, string()},
{configuration::UUID, string()},
{configuration::Uuid, string()}});

if (HasOption(adapterOptions, configuration::Uuid) &&
!HasOption(adapterOptions, configuration::UUID))
adapterOptions[configuration::UUID] = adapterOptions[configuration::Uuid];

auto qname = entity::QName(block.first);
auto [factory, name] = qname.getPair();
Expand Down
1 change: 1 addition & 0 deletions src/mtconnect/configuration/config_options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ namespace mtconnect {
DECLARE_CONFIGURATION(SuppressIPAddress);
DECLARE_CONFIGURATION(Topics);
DECLARE_CONFIGURATION(UUID);
DECLARE_CONFIGURATION(Uuid);
DECLARE_CONFIGURATION(UpcaseDataItemValue);
DECLARE_CONFIGURATION(Url);
DECLARE_CONFIGURATION(UsePolling);
Expand Down
2 changes: 1 addition & 1 deletion src/mtconnect/configuration/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

#include "mtconnect/utilities.hpp"

//#define BOOST_SPIRIT_DEBUG 1
// #define BOOST_SPIRIT_DEBUG 1
#ifdef BOOST_SPIRIT_DEBUG
namespace std {
static ostream &operator<<(ostream &s, const boost::property_tree::ptree &t);
Expand Down
2 changes: 1 addition & 1 deletion src/mtconnect/device_model/component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ namespace mtconnect {
: Entity(name, props)
{
m_id = get<string>("id");
m_name = maybeGet<string>("name");
m_componentName = maybeGet<string>("name");
m_uuid = maybeGet<string>("uuid");
}

Expand Down
37 changes: 20 additions & 17 deletions src/mtconnect/device_model/component.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ namespace mtconnect {
const auto &getId() const { return m_id; }
/// @brief get the name property of the component
/// @return name if it exists
const auto &getComponentName() const { return m_name; }
const auto &getComponentName() const { return m_componentName; }
/// @brief get the component uuid
/// @return uuid if it exists
const auto &getUuid() const { return m_uuid; }
Expand All @@ -94,9 +94,9 @@ namespace mtconnect {
{
auto *self = const_cast<Component *>(this);
self->m_topicName.emplace(getName());
if (m_name)
if (m_componentName)
{
self->m_topicName->append("[").append(*m_name).append("]");
self->m_topicName->append("[").append(*m_componentName).append("]");
}
}
return *m_topicName;
Expand Down Expand Up @@ -161,9 +161,19 @@ namespace mtconnect {
/// @param name name property
void setComponentName(const std::string &name)
{
m_name = name;
m_componentName = name;
setProperty("name", name);
}
/// @brief set the compoent name property, not the compoent type
/// @param name name property
void setComponentName(const std::optional<std::string> &name)
{
m_componentName = name;
if (name)
setProperty("name", *name);
else
m_properties.erase("name");
}

/// @brief get the device (top level component)
/// @return shared pointer to the device
Expand Down Expand Up @@ -272,22 +282,15 @@ namespace mtconnect {
void setDevice(DevicePtr device) { m_device = device; }

protected:
// Unique ID for each component
std::string m_id;

// Name for itself
std::optional<std::string> m_name;

// Universal unique identifier
std::optional<std::string> m_uuid;
std::string m_id; //< Unique ID for each component
std::optional<std::string> m_componentName; //< Name property for the component
std::optional<std::string> m_uuid; //< Universal unique identifier

// Component relationships
// Pointer to the parent component
std::weak_ptr<Component> m_parent;
std::weak_ptr<Device> m_device;

// Topic
std::optional<std::string> m_topicName;
std::weak_ptr<Component> m_parent; //< Pointer to the parent component
std::weak_ptr<Device> m_device; //< Pointer to the device related to the component
std::optional<std::string> m_topicName; //< The cached topic name
};

/// @brief Comparison lambda to sort components
Expand Down
2 changes: 1 addition & 1 deletion src/mtconnect/entity/data_set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#include "mtconnect/utilities.hpp"

//#define BOOST_SPIRIT_DEBUG 1
// #define BOOST_SPIRIT_DEBUG 1

#include <ostream>

Expand Down
13 changes: 13 additions & 0 deletions src/mtconnect/pipeline/deliver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,19 @@ namespace mtconnect {
return entity;
}

EntityPtr DeliverDevice::operator()(entity::EntityPtr &&entity)
{
auto d = std::dynamic_pointer_cast<device_model::Device>(entity);
if (!d)
{
throw EntityError("Unexpected entity type, cannot convert to asset in DeliverAsset");
}

m_contract->deliverDevice(d);

return entity;
}

entity::EntityPtr DeliverConnectionStatus::operator()(entity::EntityPtr &&entity)
{
m_contract->deliverConnectStatus(entity, m_devices, m_autoAvailable);
Expand Down
17 changes: 17 additions & 0 deletions src/mtconnect/pipeline/deliver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include "mtconnect/asset/asset.hpp"
#include "mtconnect/config.hpp"
#include "mtconnect/device_model/device.hpp"
#include "mtconnect/observation/observation.hpp"
#include "transform.hpp"

Expand Down Expand Up @@ -153,6 +154,22 @@ namespace mtconnect::pipeline {
entity::EntityPtr operator()(entity::EntityPtr &&entity) override;
};

/// @brief A transform to deliver a device
class AGENT_LIB_API DeliverDevice : public Transform
{
public:
using Deliver = std::function<void(asset::AssetPtr)>;
DeliverDevice(PipelineContextPtr context)
: Transform("DeliverDevice"), m_contract(context->m_contract.get())
{
m_guard = TypeGuard<device_model::Device>(RUN);
}
entity::EntityPtr operator()(entity::EntityPtr &&entity) override;

protected:
PipelineContract *m_contract;
};

/// @brief deliver the connection status of an adapter
class AGENT_LIB_API DeliverConnectionStatus : public Transform
{
Expand Down
10 changes: 5 additions & 5 deletions src/mtconnect/pipeline/guard.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ namespace mtconnect {
{
public:
/// @brief Construct a GuardCls
/// @param match the match to return if matched
GuardCls(GuardAction match) : m_match(match) {}
/// @param match the action if matched
GuardCls(GuardAction action) : m_action(action) {}
GuardCls(const GuardCls &) = default;

GuardAction operator()(const entity::Entity *entity) { return m_match; }
GuardAction operator()(const entity::Entity *entity) { return m_action; }

/// @brief set the alternative guard
/// @param alt alternative
Expand All @@ -57,7 +57,7 @@ namespace mtconnect {
GuardAction check(bool matched, const entity::Entity *entity)
{
if (matched)
return m_match;
return m_action;
else if (m_alternative)
return m_alternative(entity);
else
Expand All @@ -83,7 +83,7 @@ namespace mtconnect {

protected:
Guard m_alternative;
GuardAction m_match;
GuardAction m_action;
};

/// @brief A guard that checks if the entity is one of the types or sub-types
Expand Down
Loading