Skip to content

Commit 72a5e11

Browse files
authored
Merge pull request mtconnect#225 from mtconnect/add_assettype_unavailable_when_unavailable
AssetChanged and Removed attribute assetType fix
2 parents bc6ba0c + a3d626c commit 72a5e11

File tree

9 files changed

+100
-81
lines changed

9 files changed

+100
-81
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
set(AGENT_VERSION_MAJOR 2)
33
set(AGENT_VERSION_MINOR 0)
44
set(AGENT_VERSION_PATCH 0)
5-
set(AGENT_VERSION_BUILD 5)
5+
set(AGENT_VERSION_BUILD 6)
66
set(AGENT_VERSION_RC "")
77

88
# This minimum version is to support Visual Studio 2017 and C++ feature checking and FetchContent

README.md

Lines changed: 65 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

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

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

1212
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.
1313

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

16-
Version 1.7.0.0 added kinematics, solid models, and new specifications types.
16+
Version 1.7.0 added kinematics, solid models, and new specifications types.
1717

18-
Version 1.6.0.0 added coordinate systems, specifications, and tabular data.
18+
Version 1.6.0 added coordinate systems, specifications, and tabular data.
1919

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

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

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

26-
Version 1.2.0.0 added the capability to support assets.
26+
Version 1.2.0 added the capability to support assets.
2727

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

