Giter VIP home page Giter VIP logo

mtconnect / cppagent Goto Github PK

View Code? Open in Web Editor NEW
133.0 38.0 88.0 84.06 MB

C++ Agent toolkit - Pre-built binaries, visit: https://github.com/mtconnect/cppagent/releases Docker images available at https://hub.docker.com/repositories/mtconnect

Home Page: http://mtcup.org/

License: Apache License 2.0

CMake 1.51% C++ 84.88% NSIS 0.69% Shell 0.36% HTML 0.89% Ruby 0.69% CSS 0.13% XSLT 0.91% Batchfile 0.07% TeX 7.73% VBScript 0.40% Dockerfile 0.47% JavaScript 0.24% Python 1.05%
c-plus-plus mtconnect mtconnect-standard mtconnect-agent iiot agent

cppagent's Introduction

MTConnect C++ Agent Version 2.3

Build MTConnect C++ Agent

The C++ Agent provides the a complete implementation of the HTTP server required by the MTConnect standard. The agent provides the protocol and data collection framework that will work as a standalone server. Once built, you only need to specify the XML description of the devices and the location of the adapter.

NOTE: This version cannot currently be built on Windows XP since there is currently no support for the XP toolchain and C++ 17.

Pre-built binary releases for Windows are available from 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.3.0 Support for all Version 2.3 standard changes and JSON ingress to MQTT adapter.

Version 2.2.0 Support for all Version 2.2 standard changes and dynamic configuration from adapters. Upgrade to conan 2.

Version 2.1.0 Added MQTT Sink, Agent Restart and new JSON format (version 2)

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

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

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

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

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

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

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 arguments. The agent can accept input from a socket in a pipe (|) delimited stream according to the descriptions given in the adapter guide.

The current win32 binary is built statically and requires no additional dlls to run. This allows for a single exe distributable.

Usage

agent [help|install|debug|run] [configuration_file]
   help           Prints this message
   install        Installs the service
   remove         Remove the service
   debug          Runs the agent on the command line with verbose logging -
                  sets logging_level to debug
   run            Runs the agent on the command line
   config_file    The configuration file to load
                  Default: agent.cfg in current directory

When the agent is started without any arguments it is assumed it will be running as a service and will begin the service initialization sequence. The full path to the configuration file is stored in the registry in the following location:

\\HKEY_LOCAL_MACHINE\SOFTWARE\MTConnect\MTConnect Agent\ConfigurationFile

Directories

  • agent/ - This contains the application source files and CMake file.

  • assets/ - Some example Cutting Tool asset files.

  • lib/ - Third party library source. Contains source for cppunit, dlib, and libxml++.

  • samples/ - Sample XML configuration files mainly used for tests.

  • simulator/ - Ruby scripts to execute an adapter simulator, both command-line and log-replay.

  • test/ - Various unit tests.

  • tools/ - Ruby scripts to dump the agent and the adapter in SHDR format. Includes a sequence test script.

  • unix/ - Unix init.d script

  • win32/ - Libraries required only for the win32 build and the win32 solution.

Windows Binary Release

The windows binary releases come with a prebuilt exe that is statically linked with the Microsoft Runtime libraries. Aside from the standard system libraries, the agent only requires winsock libraries. The agent has been test with version of Windows 2000 and later.

  • bin/ - Win32 binary (no dependencies required).

Building

Platform specific instructions are at the end of the README.

Configuration

The configuration file is using the standard Boost C++ file format. The configuration file format is flexible and allows for both many adapters to be served from one agent and an adapter to feed multiple agents. The format is:

Key = Value

The key can only occur once within a section and the value can be any sequence of characters followed by a <CR>. There no significance to the order of the keys, so the file can be specified in free form. We will go over some configurations from a minimal configuration to more complex multi-adapter configurations.

Serving Static Content

Using a Files Configuration section, individual files or directories can be inserted into the request file space from the agent. To do this, we use the Files top level configuration declaration as follows:

Files {
    schemas {
        Path = ../schemas
        Location = /schemas/
    }
    styles {
        Path = ../styles
        Location = /styles/
    }
}

Each set of files must be declared using a named file description, like schema or 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_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.

Specifying the Extended Schemas

To specify the new schema for the documents, use the following declaration:

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

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.

An optional Path can be added to the ...Namespaces declaration instead of declaring the Files section. The Files makes it easier to include multiple files from a directory and will automatically include all the default MTConnect schema files for the correct version. (See SchemaVersion option below)

You can do this for any one of the other documents:

StreamsNamespaces
DevicesNamespaces
AssetsNamespaces
ErrorNamespaces

Specifying the XML Document Style

The same can be done with style sheets, but only the Location is required.

StreamsStyle {
  Location = /styles/Streams.xsl
}

An optional Path can also be used to reference the xsl file directly. This will not include other files in the path like css or included xsl transforms. It is advised to use the Files declaration.

The following can also be declared:

DevicesStyle
StreamsStyle
AssetsStyle
ErrorStyle

Example 1:

Here’s an example configuration file. The # character can be used to comment sections of the file. Everything on the line after the # is ignored. We will start with an extremely simple configuration file.

# A very simple file...
Devices = VMC-3Axis.xml

This is a one line configuration that specifies the XML file to load for the devices. Since all the values are defaulted, an empty configuration file can be specified. This configuration file will load the VMC-3Axis.xml file and try to connect to an adapter located on the localhost at port 7878. VMC-3Axis.xml must only contain the definition for one device; if more devices exist, an error will be raised and the process will exit.

Example 2:

Most configuration files will specify at least one adapter. The adapters are contained within a block. The Boost configuration file format allows for nested configurations and block associations. There are a number of configurations that can be given for each adapter. Multiple adapters can be specified for one device as well.

Devices = VMC-3Axis.xml

Adapters
{
    VMC-3Axis
    {
        Host = 192.168.10.22
        Port = 7878 # *Default* value...
    }
}

This example loads the devices file as before, but specifies the list of adapters. The device is taken from the name VMC-3Axis that starts the nested block and connects to the adapter on 192.168.10.22 and port 7878. Another way of specifying the equivalent configuration is:

Devices = VMC-3Axis.xml

Adapters
{
    Adapter_1
    {
        Device = VMC-3Axis
        Host = 192.168.10.22
        Port = 7878 # *Default* value...
    }
}

Line 7 specifies the Device name associated with this adapter explicitly. We will show how this is used in the next example.

Example 3:

Multiple adapters can supply data to the same device. This is done by creating multiple adapter entries and specifying the same Device for each.

Devices = VMC-3Axis.xml

Adapters
{
    Adapter_1
    {
        Device = VMC-3Axis
        Host = 192.168.10.22
        Port = 7878 # *Default* value...
    }

    # Energy sensor
    Adapter_2
    {
        Device = VMC-3Axis
        Host = 192.168.10.2
        Port = 7878 # *Default* value...
    }
}

Both Adapter_1 and Adapter_2 will feed the VMC-3Axis device with different data items. The Adapter_1 name is arbitrary and could just as well be named EnergySensor if desired as illustrated below.

Devices = VMC-3Axis.xml

Adapters
{
    Controller
    {
        Device = VMC-3Axis
        Host = 192.168.10.22
        Port = 7878 # *Default* value...
    }

    EnergySensor
    {
        Device = VMC-3Axis
        Host = 192.168.10.2
        Port = 7878 # *Default* value...
    }
}

Example 4:

In this example we change the port to 80 which is the default http port. This also allows HTTP PUT from the local machine and 10.211.55.2.

Devices = MyDevices.xml
Port = 80
AllowPutFrom = localhost, 10.211.55.2

