Skip to content

Commit

Permalink
Merge pull request #225 from mtconnect/add_assettype_unavailable_when…
Browse files Browse the repository at this point in the history
…_unavailable

AssetChanged and Removed attribute assetType fix
  • Loading branch information
wsobel authored May 31, 2022
2 parents bc6ba0c + a3d626c commit 72a5e11
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 81 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
set(AGENT_VERSION_MAJOR 2)
set(AGENT_VERSION_MINOR 0)
set(AGENT_VERSION_PATCH 0)
set(AGENT_VERSION_BUILD 5)
set(AGENT_VERSION_BUILD 6)
set(AGENT_VERSION_RC "")

# This minimum version is to support Visual Studio 2017 and C++ feature checking and FetchContent
Expand Down
114 changes: 65 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

MTConnect C++ Agent Version 2.0
--------
[![Build status](https://ci.appveyor.com/api/projects/status/g4xdyitw7h41rl48?svg=true)](https://ci.appveyor.com/project/WilliamSobel/cppagent_dev)
[![Build status](https://ci.appveyor.com/api/projects/status/g4xdyitw7h41rl48/branch/master?svg=true)](https://ci.appveyor.com/project/WilliamSobel/cppagent/branch/master)

The C++ Agent provides the a complete implementation of the HTTP
server required by the MTConnect standard. The agent provides the
Expand All @@ -11,19 +11,19 @@ the devices and the location of the adapter.

Pre-built binary releases for Windows are available from [Releases](https://github.com/mtconnect/cppagent/releases) for those who do not want to build the agent themselves. For *NIX users, you will need libxml2, cppunit, and cmake as well as build essentials.

Version 2.0.0.1 Rearchitecture of the agent with TLS, MQTT Adapter, Ruby Interpreter, Agent Adaptr, and much more
Version 2.0.0 Rearchitecture of the agent with TLS, MQTT Adapter, Ruby Interpreter, Agent Adaptr, and much more

Version 1.7.0.0 added kinematics, solid models, and new specifications types.
Version 1.7.0 added kinematics, solid models, and new specifications types.

Version 1.6.0.0 added coordinate systems, specifications, and tabular data.
Version 1.6.0 added coordinate systems, specifications, and tabular data.

Version 1.5.0.0 added Data Set capabilities and has been updated to use C++ 14.
Version 1.5.0 added Data Set capabilities and has been updated to use C++ 14.

Version 1.4.0.0 added time period filter constraint, compositions, initial values, and reset triggers.
Version 1.4.0 added time period filter constraint, compositions, initial values, and reset triggers.

Version 1.3.0.0 added the filter constraints, references, cutting tool archetypes, and formatting styles.
Version 1.3.0 added the filter constraints, references, cutting tool archetypes, and formatting styles.

Version 1.2.0.0 added the capability to support assets.
Version 1.2.0 added the capability to support assets.

Version 1.1.0.8 add the ability to run the C++ Agent as a Windows
service and support for a configuration file instead of command line
Expand Down Expand Up @@ -89,18 +89,7 @@ later.
Building
-------

Download cmake from [cmake](http://www.cmake.org/cmake/resources/software.html)

Make sure to initialize submodules:

git submodule init
git submodule update

Configure cmake using the `CMakeLists.txt` file in the agent
directory. This will generate a project file for the target
platform. See CMake documentation for more information.


Platform specific instructions are at the end of the README.

Configuration
------
Expand Down Expand Up @@ -139,7 +128,7 @@ Each set of files must be declared using a named file description, like schema o
styles and the local `Path` and the `Location` the files will be mapped to in the
HTTP server namespace. For example:

http://example.com:5000/schemas/MTConnectStreams_1.7.xsd will map to ../schemas/MTConnectStreams_1.7.xsd
http://example.com:5000/schemas/MTConnectStreams_2.0.xsd will map to ../schemas/MTConnectStreams_2.0.xsd

All files will be mapped and the directory names do not need to be the same. These files can be either served directly or can be used to extend the schema or add XSLT stylesheets for formatting the XML in browsers.

Expand All @@ -149,12 +138,12 @@ To specify the new schema for the documents, use the following declaration:

StreamsNamespaces {
e {
Urn = urn:example.com:ExampleStreams:1.7
Location = /schemas/ExampleStreams_1.7.xsd
Urn = urn:example.com:ExampleStreams:2.0
Location = /schemas/ExampleStreams_2.0.xsd
}
}

This will use the ExampleStreams_1.7.xsd schema in the document. The `e` is the alias that will be
This will use the ExampleStreams_2.0.xsd schema in the document. The `e` is the alias that will be
used to reference the extended schema. The `Location` is the location of the xsd file relative in
the agent namespace. The `Location` must be mapped in the `Files` section.

Expand Down Expand Up @@ -439,20 +428,20 @@ namespace -- you cannot change it.

StreamsNamespaces {
m {
Location = /schemas/MTConnectStreams_1.7.xsd
Path = ./MTConnectStreams_1.7.xsd
Location = /schemas/MTConnectStreams_2.0.xsd
Path = ./MTConnectStreams_2.0.xsd
}
}

DevicesNamespaces {
m {
Location = /schemas/MTConnectDevices_1.7.xsd
Path = ./MTConnectDevices_1.7.xsd
Location = /schemas/MTConnectDevices_2.0.xsd
Path = ./MTConnectDevices_2.0.xsd
}
}

The MTConnect agent will now serve the standard MTConnect schema files
from the local directory using the schema path /schemas/MTConnectDevices_1.7.xsd.
from the local directory using the schema path /schemas/MTConnectDevices_2.0.xsd.


### Example: 10 ###
Expand All @@ -464,40 +453,40 @@ Agent serve them up locally.

DevicesNamespaces {
x {
Urn = urn:example.com:ExampleDevices:1.7
Location = /schemas/ExampleDevices_1.7.xsd
Path = ./ExampleDevices_1.7.xsd
Urn = urn:example.com:ExampleDevices:2.0
Location = /schemas/ExampleDevices_2.0.xsd
Path = ./ExampleDevices_2.0.xsd
}

Files {
stream {
Location = /schemas/MTConnectStreams_1.7.xsd
Path = ./MTConnectStreams_1.7.xsd
Location = /schemas/MTConnectStreams_2.0.xsd
Path = ./MTConnectStreams_2.0.xsd
}
device {
Location = /schemas/MTConnectDevices_1.7.xsd
Path = ./MTConnectDevices_1.7.xsd
Location = /schemas/MTConnectDevices_2.0.xsd
Path = ./MTConnectDevices_2.0.xsd
}
}

Or use the short form for all files:

Files {
schemas {
Location = /schemas/MTConnectStreams_1.7.xsd
Path = ./MTConnectStreams_1.7.xsd
Location = /schemas/MTConnectStreams_2.0.xsd
Path = ./MTConnectStreams_2.0.xsd
}
}

If you have specified in your xs:include schemaLocation inside the
ExampleDevices_1.7.xsd file the location "/schemas/MTConnectStreams_1.7.xsd",
ExampleDevices_2.0.xsd file the location "/schemas/MTConnectStreams_2.0.xsd",
this will allow it to be served properly. This can also be done using the
Devices namespace:

DevicesNamespaces {
m {
Location = /schemas/MTConnectDevices_1.7.xsd
Path = ./MTConnectDevices_1.7.xsd
Location = /schemas/MTConnectDevices_2.0.xsd
Path = ./MTConnectDevices_2.0.xsd
}
}

Expand Down Expand Up @@ -651,7 +640,7 @@ Configuration Parameters

* `SchemaVersion` - Change the schema version to a different version number.

*Default*: 1.7
*Default*: 2.0

* `ConversionRequired` - Global default for data item units conversion in the agent.
Assumes the adapter has already done unit conversion.
Expand All @@ -678,7 +667,7 @@ Configuration Parameters

*Default*: 1

* `SuppressIPAddress` - Suppress the Adapter IP Address and port when creating the Agent Device ids and names for 1.7. This applies to all adapters.
* `SuppressIPAddress` - Suppress the Adapter IP Address and port when creating the Agent Device ids and names. This applies to all adapters.

*Default*: false

Expand Down Expand Up @@ -821,7 +810,7 @@ The following parameters must be present to enable https requests. If there is n

*Default*: 1

* `SuppressIPAddress` - Suppress the Adapter IP Address and port when creating the Agent Device ids and names for 1.7.
* `SuppressIPAddress` - Suppress the Adapter IP Address and port when creating the Agent Device ids and names.
*Default*: false


Expand Down Expand Up @@ -879,7 +868,7 @@ logger_config configuration items

*Default*: NEVER

Adapter Agent Protocol Version 1.7
Adapter Agent Protocol Version 2.0
=======

The principle adapter data format is a simple plain text stream separated by the pipe character `|`. Every line except for commands starts with an optional timestamp in UTC. If the timestamp is not supplied the agent will supply a timestamp of its own taken at the arrival time of the data to the agent. The remainder of the line is a key followed by data – depending on the type of data item is being written to.
Expand Down Expand Up @@ -1221,25 +1210,42 @@ An example in ruby is as follows:
> r.body
=> "<success/>"

# Building the agent on Windows and Ubuntu
# Building the agent

## Overview

The agent build is dependent on the following utilities:

* C++ Compiler compliant with C++ 17
* git is optional but suggested to download source and update when changes occur
* cmake for build generator and testing
* python 3 and pip to support conan for dependency and package management
* ruby and rake for mruby to support building the embedded scripting engine [not required if -o with_ruby=False]

## Building on Windows

The MTConnect Agent uses the conan package manager to install dependencies:

[Conan Package Manager Downloads](https://conan.io/downloads.html)
[python 3](https://www.python.org/downloads/) and [Conan Package Manager Downloads](https://conan.io/downloads.html)

Download the Windows installer for your platform and run the installer.

You also need CMake [CMake](https://cmake.org/download/) and git [git](https://git-scm.com/download/win)
You also need [git](https://git-scm.com/download/win) and [ruby](https://rubyinstaller.org) if you want to embed mruby.

CMake is installed as part of Visual Studio. If you are using Visual Studio for the build, use the bundled version. Otherwise download from CMake [CMake](https://cmake.org/download/).

### Setting up build

Install dependencies from the downloads above. Make sure python, ruby, and cmake are in your path.

pip install --upgrade pip
pip install conan

Clone the agent to another directory:

git clone https://github.com/mtconnect/cppagent.git

Make a build subdirectory of `cppagent_dev`
Make a build subdirectory of `cppagent`

cd cppagent
conan export conan\mqtt_cpp
Expand Down Expand Up @@ -1275,6 +1281,16 @@ The windows XP 140 XP toolchain needs to be installed under individual component

cpack -G ZIP

## *NIX Builds

The minimum memory (main + swap) when building with on CPU is 3GB. Less than that will likely cause the build to fail.

If the build runs out of resources, there are two options, you can add swap or set the following environment variable:

export CONAN_CPU_COUNT=1

to instruct conan to not parallelize the builds. Some of the modules that include boost beast require significant resources to build.

## Building on Ubuntu on 20.04 LTS

### Setup the build
Expand Down
2 changes: 1 addition & 1 deletion simulator/agent.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Devices = ../simulator/VMC-3Axis.xml
AllowPut = true
ReconnectInterval = 1000
BufferSize = 17
SchemaVersion = 1.7
SchemaVersion = 2.0
MonitorConfigFiles = true
Pretty = true
# MinimumConfigReloadAge = 30
Expand Down
7 changes: 6 additions & 1 deletion src/observation/observation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,12 @@ namespace mtconnect {
{
factory = make_shared<Factory>(*Event::getFactory());
factory->setFunction([](const std::string &name, Properties &props) -> EntityPtr {
return make_shared<AssetEvent>(name, props);
auto ent = make_shared<AssetEvent>(name, props);
if (!ent->hasProperty("assetType") && !ent->hasValue())
{
ent->setProperty("assetType", "UNAVAILABLE"s);
}
return ent;
});
factory->addRequirements(Requirements({{"assetType", false}}));
}
Expand Down
2 changes: 0 additions & 2 deletions src/observation/observation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,6 @@ namespace mtconnect {
class AssetEvent : public Event
{
public:
using super = Event;

using Event::Event;
static entity::FactoryPtr getFactory();
~AssetEvent() override = default;
Expand Down
2 changes: 1 addition & 1 deletion src/sink/rest_sink/cached_file.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ namespace mtconnect {
if (cached)
{
allocate(m_size);
auto file = std::fopen(path.string().c_str(), "r");
auto file = std::fopen(path.string().c_str(), "rb");
m_size = std::fread(m_buffer, 1, m_size, file);
}
m_lastWrite = std::filesystem::last_write_time(m_path);
Expand Down
Binary file added styles/MTConnect_Logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions styles/styles.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" style="padding: 5px 10px;" href="https://mtconnect.org" target="_blank" rel="noopener noreferrer">
<img alt="Brand" src="styles/LogoMTConnect.webp" />
<img alt="Brand" src="/styles/MTConnect_Logo.png" />
</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
Expand Down Expand Up @@ -573,4 +573,4 @@
</table>
</xsl:template> -->

</xsl:stylesheet>
</xsl:stylesheet>
48 changes: 24 additions & 24 deletions test/observation_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,30 @@ TEST_F(ObservationTest, subType_prefix_should_be_passed_through)
ASSERT_EQ("x:AUTO", event->get<string>("subType"));
}

TEST_F(ObservationTest, shoud_handle_asset_type)
{
ErrorList errors;
auto dataItem = DataItem::make(
{{"id", "c1"s}, {"category", "EVENT"s}, {"type", "ASSET_CHANGED"s}},
errors);

auto event1 = Observation::make(dataItem, {{"VALUE", "123"s}, {"assetType", "CuttingTool"s}},
m_time, errors);
ASSERT_EQ(0, errors.size());

ASSERT_EQ("CuttingTool"s, event1->get<string>("assetType"));
ASSERT_EQ("123"s, event1->getValue<string>());


auto event2 = Observation::make(dataItem, {{"VALUE", "UNAVAILABLE"s}},
m_time, errors);
ASSERT_EQ(0, errors.size());

ASSERT_TRUE(event2->isUnavailable());
ASSERT_EQ("UNAVAILABLE"s, event2->get<string>("assetType"));
}


// TODO: Make sure these tests are covered someplace else. Refactoring
// Moved this functionality outside the observation.

Expand Down Expand Up @@ -359,28 +383,4 @@ TEST_F(ObservationTest, Duration)
d.reset();
}

TEST_F(ObservationTest, AssetChanged)
{
string time("2011-02-18T15:52:[email protected]");
std::map<string, string> attributes1;
attributes1["id"] = "1";
attributes1["name"] = "ac";
attributes1["type"] = "ASSET_CHANGED";
attributes1["category"] = "EVENT";
auto d = make_unique<DataItem>(attributes1);

ASSERT_TRUE(d->isAssetChanged());

ObservationPtr event1(new Observation(*d, time, (string) "CuttingTool|123", 123), true);
const auto &attr_list = event1->getAttributes();
map<string, string> attrs1;

for (const auto &attr : attr_list)
attrs1[attr.first] = attr.second;

ASSERT_EQ((string) "CuttingTool", attrs1["assetType"]);
ASSERT_EQ((string) "123", event1->getValue());

d.reset();
}
#endif

0 comments on commit 72a5e11

Please sign in to comment.