92-
Download cmake from [cmake](http://www.cmake.org/cmake/resources/software.html)
93-
94-
Make sure to initialize submodules:
95-
96-
git submodule init
97-
git submodule update
98-
99-
Configure cmake using the `CMakeLists.txt` file in the agent
100-
directory. This will generate a project file for the target
101-
platform. See CMake documentation for more information.
102-
103-
92+
Platform specific instructions are at the end of the README.
10493

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

142-
http://example.com:5000/schemas/MTConnectStreams_1.7.xsd will map to ../schemas/MTConnectStreams_1.7.xsd
131+
http://example.com:5000/schemas/MTConnectStreams_2.0.xsd will map to ../schemas/MTConnectStreams_2.0.xsd
143132

144133
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.
145134

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

150139
StreamsNamespaces {
151140
e {
152-
Urn = urn:example.com:ExampleStreams:1.7
153-
Location = /schemas/ExampleStreams_1.7.xsd
141+
Urn = urn:example.com:ExampleStreams:2.0
142+
Location = /schemas/ExampleStreams_2.0.xsd
154143
}
155144
}
156145

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

@@ -439,20 +428,20 @@ namespace -- you cannot change it.
439428

440429
StreamsNamespaces {
441430
m {
442-
Location = /schemas/MTConnectStreams_1.7.xsd
443-
Path = ./MTConnectStreams_1.7.xsd
431+
Location = /schemas/MTConnectStreams_2.0.xsd
432+
Path = ./MTConnectStreams_2.0.xsd
444433
}
445434
}
446435

447436
DevicesNamespaces {
448437
m {
449-
Location = /schemas/MTConnectDevices_1.7.xsd
450-
Path = ./MTConnectDevices_1.7.xsd
438+
Location = /schemas/MTConnectDevices_2.0.xsd
439+
Path = ./MTConnectDevices_2.0.xsd
451440
}
452441
}
453442

454443
The MTConnect agent will now serve the standard MTConnect schema files
455-
from the local directory using the schema path /schemas/MTConnectDevices_1.7.xsd.
444+
from the local directory using the schema path /schemas/MTConnectDevices_2.0.xsd.
456445

457446

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

465454
DevicesNamespaces {
466455
x {
467-
Urn = urn:example.com:ExampleDevices:1.7
468-
Location = /schemas/ExampleDevices_1.7.xsd
469-
Path = ./ExampleDevices_1.7.xsd
456+
Urn = urn:example.com:ExampleDevices:2.0
457+
Location = /schemas/ExampleDevices_2.0.xsd
458+
Path = ./ExampleDevices_2.0.xsd
470459
}
471460

472461
Files {
473462
stream {
474-
Location = /schemas/MTConnectStreams_1.7.xsd
475-
Path = ./MTConnectStreams_1.7.xsd
463+
Location = /schemas/MTConnectStreams_2.0.xsd
464+
Path = ./MTConnectStreams_2.0.xsd
476465
}
477466
device {
478-
Location = /schemas/MTConnectDevices_1.7.xsd
479-
Path = ./MTConnectDevices_1.7.xsd
467+
Location = /schemas/MTConnectDevices_2.0.xsd
468+
Path = ./MTConnectDevices_2.0.xsd
480469
}
481470
}
482471

483472
Or use the short form for all files:
484473

485474
Files {
486475
schemas {
487-
Location = /schemas/MTConnectStreams_1.7.xsd
488-
Path = ./MTConnectStreams_1.7.xsd
476+
Location = /schemas/MTConnectStreams_2.0.xsd
477+
Path = ./MTConnectStreams_2.0.xsd
489478
}
490479
}
491480

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

497486
DevicesNamespaces {
498487
m {
499-
Location = /schemas/MTConnectDevices_1.7.xsd
500-
Path = ./MTConnectDevices_1.7.xsd
488+
Location = /schemas/MTConnectDevices_2.0.xsd
489+
Path = ./MTConnectDevices_2.0.xsd
501490
}
502491
}
503492

@@ -651,7 +640,7 @@ Configuration Parameters
651640

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

654-
*Default*: 1.7
643+
*Default*: 2.0
655644

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

679668
*Default*: 1
680669

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

683672
*Default*: false
684673

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

822811
*Default*: 1
823812

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

827816

@@ -879,7 +868,7 @@ logger_config configuration items
879868

880869
*Default*: NEVER
881870

882-
Adapter Agent Protocol Version 1.7
871+
Adapter Agent Protocol Version 2.0
883872
=======
884873

885874
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.
@@ -1221,25 +1210,42 @@ An example in ruby is as follows:
12211210
> r.body
12221211
=> "<success/>"
12231212

1224-
# Building the agent on Windows and Ubuntu
1213+
# Building the agent
1214+
1215+
## Overview
1216+
1217+
The agent build is dependent on the following utilities:
1218+
1219+
* C++ Compiler compliant with C++ 17
1220+
* git is optional but suggested to download source and update when changes occur
1221+
* cmake for build generator and testing
1222+
* python 3 and pip to support conan for dependency and package management
1223+
* ruby and rake for mruby to support building the embedded scripting engine [not required if -o with_ruby=False]
12251224

12261225
## Building on Windows
12271226

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

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

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

1234-
You also need CMake [CMake](https://cmake.org/download/) and git [git](https://git-scm.com/download/win)
1233+
You also need [git](https://git-scm.com/download/win) and [ruby](https://rubyinstaller.org) if you want to embed mruby.
1234+
1235+
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/).
12351236

12361237
### Setting up build
12371238

1239+
Install dependencies from the downloads above. Make sure python, ruby, and cmake are in your path.
1240+
1241+
pip install --upgrade pip
1242+
pip install conan
1243+
12381244
Clone the agent to another directory:
12391245

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

1242-
Make a build subdirectory of `cppagent_dev`
1248+
Make a build subdirectory of `cppagent`
12431249

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

12761282
cpack -G ZIP
12771283

1284+
## *NIX Builds
1285+
1286+
The minimum memory (main + swap) when building with on CPU is 3GB. Less than that will likely cause the build to fail.
1287+
1288+
If the build runs out of resources, there are two options, you can add swap or set the following environment variable:
1289+
1290+
export CONAN_CPU_COUNT=1
1291+
1292+
to instruct conan to not parallelize the builds. Some of the modules that include boost beast require significant resources to build.
1293+
12781294
## Building on Ubuntu on 20.04 LTS
12791295

12801296
### Setup the build

simulator/agent.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Devices = ../simulator/VMC-3Axis.xml
22
AllowPut = true
33
ReconnectInterval = 1000
44
BufferSize = 17
5-
SchemaVersion = 1.7
5+
SchemaVersion = 2.0
66
MonitorConfigFiles = true
77
Pretty = true
88
# MinimumConfigReloadAge = 30

src/observation/observation.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,12 @@ namespace mtconnect {
308308
{
309309
factory = make_shared<Factory>(*Event::getFactory());
310310
factory->setFunction([](const std::string &name, Properties &props) -> EntityPtr {
311-
return make_shared<AssetEvent>(name, props);
311+
auto ent = make_shared<AssetEvent>(name, props);
312+
if (!ent->hasProperty("assetType") && !ent->hasValue())
313+
{
314+
ent->setProperty("assetType", "UNAVAILABLE"s);
315+
}
316+
return ent;
312317
});
313318
factory->addRequirements(Requirements({{"assetType", false}}));
314319
}

src/observation/observation.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,6 @@ namespace mtconnect {
316316
class AssetEvent : public Event
317317
{
318318
public:
319-
using super = Event;
320-
321319
using Event::Event;
322320
static entity::FactoryPtr getFactory();
323321
~AssetEvent() override = default;

src/sink/rest_sink/cached_file.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ namespace mtconnect {
7676
if (cached)
7777
{
7878
allocate(m_size);
79-
auto file = std::fopen(path.string().c_str(), "r");
79+
auto file = std::fopen(path.string().c_str(), "rb");
8080
m_size = std::fread(m_buffer, 1, m_size, file);
8181
}
8282
m_lastWrite = std::filesystem::last_write_time(m_path);

styles/MTConnect_Logo.png

8.02 KB
Loading

styles/styles.xsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
<span class="icon-bar"></span>
4040
</button>
4141
<a class="navbar-brand" style="padding: 5px 10px;" href="https://mtconnect.org" target="_blank" rel="noopener noreferrer">
42-
<img alt="Brand" src="styles/LogoMTConnect.webp" />
42+
<img alt="Brand" src="/styles/MTConnect_Logo.png" />
4343
</a>
4444
</div>
4545
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
@@ -573,4 +573,4 @@
573573
</table>
574574
</xsl:template> -->
575575

576-
</xsl:stylesheet>
576+
</xsl:stylesheet>

test/observation_test.cpp

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,30 @@ TEST_F(ObservationTest, subType_prefix_should_be_passed_through)
228228
ASSERT_EQ("x:AUTO", event->get<string>("subType"));
229229
}
230230

231+
TEST_F(ObservationTest, shoud_handle_asset_type)
232+
{
233+
ErrorList errors;
234+
auto dataItem = DataItem::make(
235+
{{"id", "c1"s}, {"category", "EVENT"s}, {"type", "ASSET_CHANGED"s}},
236+
errors);
237+
238+
auto event1 = Observation::make(dataItem, {{"VALUE", "123"s}, {"assetType", "CuttingTool"s}},
239+
m_time, errors);
240+
ASSERT_EQ(0, errors.size());
241+
242+
ASSERT_EQ("CuttingTool"s, event1->get<string>("assetType"));
243+
ASSERT_EQ("123"s, event1->getValue<string>());
244+
245+
246+
auto event2 = Observation::make(dataItem, {{"VALUE", "UNAVAILABLE"s}},
247+
m_time, errors);
248+
ASSERT_EQ(0, errors.size());
249+
250+
ASSERT_TRUE(event2->isUnavailable());
251+
ASSERT_EQ("UNAVAILABLE"s, event2->get<string>("assetType"));
252+
}
253+
254+
231255
// TODO: Make sure these tests are covered someplace else. Refactoring
232256
// Moved this functionality outside the observation.
233257

@@ -359,28 +383,4 @@ TEST_F(ObservationTest, Duration)
359383
d.reset();
360384
}
361385

362-
TEST_F(ObservationTest, AssetChanged)
363-
{
364-
string time("2011-02-18T15:52:[email protected]");
365-
std::map<string, string> attributes1;
366-
attributes1["id"] = "1";
367-
attributes1["name"] = "ac";
368-
attributes1["type"] = "ASSET_CHANGED";
369-
attributes1["category"] = "EVENT";
370-
auto d = make_unique<DataItem>(attributes1);
371-
372-
ASSERT_TRUE(d->isAssetChanged());
373-
374-
ObservationPtr event1(new Observation(*d, time, (string) "CuttingTool|123", 123), true);
375-
const auto &attr_list = event1->getAttributes();
376-
map<string, string> attrs1;
377-
378-
for (const auto &attr : attr_list)
379-
attrs1[attr.first] = attr.second;
380-
381-
ASSERT_EQ((string) "CuttingTool", attrs1["assetType"]);
382-
ASSERT_EQ((string) "123", event1->getValue());
383-
384-
d.reset();
385-
}
386386
#endif

0 commit comments

Comments
 (0)