Adapters
{
    ...

For browsers you will no longer need to specify the port to connect to.

Example 5:

If multiple devices are specified in the XML file, there must be an adapter feeding each device.

Devices = MyDevices.xml

Adapters
{
    VMC-3Axis
    {
        Host = 192.168.10.22
    }

    HMC-5Axis
    {
        Host = 192.168.10.24
    }
}

This will associate the adapters for these two machines to the VMC and HMC devices in MyDevices.xml file. The ports are defaulted to 7878, so we are not required to specify them.

Example 6:

In this example we demonstrate how to change the service name of the agent. This allows a single machine to run multiple agents and/or customize the name of the service. Multiple configuration files can be created for each service, each with a different ServiceName. The configuration file must be referenced as follows:

C:> agent install myagent.cfg

If myagent.cfg contains the following statements:

Devices = MyDevices.xml
ServiceName = MTC Agent 1

Adapters
{
    ...

The service will now be displayed as "MTC Agent 1" as opposed to "MTConnect Agent" and it will automatically load the contents of myagent.cfg with it starts. You can now use the following command to start this from a command prompt:

C:> net start "MTC Agent 1"

To remove the service, do the following:

C:> agent remove myagent.cfg

Example 7:

Logging configuration is specified using the logger_config block. You can change the logging_level to specify the verbosity of the logging as well as the destination of the logging output.

logger_config
{
    logging_level = debug
    output = file debug.log
}

This will log everything from debug to fatal to the file debug.log. For only fatal errors you can specify the following:

logger_config
{
    logging_level = fatal
}

The default file is agent.log in the same directory as the agent.exe file resides. The default logging level is info. To have the agent log to the command window:

logger_config
{
    logging_level = debug
    output = cout
}

This will log debug level messages to the current console window. When the agent is run with debug, it sets the logging configuration to debug and outputs to the standard output as specified above.

Example: 8

The MTConnect C++ Agent supports extensions by allowing you to specify your own XSD schema files. These files must include the MTConnect schema and the top level node is required to be MTConnect. The "x" in this case is the namespace. You MUST NOT use the namespace "m" since it is reserved for MTConnect. See example 9 for an example of changing the MTConnect schema file location.

There are four namespaces in MTConnect: Devices, Streams, Assets, and Error. In this example we will replace the Streams and Devices namespace with our own namespace so we can have validatable XML documents.

StreamsNamespaces {
  x {
    Urn = urn:example.com:ExampleStreams:1.2
    Location = /schemas/ExampleStreams_1.2.xsd
    Path = ./ExampleStreams_1.2.xsd
  }
}

DevicesNamespaces {
  x {
    Urn = urn:example.com:ExampleDevices:1.2
    Location = /schemas/ExampleDevices_1.2.xsd
    Path = ./ExampleDevices_1.2.xsd
  }
}

For each schema file we have three options we need to specify. The Urn is the urn in the schema file that will be used in the header. The Location is the path specified in the URL when requesting the schema file from the HTTP client and the Path is the path on the local file system.

Example: 9

If you only want to change the schema location of the MTConnect schema files and serve them from your local agent and not from the default internet location, you can use the namespace "m" and give the new schema file location. This MUST be the MTConnect schema files and the urn will always be the MTConnect urn for the "m" namespace -- you cannot change it.

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

DevicesNamespaces {
  m {
    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_2.0.xsd.

Example: 10

We can also serve files from the MTConnect Agent as well. In this example we can assume we don't have access to the public internet and we would still like to provide the MTConnect streams and devices files but have the MTConnect Agent serve them up locally.

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

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

Or use the short form for all files:

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

If you have specified in your xs:include schemaLocation inside the 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_2.0.xsd
    Path = ./MTConnectDevices_2.0.xsd
  }
}

The MTConnect agent will allow you to serve any other files you wish as well. You can specify a new static file you would like to deliver:

Files {
  myfile { 
    Location = /files/xxx.txt
    Path = ./files/xxx.txt
  }

The agent will not serve all files from a directory and will not provide an index function as this is insecure and not the intended function of the agent.

Ruby

If the "-o with_ruby=True" build is selected, then use to following configuration:

Ruby {
  module = path/to/module.rb
}

The module specified at the path given will be loaded. There are examples in the test/Resources/ruby directory in github: Ruby Tests.

The current functionality is limited to the pipeline transformations from the adapters. Future changes will include adding sources and sinks.

The following is a complete example for fixing the Execution of a machine:

class AlertTransform < MTConnect::RubyTransform
  def initialize(name, filter)
    @cache = Hash.new
    super(name, filter)
  end

  @@count = 0
  def transform(obs)
    @@count += 1
    if @@count % 10000 == 0
      puts "---------------------------"
      puts ">  #{ObjectSpace.count_objects}"
      puts "---------------------------"
    end
    
    dataItemId = obs.properties[:dataItemId]
    if dataItemId == 'servotemp1' or dataItemId == 'Xfrt' or dataItemId == 'Xload'
      @cache[dataItemId] = obs.value
      device = MTConnect.agent.default_device
      
      di = device.data_item('xaxisstate')
      if @cache['servotemp1'].to_f > 10.0 or @cache['Xfrt'].to_f > 10.0 or @cache['Xload'].to_f > 10
        newobs = MTConnect::Observation.new(di, "ERROR")
      else
        newobs = MTConnect::Observation.new(di, "OK")
      end
      forward(newobs)
    end
    forward(obs)
  end
end
    
MTConnect.agent.sources.each do |s|
  pipe = s.pipeline
  puts "Splicing the pipeline"
  trans = AlertTransform.new('AlertTransform', :Sample)
  puts trans
  pipe.splice_before('DeliverObservation', trans)
end

Configuration Parameters

Top level configuration items

  • AgentDeviceUUID - Set the UUID of the agent device

    Default: UUID derived from the IP address and port of the agent

  • BufferSize - The 2^X number of slots available in the circular buffer for samples, events, and conditions.

    Default: 17 -> 2^17 = 131,072 slots.

  • CheckpointFrequency - The frequency checkpoints are created in the stream. This is used for current with the at argument. This is an advanced configuration item and should not be changed unless you understand the internal workings of the agent.

    Default: 1000

  • Devices - The XML file to load that specifies the devices and is supplied as the result of a probe request. If the key is not found the defaults are tried.

    Defaults: probe.xml or Devices.xml

  • DisableAgentDevice - When the schema version is >= 1.7, disable the creation of the Agent device.

    Default: false

  • JsonVersion - JSON Printer format. Old format: 1, new format: 2

    Default: 2

  • SchemaVersion - Change the schema version to a different version number.

    Default: 2.0

  • MaxAssets - The maximum number of assets the agent can hold in its buffer. The number is the actual count, not an exponent.

    Default: 1024

  • MonitorConfigFiles - Monitor agent.cfg and Devices.xml files and restart agent if they change.

    Default: false

  • MinimumConfigReloadAge - The minimum age of a config file before an agent reload is triggered (seconds).

    Default: 15

  • Pretty - Pretty print the output with indententation

    Default: false

  • PidFile - UNIX only. The full path of the file that contains the process id of the daemon. This is not supported in Windows.

    Default: agent.pid

  • ServiceName - Changes the service name when installing or removing the service. This allows multiple agents to run as services on the same machine.

    Default: MTConnect Agent

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

    Default: false

  • WorkerThreads - The number of operating system threads dedicated to the Agent

    Default: 1

Adapter General Configuration

These can be overridden on a per-adapter basis

  • Protocol –Specify protocol. Options: [shdr|mqtt]

    Default: shdr

  • ConversionRequired - Global default for data item units conversion in the agent. Assumes the adapter has already done unit conversion.

    Default: true

  • EnableSourceDeviceModels - Allow adapters and data sources to supply Device configuration

    Default: false

  • Heartbeat – Overrides the heartbeat interval sent back from the adapter in the * PONG <hb>. The heartbeat will always be this value in milliseconds.

    Default: None

  • IgnoreTimestamps - Overwrite timestamps with the agent time. This will correct clock drift but will not give as accurate relative time since it will not take into consideration network latencies. This can be overridden on a per adapter basis.

    Default: false

  • LegacyTimeout - The default length of time an adapter can be silent before it is disconnected. This is only for legacy adapters that do not support heartbeats.

    Default: 600

  • PreserveUUID - Do not overwrite the UUID with the UUID from the adapter, preserve the UUID in the Devices.xml file. This can be overridden on a per adapter basis.

    Default: true

  • ReconnectInterval - The amount of time between adapter reconnection attempts. This is useful for implementation of high performance adapters where availability needs to be tracked in near-real-time. Time is specified in milliseconds (ms).

    Default: 10000

  • ShdrVersion - Specifies the SHDR protocol version used by the adapter. When greater than one (1), allows multiple complex observations, like Condition and Message on the same line. If it equials one (1), then any observation requiring more than a key/value pair need to be on separate lines. This is the default for all adapters.

    Default: 1

  • UpcaseDataItemValue - Always converts the value of the data items to upper case.

    Default: true

REST Service Configuration

  • AllowPut - Allow HTTP PUT or POST of data item values or assets.

    Default: false

  • AllowPutFrom - Allow HTTP PUT or POST from a specific host or list of hosts. Lists are comma (,) separated and the host names will be validated by translating them into IP addresses.

    Default: none

  • HttpHeaders - Additional headers to add to the HTTP Response for CORS Security

    Example: HttpHeaders { Access-Control-Allow-Origin = * Access-Control-Allow-Methods = GET Access-Control-Allow-Headers = Content-Type }

  • Port - The port number the agent binds to for requests.

    Default: 5000

  • ServerIp - The server IP Address to bind to. Can be used to select the interface in IPV4 or IPV6.

    Default: 0.0.0.0

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.

  • TlsCertificateChain - The name of the file containing the certificate chain created from signing authority

    Default: NULL

  • TlsCertificatePassword - The password used when creating the certificate. If none was supplied, do not use.

    Default: NULL

  • TlsClientCAs - For TlsVerifyClientCertificate, specifies a file that contains additional certificate authorities for verification

    Default: NULL

  • TlsDHKey - The name of the file containing the Diffie–Hellman key

    Default: NULL

  • TlsOnly - Only allow secure connections, http requests will be rejected

    Default: false

  • TlsPrivateKey - The name of the file containing the private key for the certificate

    Default: NULL

  • TlsVerifyClientCertificate - Request and verify the client certificate against root authorities

    Default: false

MQTT Configuration

  • MqttCaCert - CA Certificate for MQTT TLS connection to the MTT Broker

    Default: NULL

  • MqttHost - IP Address or name of the MQTT Broker

    Default: 127.0.0.1

  • MqttPort - Port number of MQTT Broker

    Default: 1883

  • MqttTls - TLS Certificate for secure connection to the MQTT Broker

    Default: false

  • MqttWs - Instructs MQTT to connect using web sockets

    Default: false

MQTT Sink

Enabled in agent.cfg by specifying:

Sinks {
  MqttService {
    # Configuration Options...
  }
}
  • DeviceTopic - Prefix for the Device Model topic

    Default: MTConnect/Device/

  • ObservationTopic - Prefix for the Streams events, samples, and conditions

    Default: MTConnect/Observation/

  • AssetTopic - Prefix for the Assets

    Default: MTConnect/Asset/

MQTT Sink 2

Enabled in agent.cfg by specifying:

Sinks {
  Mqtt2Service {
    # Configuration Options...
  }
}
  • AssetTopic - Prefix for the Assets

    Default: MTConnect/Asset/[device]

  • CurrentTopic - Prefix for the Current

    Default: MTConnect/Current/[device]

  • ProbeTopic or DeviceTopic - Prefix for the Device Model topic

    Note: The [device] will be replace with the uuid of each device. Other patterns can be created, for example: MTConnect/[device]/Probe will group by device instead of operation. DeviceTopic will also work.

    Default: MTConnect/Probe/[device]

  • SampleTopic - Prefix for the Sample

    Default: MTConnect/Sample/[device]

  • MqttLastWillTopic - The topic used for the last will and testement for an agent

    Note: The value will be AVAILABLE when the Agent is publishing and connected and will publish UNAVAILABLE when the agent disconnects from the broker.

    Default: MTConnect/Probe/[device]/Availability"

  • MqttCurrentInterval - The frequency to publish currents. Acts like a keyframe in a video stream.

    Default: 10000ms

  • MqttSampleInterval - The frequency to publish samples. Works the same way as the interval in the rest call. Groups observations up and publishes with the minimum interval given. If nothing is availble, will wait until an observation arrives to publish.

    Default: 500ms

  • MqttSampleCount - The maxmimum number of observations to publish at one time.

    Default: 1000

Adapter Configuration Items

  • Adapters - Contains a list of device blocks. If there are no Adapters specified and the Devices file contains one device, the Agent defaults to an adapter located on the localhost at port 7878. Data passed from the Adapter is associated with the default device.

    Default: localhost 7878, associated with the default device

    • Device - The name of the device that corresponds to the name of the device in the Devices file. Each adapter can map to one device. Specifying a "*" will map to the default device.

      Default: The name of the block for this adapter or if that is not found the default device if only one device is specified in the devices file.

    • Host - The host the adapter is located on.

      Default: localhost

    • Port - The port to connect to the adapter.

      Default: 7878

    • Manufacturer - Replaces the manufacturer attribute in the device XML.

      Default: Current value in device XML.

    • Station - Replaces the Station attribute in the device XML.

      Default: Current value in device XML.

    • SerialNumber - Replaces the SerialNumber attribute in the device XML.

      Default: Current value in device XML.

    • UUID - Replaces the UUID attribute in the device XML.

      Default: Current value in device XML.

    • AutoAvailable - For devices that do not have the ability to provide available events, if yes, this sets the Availability to AVAILABLE upon connection.

      Default: no (new in 1.2, if AVAILABILITY is not provided for device it will be automatically added and this will default to yes)

    • AdditionalDevices - Comma separated list of additional devices connected to this adapter. This provides availability support when one adapter feeds multiple devices.

      Default: nothing

    • FilterDuplicates - If value is yes, filters all duplicate values for data items. This is to support adapters that are not doing proper duplicate filtering.

      Default: no

    • LegacyTimeout - length of time an adapter can be silent before it is disconnected. This is only for legacy adapters that do not support heartbeats. If heartbeats are present, this will be ignored.

      Default: 600

    • ReconnectInterval - The amount of time between adapter reconnection attempts. This is useful for implementation of high performance adapters where availability needs to be tracked in near-real-time. Time is specified in milliseconds (ms). Defaults to the top level ReconnectInterval.

      Default: 10000

    • IgnoreTimestamps - Overwrite timestamps with the agent time. This will correct clock drift but will not give as accurate relative time since it will not take into consideration network latencies. This can be overridden on a per adapter basis.

      Default: Top Level Setting

    • PreserveUUID - Do not overwrite the UUID with the UUID from the adapter, preserve the UUID in the Devices.xml file. This can be overridden on a per adapter basis.

        *Default*: false
      
    • RealTime - Boost the thread priority of this adapter so that events are handled faster.

      Default: false

    • RelativeTime - The timestamps will be given as relative offsets represented as a floating point number of milliseconds. The offset will be added to the arrival time of the first recorded event.

      Default: false

    • ConversionRequired - Adapter setting for data item units conversion in the agent. Assumes the adapter has already done unit conversion. Defaults to global.

      Default: Top Level Setting

    • UpcaseDataItemValue - Always converts the value of the data items to upper case.

      Default: Top Level Setting

    • ShdrVersion - Specifies the SHDR protocol version used by the adapter. When greater than one (1), allows multiple complex observations, like Condition and Message on the same line. If it equials one (1), then any observation requiring more than a key/value pair need to be on separate lines. Applies to only this adapter.

      Default: 1

    • SuppressIPAddress - Suppress the Adapter IP Address and port when creating the Agent Device ids and names.

      Default: false

    • AdapterIdentity - Adapter Identity name used to prefix dataitems within the Agent device ids and names.

      Default:

      • If SuppressIPAddress == false:
        AdapterIdentity = _ {IP}_{PORT}
        example:_localhost_7878

      • If SuppressIPAddress == true:
        AdapterIdentity = _ sha1digest({IP}_{PORT})
        example: __71020ed1ed

MQTT Adapter/Source

  • MqttHost - IP Address or name of the MQTT Broker

    Default: 127.0.0.1

  • MqttPort - Port number of MQTT Broker

    Default: 1883

  • topics - list of topics to subscribe to. Note : Only raw SHDR strings supported at this time

    Required

  • MqttClientId - Port number of MQTT Broker

    Default: Auto-generated

    ⚠️Note: Mqtt Sinks and Mqtt Adapters create separate connections to their respective brokers, but currently use the same client ID by default. Because of this, when using a single broker for source and sink, best practice is to explicitly specify their respective MqttClientId

    Example mqtt adapter block:

     mydevice {
     		Protocol = mqtt
     		MqttHost = localhost
     		MqttPort = 1883
     		MqttClientId = myUniqueID
     		Topics = /ingest
     	}

MQTT JSON Ingress Protocol Version 2.0

In general the data format will be {"timestamp": "YYYY-MM-DDThh:mm:ssZ","dataItemId":"value", "dataItemId":{"key1":"value1", ..., "keyn":"valuen}}

NOTE: See the standard for the complete description of the fields for the data item representations below.

A simple set of events and samples will look something like this:

```json
{
   "timestamp": "2023-11-06T12:12:44Z",			//Time Stamp
    "tempId": 22.6,								//Temperature
    "positionId": 1002.345,						//X axis position
    "executionId": "ACTIVE"						//Execution state
}
```

A CONDITION requires the key to be the dataItemId and requires the 6 fields as shown in the example below

```json
{
   "timestamp": "2023-11-06T12:12:44Z",
	"dataItemId": {
	  "level": "fault",
	  "conditionId":"ac324",
	  "nativeSeverity": "1000",
	  "qualifier": "HIGH",
	  "nativeCode": "ABC",
	  "message": "something went wrong"
	}
}
```

A MESSAGE requires the key to be the dataItemId and requires the nativeCode field as shown in the example below

```json
{
   "timestamp": "2023-11-06T12:12:44Z",
	"messsageId": {
	  "nativeCode": "ABC",
	  "message": "something went wrong"
	}
}
```

The TimeSeries REPRESENTATION requires the key to be the dataItemId and requires 2 fields "count" and "values" and 1 to n comma delimited values.
NOTE: The "frequency" field is optional.

```json
{
	"timestamp": "2023-11-06T12:12:44Z",
	"timeSeries1": {
		"count": 10,
		"frequency": 100,
		"values": [1,2,3,4,5,6,7,8,9,10]
	}
}
```

The DataSet REPRESENTATION requires the the dataItemId as the key and the "values" field. It may also have the optional "resetTriggered" field.

```json
{
{
	"timestamp": "2023-11-09T11:20:00Z",
	"dataSetId": {
		"key1": 123,
		"key2": 456,
		"key3": 789
	}
}
```

Example with the optional "resetTriggered" filed:	

```json
{
	"timestamp": "2023-11-09T11:20:00Z",
	"cncregisterset1": {
		"resetTriggered": "NEW",
		"value": {"r1":"v1", "r2":"v2", "r3":"v3" }
	}
}
```

The Table REPRESENTATION requires the the dataItemId as the key and the "values" field. It may also have the optional "resetTriggered" field.

```json

{
	"timestamp":"2023-11-06T12:12:44Z",
	"tableId":{
	  "row1":{
		"cell1":"Some Text",
		"cell2":3243
	  },
	  "row2": {
		"cell1":"Some Other Text",
		"cell2":243        
	  }      
	}
}
```

Example with the optional resetTriggered field:

```json
{
	"timestamp": "2023-11-09T11:20:00Z",
	"a1": {
		"resetTriggered": "NEW",
		"value": {
			"r1": {
				"k1": 123.45,
				"k3": 6789
			},
			"r2": null
		}
	}
}
```



* `AdapterIdentity` - Adapter Identity name used to prefix dataitems within the Agent device ids and names.

    *Default*:
	* If `SuppressIPAddress` == false:\
	`AdapterIdentity` = ```_ {IP}_{PORT}```\
	example:`_localhost_7878`

	* If `SuppressIPAddress` == true:\
	`AdapterIdentity` = ```_ sha1digest({IP}_{PORT})```\
	example: `__71020ed1ed`

MQTT Adapter/Source

  • MqttHost - IP Address or name of the MQTT Broker

    Default: 127.0.0.1

  • MqttPort - Port number of MQTT Broker

    Default: 1883

  • topics - list of topics to subscribe to. Note : Only raw SHDR strings supported at this time

    Required

  • MqttClientId - Client ID used when connecting to the MQTT Broker

    Default: Auto-generated

    ⚠️Note: Mqtt Sinks and Mqtt Adapters create separate connections to their respective brokers, but currently use the same client ID by default. Because of this, when using a single broker for source and sink, best practice is to explicitly specify a distinct MqttClientId for each.

    ⚠️Note: Currently, there is no JSON parser functionality. Agent is expecting a raw SHDR-formatted string

    Example mqtt adapter block:

     mydevice {
     		Protocol = mqtt
     		MqttHost = localhost
     		MqttPort = 1883
     		MqttClientId = myUniqueID
     		Topics = /ingest
     	}

Agent Adapter Configuration

  • Url - The URL of the source agent. http: or https: are accepted for the protocol.

  • SourceDevice – The Device name or UUID for the source of the data

  • Count – the number of items request during a single sample

    Default: 1000

  • Polling Interval – The interval used for streaming or polling in milliseconds

    Default: 500ms

  • Reconnect Interval – The interval between reconnection attampts in milliseconds

    Default: 10000ms

  • Use Polling – Force the adapter to use polling instead of streaming. Only set to true if x-multipart-replace blocked.

    Default: false

  • Heartbeat – The heartbeat interval from the server

    Default: 10000ms

logger_config configuration items

  • logger_config - The logging configuration section.

    • logging_level - The logging level: trace, debug, info, warn, error, or fatal.

      Default: info

      Note: when running Agent with agent debug, logging_level will be set to debug.

    • output - The output file or stream. If using a file, specify as: "file <filename>". cout and cerr can be used to specify the standard output and standard error streams. Defaults to the same directory as the executable.

      Default: file adapter.log

    • max_size - The maximum log file size. Suffix can be K for kilobytes, M for megabytes, or G for gigabytes. No suffix will default to bytes (B). Case is ignored.

      Default: 10M

    • max_index - The maximum number of log files to keep.

      Default: 9

    • schedule - The scheduled time to start a new file. Can be DAILY, WEEKLY, or NEVER.

      Default: NEVER

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.

A simple set of events and samples will look something like this:

2009-06-15T00:00:00.000000|power|ON|execution|ACTIVE|line|412|Xact|-1.1761875153|Yact|1766618937

A line is a sequence of fields separated by |. The simplest requires one key/value pair. The agent will discard any lines where the data is malformed. The end must end with a LF (ASCII 10) or CR-LF (ASCII 15 followed by ASCII 10) (UNIX or Windows conventions respectively). The key will map to the data item using the following items: the id attribute, the name attribute, and the CDATA of the Source element. If the key does not match it will be rejected and the agent will log the first time it fails. Different data items categories and types require a different number of tokens. The following rules specify the requirements for the adapter tokens:

If the value itself contains a pipe character | the pipe must be escaped using a leading backslash \. In addition the entire value has to be wrapped in quotes:

    2009-06-15T00:00:00.000000|description|"Text with \| (pipe) character."

Conditions require six (6) fields as follows:

<timestamp>|<data_item_name>|<level>|<native_code>|<native_severity>|<qualifier>|<message>

Condition id and native code are set to the same value given as <native_code>

<timestamp>|<data_item_name>|<level>|<native_code>:<condition_id>|<native_severity>|<qualifier>|<message>

Condition id is set to condition_id and native code is set to native_code

<timestamp>|<data_item_name>|<level>|<condition_id>|<native_severity>|<qualifier>|<message>

Condition id is set to condition_id and native code is not set

For a complete description of these fields, see the standard. An example line will look like this:

2014-09-29T23:59:33.460470Z|htemp|WARNING|HTEMP-1-HIGH|HTEMP|1|HIGH|Oil Temperature High

The next special format is the Message. There is one additional field, native_code, which needs to be included:

2014-09-29T23:59:33.460470Z|message|CHG_INSRT|Change Inserts

Time series data also gets special treatment, the count and optional frequency are specified. In the following example we have 10 items at a frequency of 100hz:

2014-09-29T23:59:33.460470Z|current|10|100|1 2 3 4 5 6 7 8 9 10

The data item name can also be prefixed with the device name if this adapter is supplying data to multiple devices. The following is an example of a power meter for three devices named device1, device2, and device3:

2014-09-29T23:59:33.460470Z|device1:current|12|device2:current|11|device3:current|10

All data items follow the formatting requirements in the MTConnect standard for the vocabulary and coordinates like PathPosition.

A new feature introduced in version 1.4 is the ability to announce a reset has been triggered. If we have a part count named pcount that gets reset daily, the new protocol is as follows:

2014-09-29T23:59:33.460470Z|pcount|0:DAY

To specify the duration of the static, indicate it with an @ sign after the timestamp as follows:

2014-09-29T23:59:[email protected]|pcount|0:DAY

DATA_SET Representation

A new feature in version 1.5 is the DATA_SET representation which allows for key value pairs to be given. The protocol is similar to time series where each pair is space delimited. The agent automatically removes duplicate values from the stream and allows for addition, deletion and resetting of the values. The format is as follows:

2014-09-29T23:59:33.460470Z|vars|v1=10 v2=20 v3=30

This will create a set of three values. To remove a value

2014-09-29T23:59:33.460470Z|vars|v2 v3=

This will remove v2 and v3. If text after the equal = is empty or the = is not given, the value is deleted. To clear the set, specify a resetTriggered value such as MANUAL or DAY by preceeding it with a colon : at the beginning of the line.

2014-09-29T23:59:33.460470Z|vars|:MANUAL

This will remove all the values from the current set. The set can also be reset to a specific set of values:

2014-09-29T23:59:33.460470Z|vars|:MANUAL v5=1 v6=2

This will remove all the old values from the set and set the current set. Values will accumulate when addition pairs are given as in:

2014-09-29T23:59:33.460470Z|vars|v8=1 v9=2 v5=10

This will add values for v8 and v9 and update the value for v5 to 10. If the values are duplcated they will be removed from the stream unless a resetTriggered value is given.

2014-09-29T23:59:33.460470Z|vars|v8=1 v9=2 v5=0

Will be detected as a duplicate with respect to the previous values and will be removed. If a partial update is given and the other values are duplicates, then will be stripped:

2014-09-29T23:59:33.460470Z|vars|v8=1 v9=3 v5=10

Will be effectively the same as specifying:

2014-09-29T23:59:33.460470Z|vars|v9=2

And the streams will only have the one value when a sample is request is made at that point in the stream.

When the discrete flag is set to true in the data item, all change tracking is ignored and each set is treated as if it is new.

One can quote values using the following methods: "<text>", '<text>', and {<text>}. Spaces and other characters can be included in the text and the matching character can be escaped with a \ if it is required as follows: "hello \"there\"" will yield the value: hellow "there".

TABLE Representation

A TABLE representation is similar to the DATA_SET that has a key value pair as the value. Using the encoding mentioned above, the following representations are allowed for tables:

<timestamp>|wpo|G53.1={X=1.0 Y=2.0 Z=3.0 s='string with space'} G53.2={X=4.0 Y=5.0 Z=6.0} G53.3={X=7.0 Y=8.0 Z=9 U=10.0}

Using the quoting conventions explained in the previous section, the inner content can contain quoted text and exscaped values. The value is interpreted as a key/value pair in the same way as the DATA_SET. A table can be thought of as a data set of data sets.

All the reset rules of data set apply to tables and the values are treated as a unit.

Assets

Assets are associated with a device but do not have a data item they are mapping to. They therefore get the special data item name @ASSET@. Assets can be sent either on one line or multiple lines depending on the adapter requirements. The single line form is as follows:

2012-02-21T23:59:33.460470Z|@ASSET@|KSSP300R.1|CuttingTool|<CuttingTool>...

This form updates the asset id KSSP300R.1 for a cutting tool with the text at the end. For multiline assets, use the keyword --multiline-- with a following unique string as follows:

	2012-02-21T23:59:33.460470Z|@ASSET@|KSSP300R.1|CuttingTool|--multiline--0FED07ACED
	<CuttingTool>
	...
	</CuttingTool>
	--multiline--0FED07ACED

The terminal text must appear on the first position after the last line of text. The adapter can also remove assets (1.3) by sending a @REMOVE_ASSET@ with an asset id:

2012-02-21T23:59:33.460470Z|@REMOVE_ASSET@|KSSP300R.1

Or all assets can be removed in one shot for a certain asset type:

2012-02-21T23:59:33.460470Z|@REMOVE_ALL_ASSETS@|CuttingTool

Partial updates to assets is also possible by using the @UPDATE_ASSET@ key, but this will only work for cutting tools. The asset id needs to be given and then one of the properties or measurements with the new value for that entity. For example to update the overall tool length and the overall diameter max, you would provide the following:

2012-02-21T23:59:33.460470Z|@UPDATE_ASSET@|KSSP300R.1|OverallToolLength|323.64|CuttingDiameterMax|76.211

Commands

There are a number of commands that can be sent as part of the adapter stream. These change some dynamic elements of the device information, the interpretation of the data, or the associated default device. Commands are given on a single line starting with an asterisk * as the first character of the line and followed by a : . They are as follows:

  • Specify the Adapter Software Version the adapter supports:

    * adapterVersion: <version>

  • Set the calibration in the device component of the associated device:

    * calibration: XXX

  • Tell the agent that the data coming from this adapter requires conversion:

    * conversionRequired: <yes|no>

  • Set the description in the device header of the associated device:

    * description: XXX

  • Specify the default device for this adapter. The device can be specified as either the device name or UUID:

    * device: <uuid|name>

  • Tell the agent to load a new device XML model:

    * devicemodel: <deviceXML>

  • Set the manufacturer in the device header of the associated device:

    * manufacturer: XXX

  • Specify the MTConnect Version the adapter supports:

    * mtconnectVersion: <version>

  • Set the nativeName in the device component of the associated device:

    * nativeName: XXX

  • Tell the agent that the data coming from this adapter would like real-time priority:

    * realTime: <yes|no>

  • Tell the agent that the data coming from this adapter is specified in relative time:

    * relativeTime: <yes|no>

  • Set the serialNumber in the device header of the associated device:

    * serialNumber: XXX

  • Specify the version of the SHDR protocol delivered by the adapter. See ShdrVersion above:

    * shdrVersion: <version>

  • Set the station in the device header of the associated device:

    * station: XXX

  • Set the uuid in the device header of the associated device if preserveUuid = false:

    * uuid: XXX

Any other command will be logged as a warning.

Protocol

The agent and the adapter have a heartbeat that makes sure each is responsive to properly handle disconnects in a timely manner. The Heartbeat frequency is set by the adapter and honored by the agent. When the agent connects to the adapter, it first sends a * PING and then expects the response * PONG <timeout> where <timeout> is specified in milliseconds. So if the following communications are given:

Agent:

* PING

Adapter:

* PONG 10000

This indicates that the adapter is expecting a PING every 10 seconds and if there is no PING, in 2x the frequency, then the adapter should close the connection. At the same time, if the agent does not receive a PONG within 2x frequency, then it will close the connection. If no PONG response is received, the agent assumes the adapter is incapable of participating in heartbeat protocol and uses the legacy time specified above.

Just as with the SHDR protocol, these messages must end with an LF (ASCII 10) or CR-LF (ASCII 15 followed by ASCII 10).

HTTP PUT/POST Method of Uploading Data

There are two configuration settings mentioned above: AllowPut and AllowPutFrom. AllowPut alone will allow any process to use HTTP POST or PUT to send data to the agent and modify values. To restrict this to a limited number of machines, you can list the IP Addresses that are allowed to POST data to the agent.

An example would be:

AllowPut = yes
AllowPutFrom = 192.168.1.72, 192.168.1.73

This will allow the two machines to post data to the MTConnect agent. The data can be either data item values or assets. The primary use of this capability is uploading assets from a process or even the command line using utilities like curl. I'll be using curl for these examples.

For example, with curl you can use the -d option to send data to the server. The data will be in standard form data format, so all you need to do is to pass the <data_item_name>=<data_item_value> to set the values, as follows:

curl -d 'avail=AVAILABLE&program_1=XXX' 'http://localhost:5000/ExampleDevice'

By specifying the device at the end of the URL, you tell the agent which device to use for the POST. This will set the availability tag to AVAILABLE and the program to XXX:

<Availability dataItemId="dtop_3" timestamp="2015-05-18T18:20:12.278236Z" name="avail" sequence="65">AVAILABLE</Availability>
...
<Program dataItemId="path_51" timestamp="2015-05-18T18:20:12.278236Z" name="program_1" sequence="66">XXX</Program>

The full raw data being passed over looks like this:

=> Send header, 161 bytes (0xa1)
0000: POST /ExampleDevice HTTP/1.1
001e: User-Agent: curl/7.37.1
0037: Host: localhost:5000
004d: Accept: */*
005a: Content-Length: 29
006e: Content-Type: application/x-www-form-urlencoded
009f: 
=> Send data, 29 bytes (0x1d)
0000: avail=AVAILABLE&program_1=XXX
== Info: upload completely sent off: 29 out of 29 bytes
== Info: HTTP 1.0, assume close after body
<= Recv header, 17 bytes (0x11)
0000: HTTP/1.0 200 OK
<= Recv header, 20 bytes (0x14)
0000: Content-Length: 10
<= Recv header, 24 bytes (0x18)
0000: Content-Type: text/xml
<= Recv header, 2 bytes (0x2)
0000: 
<= Recv data, 10 bytes (0xa)
0000: <success/>
>== Info: Closing connection 0

This is using the --trace - to dump the internal data. The response will be a simple <success/> or <fail/>.

Any data item can be set in this fashion. Similarly conditions are set using the following syntax:

curl -d 'system=fault|XXX|1|LOW|Feeling%20low' 'http://localhost:5000/ExampleDevice'

One thing to note, the data and values are URL encoded, so the space needs to be encoded as a %20 to appear correctly.

<Fault dataItemId="controller_46" timestamp="2015-05-18T18:24:48.407898Z" name="system" sequence="67" nativeCode="XXX" nativeSeverity="1" qualifier="LOW" type="SYSTEM">Feeling Low</Fault>

Assets are posted in a similar fashion. The data will be taken from a file containing the XML for the content. The syntax is very similar to the other requests:

curl -d @B732A08500HP.xml 'http://localhost:5000/asset/B732A08500HP.1?device=ExampleDevice&type=CuttingTool'

The @... uses the named file to pass the data and the URL must contain the asset id and the device name as well as the asset type. If the type is CuttingTool or CuttingToolArchetype, the data will be parsed and corrected if properties are out of order as with the adapter. If the device is not specified and there are more than one device in this adapter, it will cause an error to be returned.

Programmatically, send the data as the body of the POST or PUT request as follows. If we look at the raw data, you will see the data is sent over verbatim as follows:

=> Send header, 230 bytes (0xe6)
0000: POST /asset/B732A08500HP.1?device=ExampleDevice&type=CuttingTool
0040:  HTTP/1.1
004b: User-Agent: curl/7.37.1
0064: Host: localhost:5000
007a: Accept: */*
0087: Content-Length: 2057
009d: Content-Type: application/x-www-form-urlencoded
00ce: Expect: 100-continue
00e4: 
== Info: Done waiting for 100-continue
=> Send data, 2057 bytes (0x809)
0000: (file data sent here, see below...)
== Info: HTTP 1.0, assume close after body
<= Recv header, 17 bytes (0x11)
0000: HTTP/1.0 200 OK
<= Recv header, 20 bytes (0x14)
0000: Content-Length: 10
<= Recv header, 24 bytes (0x18)
0000: Content-Type: text/xml
<= Recv header, 2 bytes (0x2)
0000: 
<= Recv data, 10 bytes (0xa)
0000: <success/>
<success/>== Info: Closing connection 0

The file that was included looks like this:

<CuttingTool serialNumber="1 " toolId="B732A08500HP" timestamp="2011-05-11T13:55:22" assetId="B732A08500HP.1" manufacturers="KMT">
	<Description>
		Step Drill KMT, B732A08500HP Grade KC7315
		Adapter KMT CV50BHPVTT12M375
	</Description>
	<CuttingToolLifeCycle>
		<CutterStatus><Status>NEW</Status></CutterStatus>
		<ProcessSpindleSpeed nominal="5893">5893</ProcessSpindleSpeed>
		<ProcessFeedRate nominal="2.5">2.5</ProcessFeedRate>
		<ConnectionCodeMachineSide>CV50 Taper</ConnectionCodeMachineSide>
		<Measurements>
			<BodyDiameterMax code="BDX">31.8</BodyDiameterMax>
			<BodyLengthMax code="LBX" nominal="120.825" maximum="126.325" minimum="115.325">120.825</BodyLengthMax>
			<ProtrudingLength code="LPR" nominal="155.75" maximum="161.25" minimum="150.26">158.965</ProtrudingLength>
			<FlangeDiameterMax code="DF" nominal="98.425">98.425</FlangeDiameterMax>
			<OverallToolLength nominal="257.35" minimum="251.85" maximum="262.85" code="OAL">257.35</OverallToolLength>
		</Measurements>
		<CuttingItems count="2">
			<CuttingItem indices="1" manufacturers="KMT" grade="KC7315">
				<Measurements>
					<CuttingDiameter code="DC1" nominal="8.5" maximum="8.521" minimum="8.506">8.513</CuttingDiameter>
					<StepIncludedAngle code="STA1" nominal="90" maximum="91" minimum="89">89.8551</StepIncludedAngle>
					<FunctionalLength code="LF1" nominal="154.286" minimum="148.786" maximum="159.786">157.259</FunctionalLength>
					<StepDiameterLength code="SDL1" nominal="9">9</StepDiameterLength>
					<PointAngle code="SIG" nominal="135" minimum="133" maximum="137">135.1540</PointAngle>
				</Measurements>
			</CuttingItem>
			<CuttingItem indices="2" manufacturers="KMT" grade="KC7315">
				<Measurements>
					<CuttingDiameter code="DC2" nominal="12" maximum="12.011" minimum="12">11.999</CuttingDiameter>
					<FunctionalLength code="LF2" nominal="122.493" maximum="127.993" minimum="116.993">125.500</FunctionalLength>
					<StepDiameterLength code="SDL2" nominal="9">9</StepDiameterLength>
				</Measurements>
			</CuttingItem>
		</CuttingItems>
	</CuttingToolLifeCycle>
</CuttingTool>

An example in ruby is as follows:

> require 'net/http'
=> true
> h = Net::HTTP.new('localhost', 5000)
=> #<Net::HTTP localhost:5000 open=false>
> r = h.post('/asset/B732A08500HP.1?type=CuttingTool&device=ExampleDevice', File.read('B732A08500HP.xml'))
=> #<Net::HTTPOK 200 OK readbody=true>
> r.body
=> "<success/>"

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]

Conan MTConnect Options (set using -o <option>=<value>)

  • agent_prefix: Prefix the agent and agent_lib executable. For example -o agent_prefix=mtc create mtcagent.exe and mtcagent_lib.lib

    default: ''

  • cpack: At the end of the build, run cpack to create a deployable package. By default it will go in the build direct, see cpack_destination to change the default location. Values: True or False.

    default: False

  • development: Create a build environment suitable for developemnt. Changes the test_package subdirectory by including it as part of the library build for easier debugging on IDEs and integrated build debug environments. Values: True or False.

    default: False

  • fPIC: Enables Position Independent Code on *NIX platforms allowing the machine code to be dynamically relocate on load. Values: True or False.

    default: True

  • shared: Specifies if the build will create shared libraries (.dll/.so/.dylib) or static libraries. Also makes dependent libraries dynamic as well. Packaging picks up all dependent libraries when creating the ZIP. This is useful when creating plugins since there is less duplication of dependent code. Values: True or False.

    default: False

  • winver: For windows, version of the minimum target operating system version. Defaults to Windows Vista.

    default: 0x600

  • with_docs: Enable generation of MTConnect Agent library documentation using doxygen. If true, will build the use conan to build doxygen if it is not installed. Values: True or False.

    default: False

  • with_ruby: Enable mruby extensions for dynamic scripting. Values: True or False.

    default: True

  • without_ipv6: Disable IPV6 support when building on operating systems that disable IPV6 services. Some docker images disable IPV6. Values: True or False.

    default: False

  • cpack_destination: The destination directory for the package

    default: Package build directory

  • cpack_name: The name of the package generated by cpack

    default: Default package name: agent{version}{OS}

  • cpack_generator:

    default: ZIP for windows and TGZ for *NIX

Conan useful settings (set using -s <setting>=<value>)

  • build_type: Changes the debug or release build type. Values: Release, Debug, RelWithDebInfo, and MinSizeRel. See CMake documentation for explanations.

    default: Release

Conan useful configurations (set using -c <config>=<value>)

  • tools.build:skip_test: Stops conan from running the tests. Test package will still build. To disable tests from building, use -tf "" or --testfolder= to skip the building of tests.

    default: False

  • tools.build:jobs: Sets the number of concurrent processes used in the build. If the machine runs out of resources, reduce the number of concurrent processes.

    default: number of processes

Building on Windows

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

python 3 and Conan Package Manager Downloads

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

You also need git and ruby 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.

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

To build for 64 bit Windows

The following 64 and 32 bit builds will create the zip package in the directory where the repository was cloned. The build will occur in the .conan2 directory of the user's home directory.

Make sure to setup the environment:

"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat"

or

"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
conan create cppagent -pr cppagent/conan/profiles/vs64 --build=missing -o cpack=True -o zip_destination=.

To build for 32 bit Windows

"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars32.bat"

or

"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars32.bat"
conan create cppagent -pr cppagent/conan/profiles/vs32 --build=missing -o cpack=True -o zip_destination=.

*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 command line option:

-c tools.build:jobs=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

sudo apt install -y build-essential cmake gcc-11 g++-11 python3 python3-pip autoconf automake ruby ruby rake 
python3 -m pip install conan
echo 'export PATH=$HOME/.local/bin:$PATH' >> .bashrc

Download the source

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

Build the agent

conan create cppagent -pr cppagent/conan/profiles/gcc --build=missing

Building on Mac OS

Install brew and xcode command line tools

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
xcode-select —install

Setup the build

brew install git
brew install cmake
pip3 install conan

Download the source

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

Build the agent

conan create cppagent -pr cppagent/conan/profiles/macos --build=missing

Generate an xcode project for debugging

conan build . -pr conan/profiles/xcode -s build_type=Debug --build=missing -o development=True

Building on Fedora Alpine

As Root

apk add g++ python3 cmake git linux-headers make perl ruby
gem install rake

python3 -m ensurepip
python3 -m pip install --upgrade pip

As the user

export PATH=~/.local/bin:$PATH
pip3 install conan	
git clone https://github.com/mtconnect/cppagent.git

Build the agent

conan create cppagent -pr cppagent/conan/profiles/gcc --build=missing

For some examples, see the CI/CD workflows in .github/workflows/build.yml

Creating Test Certifications (see resources gen_certs shell script)

This section assumes you have installed openssl and can use the command line. The subject of the certificate is only for testing and should not be used in production. This section is provided to support testing and verification of the functionality. A certificate provided by a real certificate authority should be used in a production process.

NOTE: The certificates must be generated with OpenSSL version 1.1.1 or later. LibreSSL 2.8.3 is not compatible with more recent version of SSL on raspian (Debian).

Server Creating self-signed certificate chain

Create Signing authority key and certificate

openssl req -x509 -nodes -sha256 -days 3650 -newkey rsa:3072 -keyout rootca.key -out rootca.crt -subj "/C=US/ST=State/L=City/O=Your Company, Inc./OU=IT/CN=serverca.org"

User Key

openssl genrsa -out user.key 3072

Signing Request

openssl req -new -sha256 -key user.key -out user.csr -subj "/C=US/ST=State/L=City/O=Your Company, Inc./OU=IT/CN=user.org"

User Certificate using root signing certificate

openssl x509 -req -in user.csr -CA rootca.crt -CAkey rootca.key -CAcreateserial -out user.crt -days 3650

Create DH Parameters

openssl dhparam -out dh2048.pem 3072

Verify

openssl verify -CAfile rootca.crt rootca.crt
openssl verify -CAfile rootca.crt user.crt

Client Certificate

Create Signing authority key

openssl req -x509 -nodes -sha256 -days 3650 -newkey rsa:3072 -keyout clientca.key -out clientca.crt -subj "/C=US/ST=State/L=City/O=Your Company, Inc./OU=IT/CN=clientca.org"

Create client key

openssl genrsa -out client.key 3072

Create client signing request

openssl req -new -key client.key -out client.csr -subj "/C=US/ST=State/L=City/O=Your Company, Inc./OU=IT/CN=client.org"

Create Client Certificate

For client.cnf

basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection

Create the cert

openssl x509 -req -in client.csr -CA clientca.crt -CAkey clientca.key -out client.crt -CAcreateserial -days 3650 -sha256 -extfile client.cnf

Verify

openssl verify -CAfile clientca.crt clientca.crt
openssl verify -CAfile clientca.crt client.crt

Docker

See demo or docker

cppagent's People

Contributors

bburns avatar bcampbell-ts avatar codenamesubho avatar dwickelhaus avatar ellisware avatar gayak avatar intolerance avatar jaxer avatar johnathan-arsenault avatar johnmichaloski avatar lorenzhaas avatar masonhieb avatar matthewpowley avatar mnoomnoo avatar ottobolyos avatar rajwork9 avatar robot-ranger avatar russwaddell avatar rwuthric avatar scottmwyant avatar shaurabhsingh avatar simonyg avatar simonyg-nv avatar skibum1869 avatar wsobel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cppagent's Issues

Can't build my MTConnect agent

Hi,

I'm not a regular programmer. I tried to set up the MTConnect agent on my PC (Win7 SP1) but it bugged at the building process (Visual Studio 2010). Below is an excerpt of the output (in french).

Am I missing something ?

Serge

1>------ Début de la génération : Projet : ZERO_CHECK, Configuration : Release Win32 ------
1>La génération a démarré 2016-02-23 09:46:10.
1>PrepareForBuild:
1> Création du répertoire "C:\cppagent\build\Release".
1>InitializeBuildStatus:
1> Création de "Win32\Release\ZERO_CHECK\ZERO_CHECK.unsuccessfulbuild", car "AlwaysCreate" a été spécifié.
1>CustomBuild:
1> Checking Build System
1> CMake does not need to re-run because C:/cppagent/build/CMakeFiles/generate.stamp is up-to-date.
1> CMake does not need to re-run because C:/cppagent/build/agent/CMakeFiles/generate.stamp is up-to-date.
1> CMake does not need to re-run because C:/cppagent/build/test/CMakeFiles/generate.stamp is up-to-date.
1>FinalizeBuildStatus:
1> Suppression du fichier "Win32\Release\ZERO_CHECK\ZERO_CHECK.unsuccessfulbuild".
1> Mise à jour de l'horodatage "Win32\Release\ZERO_CHECK\ZERO_CHECK.lastbuildstate".
1>
1>La génération a réussi.
1>
1>Temps écoulé 00:00:00.06
2>------ Début de la génération : Projet : UPDATE_VERSION, Configuration : Release Win32 ------
3>------ Génération ignorée : Projet : agent_test, Configuration : Release Win32 ------
3>Projet non sélectionné dans le cadre d'une génération pour cette configuration de solution
4>------ Génération ignorée : Projet : cov, Configuration : Release Win32 ------
4>Projet non sélectionné dans le cadre d'une génération pour cette configuration de solution
2>La génération a démarré 2016-02-23 09:46:11.
2>InitializeBuildStatus:
2> Création de "Win32\Release\UPDATE_VERSION\UPDATE_VERSION.unsuccessfulbuild", car "AlwaysCreate" a été spécifié.
2>CustomBuild:
2> Building Custom Rule C:/cppagent/agent/CMakeLists.txt
2> CMake does not need to re-run because C:\cppagent\build\agent\CMakeFiles\generate.stamp is up-to-date.
2>FinalizeBuildStatus:
2> Suppression du fichier "Win32\Release\UPDATE_VERSION\UPDATE_VERSION.unsuccessfulbuild".
2> Mise à jour de l'horodatage "Win32\Release\UPDATE_VERSION\UPDATE_VERSION.lastbuildstate".
2>
2>La génération a réussi.
2>
2>Temps écoulé 00:00:00.06
5>------ Début de la génération : Projet : agent, Configuration : Release Win32 ------
5>La génération a démarré 2016-02-23 09:46:11.
5>PrepareForBuild:
5> Création du répertoire "C:\cppagent\build\agent\Release".
5>InitializeBuildStatus:
5> Création de "agent.dir\Release\agent.unsuccessfulbuild", car "AlwaysCreate" a été spécifié.
5>CustomBuild:
5> Building Custom Rule C:/cppagent/agent/CMakeLists.txt
5> CMake does not need to re-run because C:\cppagent\build\agent\CMakeFiles\generate.stamp is up-to-date.
5>ClCompile:
5> cppagent.cpp
5> adapter.cpp
5> asset.cpp
5> agent.cpp
5> checkpoint.cpp
5> component.cpp
5> component_event.cpp
5> change_observer.cpp
5> connector.cpp
5> cutting_tool.cpp
5> data_item.cpp
5> device.cpp
5> globals.cpp
5> options.cpp
5> service.cpp
5>....\agent\service.cpp(83): warning C4995: 'gets' : le nom a été marqué comme #pragma deprecated
5>....\agent\service.cpp(437): warning C4995: '_snprintf' : le nom a été marqué comme #pragma deprecated
5> config.cpp
5> ref_counted.cpp
5> version.cpp
5> xml_parser.cpp
5> xml_printer.cpp
5> Génération de code en cours...
5> Compilation en cours...
5> rolling_file_logger.cpp
5> Génération de code en cours...
5>xml_parser.obj : warning LNK4217: symbole défini localement _xmlFree importé dans la fonction "public: void __thiscall XmlParser::getDataItems(class std::set<class std::basic_string<char,struct std::char_traits,class std::allocator >,struct std::less<class std::basic_string<char,struct std::char_traits,class std::allocator > >,class std::allocator<class std::basic_string<char,struct std::char_traits,class std::allocator > > > &,class std::basic_string<char,struct std::char_traits,class std::allocator > const &,struct _xmlNode *)" (?getDataItems@XmlParser@@QAEXAAV?$set@V?$basic_string@DU?$char_traits@D@std@@v?$allocator@D@2@@std@@U?$less@V?$basic_string@DU?$char_traits@D@std@@v?$allocator@D@2@@std@@@2@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@v?$allocator@D@2@@std@@@2@@std@@abv?$basic_string@DU?$char_traits@D@std@@v?$allocator@D@2@@3@PAU_xmlNode@@@z)
5>xml_printer.obj : warning LNK4049: symbole défini localement _xmlFree importé
5>libxml2_a_v120_32.lib(nanoftp.obj) : error LNK2001: symbole externe non résolu ___report_rangecheckfailure
5>libxml2_a_v120_32.lib(xmlschemas.obj) : error LNK2001: symbole externe non résolu ___report_rangecheckfailure
5>libxml2_a_v120_32.lib(HTMLparser.obj) : error LNK2001: symbole externe non résolu ___report_rangecheckfailure
5>libxml2_a_v120_32.lib(encoding.obj) : error LNK2001: symbole externe non résolu ___report_rangecheckfailure
5>libxml2_a_v120_32.lib(catalog.obj) : error LNK2001: symbole externe non résolu ___report_rangecheckfailure
5>libxml2_a_v120_32.lib(debugXML.obj) : error LNK2019: symbole externe non résolu ___report_rangecheckfailure référencé dans la fonction _xmlCtxtDumpAttrDecl
5>libxml2_a_v120_32.lib(tree.obj) : error LNK2001: symbole externe non résolu ___report_rangecheckfailure
5>libxml2_a_v120_32.lib(parser.obj) : error LNK2001: symbole externe non résolu ___report_rangecheckfailure
5>libxml2_a_v120_32.lib(error.obj) : error LNK2001: symbole externe non résolu ___report_rangecheckfailure
5>libxml2_a_v120_32.lib(xpath.obj) : error LNK2001: symbole externe non résolu ___report_rangecheckfailure
5>libxml2_a_v120_32.lib(xpath.obj) : error LNK2019: symbole externe non résolu __dclass référencé dans la fonction _trio_fpclassify_and_signbit
5>libxml2_a_v120_32.lib(xpath.obj) : error LNK2019: symbole externe non résolu __dsign référencé dans la fonction _trio_fpclassify_and_signbit
5>libxml2_a_v120_32.lib(xpath.obj) : error LNK2019: symbole externe non résolu __libm_sse2_log10_precise référencé dans la fonction _xmlXPathFormatNumber
5>libxml2_a_v120_32.lib(xpath.obj) : error LNK2019: symbole externe non résolu __libm_sse2_pow_precise référencé dans la fonction _xmlXPathCompNumber
5>libxml2_a_v120_32.lib(xmlschemastypes.obj) : error LNK2019: symbole externe non résolu __dtoui3 référencé dans la fonction __xmlSchemaDateAdd
5>C:\cppagent\build\agent\Release\agent.exe : fatal error LNK1120: 6 externes non résolus
5>
5>ÉCHEC de la build.
5>
5>Temps écoulé 00:00:32.61
6>------ Début de la génération : Projet : ALL_BUILD, Configuration : Release Win32 ------
6>La génération a démarré 2016-02-23 09:46:43.
6>InitializeBuildStatus:
6> Création de "Win32\Release\ALL_BUILD\ALL_BUILD.unsuccessfulbuild", car "AlwaysCreate" a été spécifié.
6>CustomBuild:
6> Building Custom Rule C:/cppagent/CMakeLists.txt
6> CMake does not need to re-run because C:\cppagent\build\CMakeFiles\generate.stamp is up-to-date.
6>FinalizeBuildStatus:
6> Suppression du fichier "Win32\Release\ALL_BUILD\ALL_BUILD.unsuccessfulbuild".
6> Mise à jour de l'horodatage "Win32\Release\ALL_BUILD\ALL_BUILD.lastbuildstate".
6>
6>La génération a réussi.
6>
6>Temps écoulé 00:00:00.07
7>------ Génération ignorée : Projet : INSTALL, Configuration : Release Win32 ------
7>Projet non sélectionné dans le cadre d'une génération pour cette configuration de solution
========== Génération : 3 a réussi, 1 a échoué, 0 mis à jour, 3 a été ignoré ==========

Data items reported at the same time stamp?

I have seen that data items reported at the same time stamp however agent will send out each data item in different sequence number with the same time stamp.
Because related data items are reported in different sequence numbers it is possible that an application will miss interpret data due to this.
Ex: Spindle Surface speed and Mode
An application might get the spindle surface speed but not mode at the same time due to different sequence number. As a result the application might think the spindle surface speed is in the current mode but it is actually already changed.

Is this an issue?

Thanks

___report_rangecheckfailure unresolved external

I tried to upgrade the C++ agent code (since agent was hanging/dieing when I stopped the service - very hard to debug) and I downloaded the latest github etc. Compiled ok, but linking - not so good. Libxml xxx.obj had a bunch of buffer overrun unresolved external errors.

I am using MSVC 2010, and the above unresolved external may be from libxml compiling with MSVC 2012. Is there any other recourse besides upgrading to 2012 (or using gnu)?

Is this correct?

Using MTConnect with LinuxCNC/MachineKit

Hi all!

I am working on a project where I need to connect LinuxCNC with MTConnect. I was able to build the agent with the help of the documentation on mtcup.org on my BeagleBone running linux. The beaglebone is running machinekit, which as far as I know is a fork of linuxCNC.

I found an adapter for EMC2 online here: https://github.com/athulan/adapter

However, I have the following 3 questions/problems/issues:

  1. I don't know how to connect an adapter with an agent? I see a lot of adapters with .cpp and .hpp files but I have no idea on how to use them. This is more of a generic problem. I have a computer with the build agent on it. Where should the adapter reside? Should it be in the computer running the CNC machine? Or should it be on my computer which has the agent? And how do I connect both of them? I am unable to find any detailed instructions on doing so.
  2. I tried the "make" command after navigating to the folder containing the adapter for EMC in my Beaglebone and it threw a "fatal error" saying a file called rcs.hh was missing. Can anyone help out with this?
  3. Is it even possible to run MTConnect on machinekit?

I am not a programmer ,unfortunately. Any help would be appreciated.

Thanks a lot for your time.

POST for undefined data items should report an error, not just log a warning

When POSTing a data item, if the data item is not defined a success response and a body of is returned to the sender.

Ideally the http status code would have an error. But at least the body should have the (oh so painful to parse) MTConnectError.

wrt to the status code, posting to invalid device name would also ideally return a status code error, not success.

Error during 'make' on ubuntu

Hej,

I tried to build the agent for linux (ubuntu 32 & 64 bit, 12.04 and 12.10) but I was not able to do it :-(

Here is my log: The cmake . looks fine:

arne@ubuntu:~/cppagent$ cmake .
-- The C compiler identification is GNU 4.7.2
-- The CXX compiler identification is GNU 4.7.2
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Found libxml2: /usr/lib/x86_64-linux-gnu/libxml2.so
-- Found CppUnit: /usr/lib/libcppunit.so
-- Found libxml2: /usr/lib/x86_64-linux-gnu/libxml2.so
-- Configuring done
-- Generating done
-- Build files have been written to: /home/arne/cppagent

But the make command:

arne@ubuntu:~/cppagent$ make
Scanning dependencies of target UPDATE_VERSION
[  0%] Built target UPDATE_VERSION
Scanning dependencies of target agent
[  1%] Building CXX object agent/CMakeFiles/agent.dir/cppagent.cpp.o
[  3%] Building CXX object agent/CMakeFiles/agent.dir/adapter.cpp.o
[  5%] Building CXX object agent/CMakeFiles/agent.dir/asset.cpp.o
[  7%] Building CXX object agent/CMakeFiles/agent.dir/agent.cpp.o
[  8%] Building CXX object agent/CMakeFiles/agent.dir/checkpoint.cpp.o
[ 10%] Building CXX object agent/CMakeFiles/agent.dir/component.cpp.o
[ 12%] Building CXX object agent/CMakeFiles/agent.dir/component_event.cpp.o
[ 14%] Building CXX object agent/CMakeFiles/agent.dir/change_observer.cpp.o
[ 16%] Building CXX object agent/CMakeFiles/agent.dir/connector.cpp.o
[ 17%] Building CXX object agent/CMakeFiles/agent.dir/cutting_tool.cpp.o
[ 19%] Building CXX object agent/CMakeFiles/agent.dir/data_item.cpp.o
[ 21%] Building CXX object agent/CMakeFiles/agent.dir/device.cpp.o
[ 23%] Building CXX object agent/CMakeFiles/agent.dir/globals.cpp.o
/home/arne/cppagent/agent/globals.cpp: In function ‘std::string getCurrentTime(TimeFormat)’:
/home/arne/cppagent/agent/globals.cpp:124:66: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘__suseconds_t {aka long int}’ [-Wformat]
[ 25%] Building CXX object agent/CMakeFiles/agent.dir/options.cpp.o
[ 26%] Building CXX object agent/CMakeFiles/agent.dir/service.cpp.o
/home/arne/cppagent/agent/service.cpp: In function ‘void cleanup_pid()’:
/home/arne/cppagent/agent/service.cpp:589:26: error: ‘unlink’ was not declared in this scope
/home/arne/cppagent/agent/service.cpp: In member function ‘void MTConnectService::daemonize()’:
/home/arne/cppagent/agent/service.cpp:596:14: error: ‘getppid’ was not declared in this scope
/home/arne/cppagent/agent/service.cpp:598:10: error: ‘fork’ was not declared in this scope
/home/arne/cppagent/agent/service.cpp:606:10: error: ‘setsid’ was not declared in this scope
/home/arne/cppagent/agent/service.cpp:609:10: error: ‘close’ was not declared in this scope
/home/arne/cppagent/agent/service.cpp:617:8: error: ‘dup’ was not declared in this scope
/home/arne/cppagent/agent/service.cpp:631:30: error: ‘getpid’ was not declared in this scope
/home/arne/cppagent/agent/service.cpp:632:30: error: ‘write’ was not declared in this scope
make[2]: *** [agent/CMakeFiles/agent.dir/service.cpp.o] Error 1
make[1]: *** [agent/CMakeFiles/agent.dir/all] Error 2
make: *** [all] Error 2
arne@ubuntu:~/cppagent$ 

I don't have that much c++ and unix knowledge to fix that for my own, maybe you know what I'm doing wrong?

Thanks

agent crashed when first connected with adapter

no problem with previous release 1.3.0.7

agent debug output:

D:\Program files\Okuma\OKUMA MT Connect Adapter>agent debug
MTConnect Agent Version 1.3.0.8 - built on Wed Oct 29 10:08:16 2014
0 INFO [0] init.config: Starting agent on port 5000
16 WARN [0] init.config: Cannot locate device name 'OKUMA.Machine.Adapter',
trying default
16 INFO [0] init.config: Adding adapter for OKUMA.Machine.Adapter on localho
st:7878
16 DEBUG [0] agent: registerFile: Path ../styles/favicon.ico is not a directo
ry: Unable to find directory ../styles/favicon.ico, trying as a file
32 ERROR [0] agent: Cannot register file: ../styles/favicon.ico: Unable to fi
nd file ../styles/favicon.ico
32 DEBUG [1] input.connector: Connecting to data source: localhost on port: 7
878
47 DEBUG [1] input.connector: Sending initial PING
63 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
63 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
63 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
78 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
78 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
78 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
78 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
78 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
94 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
94 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
94 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
94 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
94 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
110 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
110 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
110 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
110 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
110 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
125 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
125 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
125 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
125 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
141 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
141 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
141 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
141 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
156 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
156 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
156 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
156 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
156 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
172 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
172 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
172 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
172 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
172 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
172 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
188 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
188 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
188 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
188 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
188 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
203 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
203 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
203 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter
219 DEBUG [1] input.adapter: Could not find device: OKUMA.Machine.Adapter

D:\Program files\Okuma\OKUMA MT Connect Adapter>

ToolAssetId

It seems there is an issue with this tag. I cannot clear after tool is removed.
Here are the data sent from adapter:
Date:9/26/2014 Time:8:09:02 AM Tracing - Sampling/Event Data Items: 2014-09-26T12:09:00.5326175Z|p1CurrentTool|71893832

Date:9/26/2014 Time:8:09:02 AM Tracing - Sampling/Event Data Items: 2014-09-26T12:09:02.5888231Z|@asset@|XXX.71893832|CuttingTool|--multiline--ABCD
0AVAILABLE071893832
--multiline--ABCD

Date:9/26/2014 Time:8:09:02 AM Tracing - Sampling/Event Data Items: 2014-09-26T12:09:02.7678410Z|p1ToolAssetId|XXX.71893832

agent reports correctly for the current tool = 71893832

Date:9/26/2014 Time:8:09:12 AM Tracing - Sampling/Event Data Items: 2014-09-26T12:09:12.0517693Z|p1CurrentTool||p1ToolAssetId|

Date:9/26/2014 Time:8:09:12 AM Tracing - Sampling/Event Data Items: 2014-09-26T12:09:02.5888231Z|@REMOVE_ASSET@|XXX.71893832

When the current tool is removed from the asset agent still report the current ToolAssetId which does not exist in Tool Assets any more.

Thanks

Mtconnect Agent Build Errors

I am trying to Build an agent on a windows 7 sp1 pc with Visual Studio 2015 community, and I can not get past a few error problems. I can configure and generate in cmake program but when to building the solution in visual studio 2015 and it generates errors. I have tried this with version 1.3.0.16 and 1.2.0.23 and have the same result. Is my computer being the hold up? Here are the error I am Getting.

Thank you for your time,
Jason Van Den Top

Severity Code Description Project File Line Suppression State

Error C3861 'gets': identifier not found agent_test C:\MTConnect\cppagent-1.3.0.16\agent\service.cpp 83
Error C2065 'timezone': undeclared identifier agent C:\MTConnect\cppagent-1.3.0.16\agent\globals.cpp 241
Error C3861 'gets': identifier not found agent C:\MTConnect\cppagent-1.3.0.16\agent\service.cpp 83
Error C2065 'timezone': undeclared identifier agent_test C:\MTConnect\cppagent-1.3.0.16\agent\globals.cpp 241

Agent is not responding to simulator.

Running Agent version 1.3.0.14
[subho@localhost] agent $ (master) ./agent
MTConnect Agent Version 1.3.0.14 - built on Wed Apr 1 19:47:51 2015

Running simulator,
[subho@localhost] simulator $ (master) ruby run_scenario.rb -l -p 7878 --scenario -v simple_scenario_1.txt
run_scenario.rb:41: warning: toplevel constant String referenced by OptionParser::String
Waiting on 0.0.0.0 7878

The simulator keeps waiting for the agent.
The same simulator works fine with Agent version 1.3.0.13.

Asset/Assets Command

It seems that I can issue "asset" command to the agent and I can get all tool assets as "assets" command.

Is this by design?

Thanks

assetCount bug?

assetCount does not clear after all assets have been removed.

Streaming, interval=0

Hey,

I have a problem to separate the payload an the header with curl, when "streaming" with the interval=0 attribute is active.

curl "agent.mtconnect.org/sample?interval=0"

example Header:

--29c661e7866fd61fe7d26de8a9a4813c
Content-type: text/xml
Content-length: 15779

is there an option to suppress those header output?

Normally, the header and body is separated with \n\r\n\n but in some cases it's not and I have to do a lot of workarounds to separate the xml from the header.

Is this related to the https://en.wikipedia.org/wiki/MIME#Mixed-Replace ? Maybe you have an idea for me :)

sample does not report same value as current?

It seems that there is an issue with sample command.
Sample command cannot report the current condition of the system type correctly as current command.

When the machine is first started and has no alarm I expect the condition of the system is Normal but it is not if using Sample command.
Current command does show the correct state.
Sample Command output from sequence 1 to the last sequence:


UNAVAILABLE
ARMED




It seems it cannot report sequence 110 for the Condition in Sample command

Current command output from sequence 1 to the last sequence:


ARMED




Thanks

view-source_localhost_5000_from=1&to=110.zip

Unable to remove/hide asset

The corresponding asset isn't being removed/hidden when the agent receives the following from an adapter: adapter output

After some digging I was able to figure out that the asset wasn't being removed because the assetId the agent was using as the search-key had a CR at the end which doesn't match the stored key.

github-remove asset issue cropped

Specifying multiple agent port numbers from one instance and Devices.xml template

Hi,

I'm curious how to specify multiple agent output port numbers. I'm assuming that you query the particular device by specifying (In my case) http://localhost:5000/[DEVICE-NAME], however, I want a unique agent port number for each device within one instance of the application. In the .cfg file, it seems that there is only one place for the output port number (Port 5000 in the following example):

Devices = ../devices/ExampleDevices1.xml
Port = 5000
AllowPut = true
ReconnectInterval = 10000
BufferSize = 17
SchemaVersion = 1.3
Adapters { 
   Example1 { 
      Host = 127.0.0.1
      Port = 7878
   } 
}

Also, I'm curious if there's a way to use the Devices.xml as a kind of template:

        <Devices>
		<Device sampleInterval="10" name="Example" iso841Class="1" uuid="EX" id="device1">
			<Description manufacturer="Example" serialNumber="Serial Number"></Description>
			<DataItems>
				<DataItem category="EVENT" id="avail1" name="avail" type="AVAILABILITY"></DataItem>
			</DataItems>
			<Components>
				<Rotary id="c1" name="C">
					<DataItems>
						<DataItem category="SAMPLE" id="c3" name="Sovr" nativeUnits="PERCENT" subType="OVERRIDE" type="SPINDLE_SPEED" units="PERCENT">
							<Source>speed_ovr</Source>
						</DataItem>
					</DataItems>
				</Rotary>
				<Controller name="Controller" id="ctrl1">
					<DataItems>
						<DataItem category="EVENT" id="msg" type="MESSAGE"/>
						<DataItem category="EVENT" id="estop" type="EMERGENCY_STOP"/>
					</DataItems>
					<Components>
						<Path id="pth" name="path">
							<DataItems>
								<DataItem category="EVENT" id="blk1" name="block" type="BLOCK"/>
								<DataItem category="EVENT" id="execute1" name="execution" type="EXECUTION"/>
								<DataItem category="EVENT" id="md1" name="mode" type="CONTROLLER_MODE"/>
								<DataItem category="EVENT" id="prgm1" name="program" type="PROGRAM"/>
								<DataItem category="EVENT" id="ln1" name="line" type="LINE"/>            
								<DataItem category="SAMPLE" id="Fovr" nativeUnits="PERCENT" type="PATH_FEEDRATE" units="PERCENT">
									<Source>feed_ovr</Source>
								</DataItem>
								<DataItem category="SAMPLE" id="Rovr" nativeUnits="PERCENT" type="RAPID_FEEDRATE" units="PERCENT">
									<Source>rapid_ovr</Source>
								</DataItem>
							</DataItems>
						</Path>
					</Components>
				</Controller>        
			</Components>
		</Device>
	</Devices>

In this example, I want to save the work of copying and pasting an identical XML tree, just changing the name, id, and uuid. I know that specifying for each device gives more control, but I was just curious.

Devices XML multiple paths

Not sure where to leave this question, as I think it is a problem with understanding how to set the devices.xml for this machine, but I can't find any examples that work. The machine has a main spindle and a sub spindle. I have been able to get one or the other and the other one will say "UNAVAILABLE".

I thought I would use BLOCK, since it comes up quickly to test changes to the xml.

Below is from the Agent debug screen, which indicates that both block and block2 are available.

184174 WARN [1] input.adapter: (Tsugami_01) Could not find data item: path_feedrate from line '2014
-11-10T18:39:19.659Z|tool_id|808|line|8|block|N8T0808(RF123G067-10B-S 3MM CUTOFF)|path_feedrate|0|path_position|4.4300400000 0.0000000000 -0.3905100000|Xact|-3e-005|Xload|9|Zact|12.05742|Zload|227|Yact|6.10767|Yload|30|S1speed|1848|S1load|9|S3speed|1848|S3load|32|block2|M78 |Zload|6|S22speed|51'

The xml that I was expecting to work is:


  <Devices>
    <Device id="dev01" iso841Class="6" name="Tsugami_01" sampleInterval="50" uuid="001">
        <Description manufacturer="Fanuc"/>
      <DataItems>
        <DataItem category="EVENT" id="avail_01" name="avail" type="AVAILABILITY"/>
      </DataItems>
        <Components>
            <Controller name="Controller" id="cont">
              <DataItems>
                <DataItem category="EVENT" id="mode_01" name="mode" type="CONTROLLER_MODE"/>
                <DataItem category="EVENT" id="estop_01" name="estop" type="EMERGENCY_STOP"/>
                <DataItem category="EVENT" id="message_01" name="message" type="MESSAGE"/>
               <DataItem category="EVENT" id="part_count_01" name="part_count" type="PART_COUNT"/>
              </DataItems>
            <Components>
             <Path id="pth_main" name="Main_Spindle">
              <DataItems>
                <DataItem category="EVENT" id="program_01" name="program" type="PROGRAM"/>
                <DataItem category="EVENT" id="program_comment_01" name="program_comment" type="PROGRAM_COMMENT"/>
                <DataItem category="EVENT" id="execution_01" name="execution" type="EXECUTION"/>
                <DataItem category="EVENT" id="line_01" name="line" type="LINE"/>
               <DataItem category="EVENT" id="block_01" name="block" type="BLOCK" />
                <DataItem category="EVENT" id="system_01" name="system" type="SYSTEM" />
              </DataItems>
            </Path>
            <Path id="pth_sub" name="Sub_Spindle">
              <DataItems>
                <DataItem category="EVENT" id="program_01_sub" name="program_sub" type="PROGRAM2"/>
                <DataItem category="EVENT" id="program_comment_01_sub" name="program_comment_sub" type="PROGRAM_COMMENT2"/>
                <DataItem category="EVENT" id="execution_01_sub" name="execution_sub" type="EXECUTION2"/>
                <DataItem category="EVENT" id="line_01_sub" name="line_sub" type="LINE2"/>
               <DataItem category="EVENT" id="block_01_sub" name="block_sub" type="BLOCK2" />
                <DataItem category="EVENT" id="system_01_sub" name="system_sub" type="SYSTEM2" />
              </DataItems>
            </Path>
                </Components>
             </Controller>
        </Components>
    </Device>

...

Anyone have any ideas what I am missing?

XML Client from Agent

I am attempting to make a client in Visual Studio 2013 in vb.net. When I read it with the following code:

    Dim sAPIUrl As String = "http://localhost:5000/current?path=//Controller|//Power"
    Dim oDocument As XDocument = XDocument.Load(sAPIUrl)
    Dim sEstop = From Ev In oDocument...<Events> _
                 Select New MTEvents With {.EmergencyStop = Ev.<EmergencyStop>.Value, .Message = Ev.<Message>.Value}
    For Each ev In sEstop
        Console.WriteLine("Emergency Stop Status is {0}.", ev.EmergencyStop)
        Console.WriteLine("Message is ""{0}""", ev.Message)
    Next

It would not function, so I copied the XML code from the browser from my agent and attempted to manipulate it until I could get results. When I removed the reference to the XML schema, it would then give me the information from the xml file. I attempted to update the devices.xml file without the reference to the xml schema, it was still putting it in. I found something in the source code of the cppagent that was causing this, so I am thinking that the xml schema is correct. As shown in the picture, Visual Studio doesn't like the xsi. Anyone have any ideas on what I am missing?

So the xml that I used is (after removing the xsi:schemalocation...):

xmldata

MTConnect CPP Agent on LinuxCNC(PocketNC)

Hi everyone

New to programming here so any help would be much appreciated.

I am trying to deploy the MTConnect CPP agent on a LinuxCNC machine (a PocketNC to be precise). I am following everything from this link for building the agent on an Ubuntu based machine. (http://mtcup.org/wiki/Installing_C%2B%2B_Agent_on_Ubuntu).

However, after executing the "make" command, I am having an error as follows:


[ 1%] Building CXX object agent/CMakeFiles/agent.dir/cppagent.cpp.o
In file included from /home/pocketnc/agent/cppagent/agent/adapter.hpp:29:0,
from /home/pocketnc/agent/cppagent/agent/agent.hpp:31,
from /home/pocketnc/agent/cppagent/agent/cppagent.cpp:17:
/home/pocketnc/agent/cppagent/agent/connector.hpp:98:22: error: ISO C++ forbids initialization of member 'mHeartbeats' [-fpermissive]
/home/pocketnc/agent/cppagent/agent/connector.hpp:98:22: error: making 'mHeartbeats' static [-fpermissive]
/home/pocketnc/agent/cppagent/agent/connector.hpp:98:22: error: ISO C++ forbids in-class initialization of non-const static member 'mHeartbeats'
/home/pocketnc/agent/cppagent/agent/connector.hpp:99:29: error: ISO C++ forbids initialization of member 'mHeartbeatFrequency' [-fpermissive]
/home/pocketnc/agent/cppagent/agent/connector.hpp:99:29: error: making 'mHeartbeatFrequency' static [-fpermissive]
/home/pocketnc/agent/cppagent/agent/connector.hpp:99:29: error: ISO C++ forbids in-class initialization of non-const static member 'mHeartbeatFrequency'
/home/pocketnc/agent/cppagent/agent/connector.hpp:100:24: error: ISO C++ forbids initialization of member 'mLegacyTimeout' [-fpermissive]
/home/pocketnc/agent/cppagent/agent/connector.hpp:100:24: error: making 'mLegacyTimeout' static [-fpermissive]
/home/pocketnc/agent/cppagent/agent/connector.hpp:100:24: error: ISO C++ forbids in-class initialization of non-const static member 'mLegacyTimeout'
make[2]: *** [agent/CMakeFiles/agent.dir/cppagent.cpp.o] Error 1
make[1]: *** [agent/CMakeFiles/agent.dir/all] Error 2
make: *** [all] Error 2


I understand, there is an error in making the mHeartbeats file but at this point am totally clueless as to how to get around this issue. Could anyone help me in this? Thank you!

program header characters?

I sent the following characters from part program header to agent but agent only reports some as shown below:

Adapter data:
p1ProgramHeader|(Comment: <>!@#$%^&`{}|:"<>?[];',./)|(second comment line)|(SPECIAL !@#$%^&)|

Agent data:
(Comment: <>~!@#$%^&*`{}

Agent drops everything after these characters:
(Comment: <>~!@#$%^&*`{}

Thanks

Some cppagent Event values are blank on change

I have a small adapter which is able to change some Event MESSAGE values, but for others the cppagent sets them to blank.. The configuration for both in my Devices.xml looks identical. I have confirmed that my adapter is sending out the changes correctly. When the adapter first connects, all the values are correct. But when I send out a change, certain become blank.
Here is a picture of the partial output in my browser right after connecting my adapter.
mach500events1b

Here is a picture of the output after I changed the System.State to ESTOP. The State is correct and the ESTop event also changed correctly.
mach500events2b

However, if I change any of the values for System.Name, System.Type or System.Operator, the Values are always blank.
mach500events3b

My Devices.xml file defines all of the Event MESSAGE types the same way. Why do some work and others do not?
mach500devices

What am I doing wrong?

Beginners problem.

Hello, I am trying to build and install the Agent on Windows, but I am having some issues. I am sorry if the problem looks dumb, but I am not a good programmer.
So, i downloaded the master cppagent and I built it using CMake. The generator used was CodeBlocks - MinGW Makefiles. Generating was done with no issues.
After that, i tried to build and run the cppagent using the CodeBlocks, but this message appeared:

||=== Build: all in cppagent (compiler: GNU GCC Compiler) ===|
C:\Users\Marcelo Cassani\Desktop\cppagent-master\agent\globals.hpp|43|fatal error: sys/resource.h: No such file or directory|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 1 second(s)) ===|

Besides, I can't find the configuration file to write my Devices xml.
Am I missing any step?

Please help me.
Thank you very much.

mRealTime does not work on adapter.

I find that, mRealTime always is false when call function connect(connector.cpp file). And after receive protocol command (realtime = true), the value only works when next connect to adapter again, right?

Dynamic device name assignment in mtconnect

Question: I want to be able to support Devices that might be assigned to a different IP address at different times. This might happen during DHCP when a router assigns an IP address to the Device. Thus, an existing Device-Agent IP configuration would be invalid. Another possibility is that the devices “move” and then replug into a router (I call this a mobile assets case) while still talking to the same MTConnect Agent. Again, the IP might change, thus nullifying the Device/Agent IP assigned configuration.

Is there any way for MTConnect to do dynamic device assignment not based on IP but on the device name?

I am posting it to the issues web site, soweb crawlers will find my response!

Fanuc Tool Offsets

I have been requested to add tool offsets to the data collected from the machine. From what I can tell, this is not included in the adapter and therefore it can't be mapped to the agent. The Focas library has access to these variables. Has anyone else done this and give me any pointers on what to do?

Alternative POST Error Message

If data is posted to the agent, and AllowPut = yes is not included in the config file, the following error is returned:
Only the HTTP GET request is supported

Recommend an error message something like this:
“This agent is not configured to accept HTTP POST requests.”
to better guide users.

Unable to use CMake(Beginner question)

Hi,

I am a beginner and I have encounter this problem and I have no idea how to solve it.

You have called ADD_LIBRARY for library cppunit without any source files. This typically indicates a problem with your CMakeLists.txt file

Best Regards,
Chua YQ

Reload devices.xml?

It would be helpful if agent can be commanded to reload the devices.xml to streamline the process of installation of agent and adapter.

Thanks

Using data streamed by agent.

I'm beginner in MTConnect and trying to make use of data/information (which is in MTConnect format) streamed by agent. My client doesn't understand MTconnect because its code is written for particular string format. So, I want to make a wrapper which will convert info. sent by agent (in MTConnect format) into the format that client will understand. So, first step is to get information from agent and the second is to convert into desired format. How do I receive information from agent? (Of course, not web browser because agent is an API).

To see output generated by agent, I was trying to do : 'telnet localhost 5000' in CMD but it wasn't showing anything.

What should I do?
Is there any wrapper for conversion of MTConnect to desired string format?

Broken header link to mtconnect.org

<MTConnectDevices xmlns:m="urn:mtconnect.org:MTConnectDevices:1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mtconnect.org:MTConnectDevices:1.1" xsi:schemaLocation="urn:mtconnect.org:MTConnectDevices:1.1 http://www.mtconnect.org/schemas/MTConnectDevices_1.1.xsd">

Links at line 2 referencing schema XSD on mtconnect.org are no longer valid. The same files are on GitHub at https://github.com/mtconnect/schema

version numbering for adapter and agent (with build number)

I was asked what version of MTConnect software I was distributing. Needless to say, I had no real answer. I am using version 1.2 adapter and agent that I downloaded from github, and know work. No drips, no runs, no errors. I tweak as appropriate (e.g., I commented out threading from the adapter). I have a msi script with version increments (so it will overwrite existing installations.) but this is no real answer. I realize there is a version.hh in the agent, but its only for major.minor MTConnect version. Visual Studio C++ versioning is horrible, C# is better (of course). If there is a way to identify version including build in MTconnect, then I will spend some time figuring out how to automate a post-build in windows.

Any thoughts appreciated before I jump in the MTConnect versioning pool...

LinuxCNC / MTConnect based on ros_bridge/mtconnect

I have been working though the code found here to complete the same project AtinA described.

The LinuxCNC data_item.py piece is working, posting data points from LinuxCNC to console.

The sticking point seems to be somewhere in the socket to the remote server. Currently, I am not relying on my MTConnect agent to create the apapter's listening socket to which the python code sends data; instead I am using netcat to create a listener for the purpose of seeing the SHDR data posted to the remote server's terminal line (think telnet).

mtconnect_adapter.py is sending some xml data (not SHDR) through to the listening port whcich I can see, but the python code stops after this initial dump with a waiter_acquire() message to console. The socket remains bound on both sending and receiving ends until the python code is manually exited, the socket listener process is forcibly closed or a command executed at the listener's terminal line.

I have a feeling I am close to success, but seem to be missing a function call to get the data_item.py to send the SHDR through the port.

I will gladly post the modifications I made to the code. Aside from adding needed libraries (modules) I only placed a call at the end of long_pull.py to the Adapter function in mtconnect_adapter.py and parameterized some ip addresses and port numbers.

Something seems to not be working with the socket connection. ADDED CODE I AM WORKING WITH BELOW.

ConfigTest Failing

I am trying to run test on Fedora 21 with gcc (GCC) 4.9.2. The Following test is failing:

Test name: ConfigTest::testMaxSize
equality assertion failed

  • Expected: 15360
  • Actual : 150

Failures !!!
Run: 201 Failure total: 1 Failures: 1 Errors: 0

Tests failing

While running the tests i am getting errors. Running on Fedora 21, gcc 4.9.2
Steps followed:

  1. cmake . (in cppagent/)
  2. make (in cppagent/)
  3. ./agent_test (in cppgent/test/)

[subho@localhost] test $ (master) ./agent_test
AdapterTest::testAdapter : OK
AgentTest::testConstructor 104 ERROR [0] xml.parser: XML: I/O
104 ERROR [0] xml.parser: XML: warning :
104 ERROR [0] xml.parser: XML: failed to load external entity "../samples/badPath.xml"

104 FATAL [0] agent: Error loading xml configuration: ../samples/badPath.xml
104 FATAL [0] agent: Error detail: XML Error at /home/subho/work/github/cppagent/agent/xml_parser.cpp(74): mDoc = xmlReadFile(aPath.c_str(), NULL, XML_PARSE_NOBLANKS)
XML Error at /home/subho/work/github/cppagent/agent/xml_parser.cpp(74): mDoc = xmlReadFile(aPath.c_str(), NULL, XML_PARSE_NOBLANKS)
: OK
AgentTest::testBadPath : OK
AgentTest::testProbe : OK
AgentTest::testBadXPath 116 ERROR [0] xml.parser: XML: Invalid expression

116 ERROR [0] xml.parser: XML: Invalid expression

116 ERROR [0] xml.parser: XML: Invalid expression

116 ERROR [0] xml.parser: XML: Invalid predicate

116 ERROR [0] xml.parser: XML: Invalid expression

: OK
AgentTest::testXPath : OK
AgentTest::testBadCount : OK
AgentTest::testBadFreq : OK
AgentTest::testGoodPath : OK
AgentTest::testEmptyStream : OK
AgentTest::testBadDevices : OK
AgentTest::testAddAdapter : OK
AgentTest::testAddToBuffer : OK
AgentTest::testAdapter : OK
AgentTest::testCurrentAt : OK
AgentTest::testCurrentAt64 : OK
AgentTest::testCurrentAtOutOfRange : OK
AgentTest::testSampleAtNextSeq : OK
AgentTest::testAdapterCommands : OK
AgentTest::testFileDownload : OK
AgentTest::testFailedFileDownload 410 ERROR [0] agent: Cannot register file: ./BadFileName.xsd: Unable to find file ./BadFileName.xsd
: OK
AgentTest::testDuplicateCheck : OK
AgentTest::testAutoAvailable : OK
AgentTest::testIgnoreTimestamps : OK
AgentTest::testAssetStorage : OK
AgentTest::testAssetError : OK
AgentTest::testAssetBuffer : OK
AgentTest::testPut : OK
AgentTest::testPutBlocking : OK
AgentTest::testPutBlockingFrom : OK
AgentTest::testAdapterAddAsset : OK
AgentTest::testMultiLineAsset : OK
AgentTest::testAssetProbe : OK
AgentTest::testAssetStorageWithoutType : OK
AgentTest::testStreamData : OK
AgentTest::testSequenceNumberRollover : OK
AgentTest::testSampleCount : OK
AgentTest::testStreamDataObserver : OK
AgentTest::testFailWithDuplicateDeviceUUID 3665 ERROR [0] xml.parser: XML: I/O
3665 ERROR [0] xml.parser: XML: warning :
3665 ERROR [0] xml.parser: XML: failed to load external entity "../samples/dup_uuid.xml"

3665 FATAL [0] agent: Error loading xml configuration: ../samples/dup_uuid.xml
3665 FATAL [0] agent: Error detail: XML Error at /home/subho/work/github/cppagent/agent/xml_parser.cpp(74): mDoc = xmlReadFile(aPath.c_str(), NULL, XML_PARSE_NOBLANKS)
XML Error at /home/subho/work/github/cppagent/agent/xml_parser.cpp(74): mDoc = xmlReadFile(aPath.c_str(), NULL, XML_PARSE_NOBLANKS)
: OK
AgentTest::testMultipleDisconnect : OK
AgentTest::testRelativeTime : OK
AgentTest::testRelativeParsedTime : OK
AgentTest::testRelativeParsedTimeDetection : OK
AgentTest::testRelativeOffsetDetection : OK
AgentTest::testDynamicCalibration : OK
AgentTest::testInitialTimeSeriesValues : OK
AgentTest::testUUIDChange : OK
AgentTest::testFilterValues : OK
AgentTest::testReferences : OK
AgentTest::testDiscrete : OK
AgentTest::testUpcaseValues : OK
AgentTest::testConditionSequence : OK
AgentTest::testAssetRemoval : OK
AgentTest::testAssetRemovalByAdapter : OK
AgentTest::testAssetAdditionOfAssetChanged12 : OK
AgentTest::testAssetAdditionOfAssetRemoved13 : OK
AgentTest::testAssetPrependId : OK
AgentTest::testBadAsset 3773 ERROR [0] xml.parser: XML: file://111.xml:1:
3773 ERROR [0] xml.parser: XML: parser
3773 ERROR [0] xml.parser: XML: error :
3773 ERROR [0] xml.parser: XML: Opening and ending tag mismatch: CuttingItem line 1 and CuttingItmems

3773 ERROR [0] xml.parser: XML: 0

3773 ERROR [0] xml.parser: XML: ^

3773 ERROR [0] xml.parser: XML: file://111.xml:1:
3773 ERROR [0] xml.parser: XML: parser
3773 ERROR [0] xml.parser: XML: error :
3773 ERROR [0] xml.parser: XML: Opening and ending tag mismatch: CuttingItem line 1 and CuttingToolLifeCycle

3773 ERROR [0] xml.parser: XML: nominal="0">0

3773 ERROR [0] xml.parser: XML: ^

3773 ERROR [0] xml.parser: XML: file://111.xml:1:
3773 ERROR [0] xml.parser: XML: parser
3773 ERROR [0] xml.parser: XML: error :
3773 ERROR [0] xml.parser: XML: Opening and ending tag mismatch: CuttingItem line 1 and CuttingTool

3774 ERROR [0] xml.parser: XML: </CuttingTool

3774 ERROR [0] xml.parser: XML: ^

3774 ERROR [0] xml.parser: XML: file://111.xml:2:
3774 ERROR [0] xml.parser: XML: parser
3774 ERROR [0] xml.parser: XML: error :
3774 ERROR [0] xml.parser: XML: Premature end of data in tag CuttingItems line 1

3774 ERROR [0] xml.parser: XML:

3774 ERROR [0] xml.parser: XML: ^

3774 ERROR [0] xml.parser: XML: file://111.xml:2:
3774 ERROR [0] xml.parser: XML: parser
3774 ERROR [0] xml.parser: XML: error :
3774 ERROR [0] xml.parser: XML: Premature end of data in tag CuttingToolLifeCycle line 1

3774 ERROR [0] xml.parser: XML:

3774 ERROR [0] xml.parser: XML: ^

3774 ERROR [0] xml.parser: XML: file://111.xml:2:
3774 ERROR [0] xml.parser: XML: parser
3774 ERROR [0] xml.parser: XML: error :
3774 ERROR [0] xml.parser: XML: Premature end of data in tag CuttingTool line 1

3774 ERROR [0] xml.parser: XML:

3774 ERROR [0] xml.parser: XML: ^

3774 ERROR [0] xml.parser: Cannot parse asset XML, Unknown execption occurred
3774 ERROR [0] agent: addAssete: Error parsing asset
: OK
AgentTest::testAssetWithSimpleCuttingItems : OK
AgentTest::testRemoveLastAssetChanged : OK
AgentTest::testRemoveAllAssets : OK
AgentTest::testEmptyLastItemFromAdapter : OK
AgentTest::testAdapterDeviceCommand 3798 ERROR [0] xml.parser: XML: I/O
3798 ERROR [0] xml.parser: XML: warning :
3798 ERROR [0] xml.parser: XML: failed to load external entity "../samples/two_devices.xml"

3798 FATAL [0] agent: Error loading xml configuration: ../samples/two_devices.xml
3798 FATAL [0] agent: Error detail: XML Error at /home/subho/work/github/cppagent/agent/xml_parser.cpp(74): mDoc = xmlReadFile(aPath.c_str(), NULL, XML_PARSE_NOBLANKS)
XML Error at /home/subho/work/github/cppagent/agent/xml_parser.cpp(74): mDoc = xmlReadFile(aPath.c_str(), NULL, XML_PARSE_NOBLANKS)
Segmentation fault (core dumped)

Compiling 1.3 Agent in MSVC 2015 Community Version

FYI. 1.3 Agent compiles and seems to work on Win 7 64 bit platform. Suppose some fixes could be pull requests.

Below are the steps I did after downloading MSVC 2015 community edition (free version) to compile the MTConnect 1.3 agent in C++ (not the agent in the master branch). I don't use CMake as it hardcodes the project links.

  1. Create console project - no precompiled ATL, etc.
    a) Setup project as multibyte not Unicode string
    b) Make Project options: Compiler-> code generation-> Runtime static lib use of C lib

  2. Create MTCAgent folder copy in agent/lib/win32 code

  3. Preprocessor - Add these definitions
    a) _Windows
    b) WIN64 for 64 bit configurations for later #pragma lib includes described below
    c) _NO_CRT_STDIO_INLINE for problem (9) doesn't solve but should

  4. Include file : In project properties, Projects->Compiler->Command line Add: @IncludeDirs.txt
    You will have to adapt the full path to the location of your
    FIle IncludeDirs.txt:

-I.
-I"C:\Users\michalos\Documents\Visual Studio 2015\Projects\MTConnectAgent1_3\MTConnectAgent\agent"
-I"C:\Users\michalos\Documents\Visual Studio 2015\Projects\MTConnectAgent1_3\MTConnectAgent\lib"
-I"C:\Users\michalos\Documents\Visual Studio 2015\Projects\MTConnectAgent1_3\MTConnectAgent\win32\libxml2-2.9\include"
-I"C:\Users\michalos\Documents\Visual Studio 2015\Projects\MTConnectAgent1_3\MTConnectAgent"
-I"C:\Users\michalos\Documents\Visual Studio 2015\Projects\MTConnectAgent1_3\NIST"

  1. No gets() in service.cpp in VS 2015

The most recent revision of the C standard (2011) has definitively removed this function from its specification.
The function is deprecated in C++ (as of 2011 standard, which follows C99+TC3).

from
http://stackoverflow.com/questions/12893774/what-is-gets-equivalent-in-c11

Subsituted:

while(gets_s(line, sizeof(line)) != NULL) {

  1. timezone not declared
    globals.cpp(241): error C2065: 'timezone': undeclared identifier

uint64_t time = (mktime(&timeinfo) - timezone) * 1000000;

Removed timezone to make it compile - but not really FIXED!

  1. In new project main file (or in some source cpp file) have to declare link path and lib of libxml:

define MTCLIBPATH(X) "C:\Users\michalos\Documents\Visual Studio 2015\Projects\MTConnectAgent1_3\MTConnectAgent\win32\libxml2-2.9\lib" ## X

if defined( WIN64 ) && defined( _DEBUG )

pragma message( "DEBUG x64" )

pragma comment(lib, MTCLIBPATH("libxml2_64d.lib"))

elif !defined( _DEBUG ) && defined( WIN64 )

pragma message( "RELEASE x64" )

pragma comment(lib, MTCLIBPATH("libxml2_64.lib"))

endif

  1. ConnectAgent1_3.obj : error LNK2005: main already defined in cppagent.obj
    remove main from console project empty main

  2. ibxml2d_a_v120_64.lib(error.obj) : error LNK2001: unresolved external symbol __iob_func

http://stackoverflow.com/questions/30412951/unresolved-external-symbol-imp-fprintf-and-imp-iob-func-sdl2

Added to project main file:

FILE _iob[] = {*stdin, *stdout, *stderr};
extern "C" FILE * __cdecl __iob_func(void)
{
return _iob;
}

  1. unresolved external symbol vfprintf

pragma comment(lib, "legacy_stdio_definitions.lib")

  1. Add libcmt.lib to Linker Ignore Library Project Properties
    This didn't work: /NODEFAULTLIB:library in Linkerv-> properties -> Command Line

  2. Runtime error: Couldn't find agent.cfg (not given full path)

5522 FATAL [0] init.config: Agent failed to load: Please make sure the configur
ation file probe.xml or Devices.xml is in the current directory or specify the c
orrect file in the configuration file agent.cfg using Devices =
Agent failed to load: Please make sure the configuration file probe.xml or Devic
es.xml is in the current directory or specify the correct file in the configurat
ion file agent.cfg using Devices =

in agent.cpp:

static std::string ExeDirectory()
{
TCHAR buf[1000];
GetModuleFileName(NULL, buf, 1000);
std::string path(buf);
path=path.substr( 0, path.find_last_of( '' ) +1 );
return path;
}

somewhere in code before initialize():

  SetCurrentDirectory(ExeDirectory().c_str());

Message update failure: error parsing Adapter - Agent packet?

I am having a tough time finding out why some of my data is failing to update.
A data packet from the Adapter to the Agent like this:

2017-10-19T15:21:33.4328001Z|firstVar|1848|secondVar|1318|thirdVar|2319|fourthVar|1697|fifthVar|2565
results in "firstVar" getting the value 2565, and none of the other variables updating.
Everything works when there are other data items included in the packet, e.g.:

2017-10-19T15:28:27.8978001Z|subProgram|7361|firstVar|296|secondVar|2289|thirdVar|2330|fourthVar|2967|fifthVar|2324
Note the addition of the subProgram data. Now all the other variables populate correctly.
I suspect there is some problem with the Agent interpreting these packets, but I'm not sure.

I am using the .NET Adapter SDK and the C++ agent v1.3.0.17.
I have attached my Devices.xml. The variables in question are at the bottom, and are supposed to be generic messages:

<DataItem type="MESSAGE" category="EVENT" id="01CV" name="firstVar" />
<DataItem type="MESSAGE" category="EVENT" id="02CV" name="secondVar" />

Devices.xml.txt

MTConnect URN not resolving when multiple xsd files

There seems to be a problem in the schema file registry. when you use the _1.0 file and it finds another MTConnect file first, it registers it with the URN for MTConnect and it masks the other file. This causes a problem when trying to resolve the MTConnect urn, since there are two files in the schemas directory.

The quick fix is to remove the MTConnect_1.3.xsd and change the name of the MTConnect_1.3_1.0.xsd to MTConnect_1.3.xsd. Then in the xml file, change the reference to the MTConnect_1.3.xsd file. This will get the correct file and it will work correctly. The issue seems to be the duplicate urn mapping in the agent and the rewrite of the header block to reference the correct MTConnect schema file in in the schema location.
MC5.zip

Possible Memory Leak

When sending cutting tool data repeatedly to the agent, the memory usage looks to keep expanding even once the asset buffer is full. We have the asset buffer size set to 74 so it's filled from the start of the adapter output.

I've attached the adapter output below.
ToolData.txt

ToolNumber and ToolAssetId?

It seems there is a bug with these 2 tags.
It will depend on the how the data sending to these 2 tags. One cannot clear it out.

Is there any logic that tied to these 2 tags when updating its data?

Here is my test:
p1CurrentTool|123|p1ToolAssetId|123 ==>display both
p1CurrentTool|123|p1ToolAssetId| ==> clear Tool asset
p1CurrentTool||p1ToolAssetId|123 ==> try to clear tool number and display tool asset but
ToolNumber is not clear after this

It also depends on how the order of which tag is sent out last:
2014-10-03T13:31:54.5240517Z|p1ToolAssetId|123|p1CurrentTool|\n

In this case, Tool Number cannot be cleared out

Thanks

Can agent support Unicode?

Our adapter can receive JIS characters without a problem; however, when I check agent output stream all Japanese characters are displayed as question mark only as seen in the captured image

image

Can agent support Unicode?

Thanks

Windows XP builds of Agent 1.4 Release Candidates don't find Devices XML file

I've tried RC1-RC4 and they all produce the following:

C:\agent>agent.exe run
MTConnect Agent Version 1.4.0.2RC2 - built on Mon Jun 12 15:01:36 2017
Agent failed to load: Please make sure the Devices XML configuration file Devices.xml 
is in the current path
Usage: agent  [<file>]
    <file>               : The configuration file

There is a Devices.xml file in the same directory as the agent.exe and I even added that directory to the path. Dropping in 1.3 agent.exe works fine.

Question about Sample 'Out of Range' Error

Using the application sequence (recommended in section 3.2 of the MTConnect Components spec) of first running a Current request to get the FirstSequence or NextSequence parameter to then use in a subsequent Sample request can sometimes return an "OUT_OF_RANGE" error.

I suspect this is due to the agent's buffer being full and the buffer setting is not set large enough but I was wondering if this should instead return the first available sequence instead of returning an error. This seems to be the way that the Count parameter works as it just returns the last available sequence when it exceeds the LastSequence value.

This typically isn't an issue when an application has already been running and it is only requesting a small range of the most recent data but can become an issue for applications that return the entire buffer. In this case, when the buffer is full, the application may end up in a situation where it is constantly chasing a moving target as by the time the application receives the Current request, the FirstSequence number is already invalid.

I haven't extensively looked at the source code for this agent but a quick observation points the issue (if this is indeed considered an issue) to the below code:

agent.cpp | Agent::handleCall()

if (start == NO_START) // If there was no data in queries
      {
        start = checkAndGetParam64(queries, "from", 1,
                                   getFirstSequence(), true, mSequence);
}

agent.cpp | Agent::checkAndGetParam() and Agent::checkAndGetParam64()

if (minValue != NO_VALUE64 && value < minValue)
  {
    if (minError)
    {
      throw ParameterError("OUT_OF_RANGE",
                          "'" + param + "' must be greater than or equal to " + intToString(minValue) + ".");
    }
    return minValue;
}

It appears the minError variable was meant to accomplish this but when used to process the Sample's start parameter it is set to true. Is there a reasoning behind this that it was set this way or is it something that can be updated? Or can this be a setting in the Agent's configuration file?

Thanks,

Patrick

Question about extend coordinatesystem?

Hi,
I tried to extend coordinateSystem as shown below but it fails to validate in the probe command.
I knew that coordinateSystem currently support Machine and Work coordinate systems.
I need to add axes using different coordinate systems.

Is that possible?

coordinateSystem="x:I_MACHINE"
coordinateSystem="x:I_WORK"

Thanks

        <!-- YI1 axis respect to A turret-->
        <Linear  name="YI1" nativeName="YIA" id="LYI1">
          <DataItems>
            <DataItem  type="POSITION" subType="ACTUAL" category="SAMPLE"
              name="YI1actm" units="MILLIMETER" nativeUnits="MILLIMETER" coordinateSystem="x:I_MACHINE" id="LYI1actm" />
            <DataItem  type="POSITION" subType="ACTUAL" category="SAMPLE"
              name="YI1actw" units="MILLIMETER" nativeUnits="MILLIMETER" coordinateSystem="x:I_WORK" id="LYI1actw" />
            <DataItem  type="LOAD"  category="SAMPLE" name="YS1load"
            units="PERCENT" nativeUnits="PERCENT" id="LYS1load"/>
          </DataItems>
        </Linear>

Fails to bind to port 5000

On launch, agent fails to bind to port 5000 and does not log error. Port 5000 was already in use by another copy of agent.exe

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.