{"id":26866569,"url":"https://github.com/mtconnect/cppagent","last_synced_at":"2025-04-07T15:10:40.384Z","repository":{"id":668028,"uuid":"311230","full_name":"mtconnect/cppagent","owner":"mtconnect","description":"C++ Agent toolkit - Pre-built binaries, visit: https://github.com/mtconnect/cppagent/releases Docker images available at https://hub.docker.com/repositories/mtconnect","archived":false,"fork":false,"pushed_at":"2024-05-22T15:38:24.000Z","size":86081,"stargazers_count":133,"open_issues_count":14,"forks_count":88,"subscribers_count":38,"default_branch":"main","last_synced_at":"2024-05-22T16:49:56.729Z","etag":null,"topics":["agent","c-plus-plus","iiot","mtconnect","mtconnect-agent","mtconnect-standard"],"latest_commit_sha":null,"homepage":"http://mtcup.org/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mtconnect.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog","contributing":null,"funding":null,"license":"LICENSE.TXT","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2009-09-18T20:44:57.000Z","updated_at":"2024-06-04T13:59:21.507Z","dependencies_parsed_at":"2024-02-08T00:27:56.403Z","dependency_job_id":"61ca2386-5091-48d1-aa7f-ee05c7964e65","html_url":"https://github.com/mtconnect/cppagent","commit_stats":{"total_commits":2306,"total_committers":26,"mean_commits":88.6923076923077,"dds":0.5910667823070251,"last_synced_commit":"66ce164d31bd215cd4b1fac4721d7e5f243cf4ca"},"previous_names":[],"tags_count":201,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtconnect%2Fcppagent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtconnect%2Fcppagent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtconnect%2Fcppagent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtconnect%2Fcppagent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mtconnect","download_url":"https://codeload.github.com/mtconnect/cppagent/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247675607,"owners_count":20977378,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent","c-plus-plus","iiot","mtconnect","mtconnect-agent","mtconnect-standard"],"created_at":"2025-03-31T04:55:07.302Z","updated_at":"2025-04-07T15:10:40.355Z","avatar_url":"https://github.com/mtconnect.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\nMTConnect C++ Agent Version 2.5\n--------\n[![Build MTConnect C++ Agent](https://github.com/mtconnect/cppagent/actions/workflows/build.yml/badge.svg)](https://github.com/mtconnect/cppagent/actions/workflows/build.yml)\n\nThe C++ Agent provides the a complete implementation of the HTTP\nserver required by the MTConnect standard. The agent provides the\nprotocol and data collection framework that will work as a standalone\nserver. Once built, you only need to specify the XML description of\nthe devices and the location of the adapter.\n\n**NOTE: This version cannot currently be built on Windows XP since there is currently no support for the XP toolchain and C++ 17.**\n\nPre-built binary releases for Windows are available from [Releases](https://github.com/mtconnect/cppagent/releases) for those who do not want to build the agent themselves. For *NIX users, you will need libxml2, cppunit, and cmake as well as build essentials.\n\nVersion 2.5.0 Support for version 2.5. Added validation of observations in the stream and WebSockets support.\n\nVersion 2.4.0 Added support for version 2.4\n\nVersion 2.3.0 Support for all Version 2.3 standard changes and JSON ingress to MQTT adapter.\n\nVersion 2.2.0 Support for all Version 2.2 standard changes and dynamic configuration from adapters. Upgrade to conan 2.\n\nVersion 2.1.0 Added MQTT Sink, Agent Restart and new JSON format (version 2)\n\nVersion 2.0.0 Rearchitecture of the agent with TLS, MQTT Adapter, Ruby Interpreter, Agent Adaptr, and much more\n\nVersion 1.7.0 added kinematics, solid models, and new specifications types.\n\nVersion 1.6.0 added coordinate systems, specifications, and tabular data.\n\nVersion 1.5.0 added Data Set capabilities and has been updated to use C++ 14.\n\nVersion 1.4.0 added time period filter constraint, compositions, initial values, and reset triggers.\n\nVersion 1.3.0 added the filter constraints, references, cutting tool archetypes, and formatting styles.\n\nVersion 1.2.0 added the capability to support assets.\n\nVersion 1.1.0.8 add the ability to run the C++ Agent as a Windows\nservice and support for a configuration file instead of command line\narguments. The agent can accept input from a socket in a pipe (`|`)\ndelimited stream according to the descriptions given in the adapter\nguide.\n\nThe current win32 binary is built statically and requires no\nadditional dlls to run. This allows for a single exe distributable.\n\nUsage\n------\n\n    agent [help|install|debug|run] [configuration_file]\n       help           Prints this message\n       install        Installs the service\n       remove         Remove the service\n       debug          Runs the agent on the command line with verbose logging -\n                      sets logging_level to debug\n       run            Runs the agent on the command line\n       config_file    The configuration file to load\n                      Default: agent.cfg in current directory\n\nWhen the agent is started without any arguments it is assumed it will\nbe running as a service and will begin the service initialization\nsequence. The full path to the configuration file is stored in the\nregistry in the following location:\n\n    \\\\HKEY_LOCAL_MACHINE\\SOFTWARE\\MTConnect\\MTConnect Agent\\ConfigurationFile\n\nDirectories\n-----\n\n* `agent/`        - This contains the application source files and CMake file.\n\n* `assets/`       - Some example Cutting Tool asset files.\n\n* `lib/`          - Third party library source. Contains source for cppunit, dlib, and libxml++.\n\n* `samples/`      - Sample XML configuration files mainly used for tests.\n\n* `simulator/`    - Ruby scripts to execute an adapter simulator, both command-line and log-replay.\n\n* `test/`         - Various unit tests.\n\n* `tools/`        - Ruby scripts to dump the agent and the adapter in SHDR format. Includes a sequence \n                    test script.\n\n* `unix/`         - Unix init.d script\n\n* `win32/`        - Libraries required only for the win32 build and the win32 solution.\n\nWindows Binary Release\n-----\n\nThe windows binary releases come with a prebuilt exe that is\nstatically linked with the Microsoft Runtime libraries. Aside from the\nstandard system libraries, the agent only requires winsock\nlibraries. The agent has been test with version of Windows 2000 and\nlater.\n\n* `bin/`         - Win32 binary (no dependencies required).\n\nBuilding\n-------\n\nPlatform specific instructions are at the end of the README.\n\nConfiguration\n------\n\nThe configuration file is using the standard Boost C++ file\nformat. The configuration file format is flexible and allows for both\nmany adapters to be served from one agent and an adapter to feed\nmultiple agents. The format is:\n\n    Key = Value\n\nThe key can only occur once within a section and the value can be any\nsequence of characters followed by a `\u003cCR\u003e`. There no significance to\nthe order of the keys, so the file can be specified in free form. We\nwill go over some configurations from a minimal configuration to more\ncomplex multi-adapter configurations.\n\n### Serving Static Content ###\n\nUsing a Files Configuration section, individual files or directories can be inserted\ninto the request file space from the agent. To do this, we use the Files top level \nconfiguration declaration as follows:\n\n    Files {\n        schemas {\n            Path = ../schemas\n            Location = /schemas/\n        }\n        styles {\n            Path = ../styles\n            Location = /styles/\n        }\n    }\n\nEach set of files must be declared using a named file description, like schema or\nstyles and the local `Path` and the `Location` the files will be mapped to in the\nHTTP server namespace. For example:\n\n    http://example.com:5000/schemas/MTConnectStreams_2.0.xsd will map to ../schemas/MTConnectStreams_2.0.xsd\n\nAll 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.\n\n### Specifying the Extended Schemas ###\n\nTo specify the new schema for the documents, use the following declaration:\n\n    StreamsNamespaces {\n      e {\n        Urn = urn:example.com:ExampleStreams:2.0\n        Location = /schemas/ExampleStreams_2.0.xsd\n      }\n    }\n\nThis will use the ExampleStreams_2.0.xsd schema in the document. The `e` is the alias that will be\nused to reference the extended schema. The `Location` is the location of the xsd file relative in \nthe agent namespace. The `Location` must be mapped in the `Files` section.\n\nAn optional `Path` can be added to the `...Namespaces` declaration instead of declaring the \n`Files` section. The `Files` makes it easier to include multiple files from a directory and will\nautomatically include all the default MTConnect schema files for the correct version. \n(See `SchemaVersion` option below)\n\nYou can do this for any one of the other documents: \n\n    StreamsNamespaces\n    DevicesNamespaces\n    AssetsNamespaces\n    ErrorNamespaces\n\n### Specifying the XML Document Style ###\n\nThe same can be done with style sheets, but only the Location is required.\n\n    StreamsStyle {\n      Location = /styles/Streams.xsl\n    }\n    \nAn optional `Path` can also be used to reference the xsl file directly. This will not \ninclude other files in the path like css or included xsl transforms. It is advised to\nuse the `Files` declaration.\n    \nThe following can also be declared:\n\n    DevicesStyle\n    StreamsStyle\n    AssetsStyle\n    ErrorStyle\n\n### Example 1: ###\n\nHere’s an example configuration file. The `#` character can be used to\ncomment sections of the file. Everything on the line after the `#` is\nignored. We will start with an extremely simple configuration file.\n\n    # A very simple file...\n    Devices = VMC-3Axis.xml\n\nThis is a one line configuration that specifies the XML file to load\nfor the devices. Since all the values are defaulted, an empty\nconfiguration file can be specified. This configuration file will load\nthe `VMC-3Axis.xml` file and try to connect to an adapter located on the\nlocalhost at port 7878. `VMC-3Axis.xml` must only contain the definition\nfor one device; if more devices exist, an error will be raised and the\nprocess will exit.\n\n### Example 2: ###\n\nMost configuration files will specify at least one adapter. The\nadapters are contained within a block. The Boost configuration file\nformat allows for nested configurations and block associations. There\nare a number of configurations that can be given for each\nadapter. Multiple adapters can be specified for one device as well.\n\n    Devices = VMC-3Axis.xml\n\n    Adapters\n    {\n        VMC-3Axis\n        {\n            Host = 192.168.10.22\n            Port = 7878 # *Default* value...\n        }\n    }\n\nThis example loads the devices file as before, but specifies the list\nof adapters. The device is taken from the name `VMC-3Axis` that starts\nthe nested block and connects to the adapter on `192.168.10.22` and port\n`7878`. Another way of specifying the equivalent configuration is:\n\n    Devices = VMC-3Axis.xml\n\n    Adapters\n    {\n        Adapter_1\n        {\n            Device = VMC-3Axis\n            Host = 192.168.10.22\n            Port = 7878 # *Default* value...\n        }\n    }\n\nLine 7 specifies the Device name associated with this adapter\nexplicitly. We will show how this is used in the next example.\n\n### Example 3: ###\n\nMultiple adapters can supply data to the same device. This is done by\ncreating multiple adapter entries and specifying the same Device for\neach.\n\n    Devices = VMC-3Axis.xml\n\n    Adapters\n    {\n        Adapter_1\n        {\n            Device = VMC-3Axis\n            Host = 192.168.10.22\n            Port = 7878 # *Default* value...\n        }\n    \n        # Energy sensor\n        Adapter_2\n        {\n            Device = VMC-3Axis\n            Host = 192.168.10.2\n            Port = 7878 # *Default* value...\n        }\n    }\n\nBoth `Adapter_1` and `Adapter_2` will feed the `VMC-3Axis` device with\ndifferent data items.  The `Adapter_1` name is arbitrary and could just\nas well be named `EnergySensor` if desired as illustrated below.\n\n    Devices = VMC-3Axis.xml\n\n    Adapters\n    {\n        Controller\n        {\n            Device = VMC-3Axis\n            Host = 192.168.10.22\n            Port = 7878 # *Default* value...\n        }\n    \n        EnergySensor\n        {\n            Device = VMC-3Axis\n            Host = 192.168.10.2\n            Port = 7878 # *Default* value...\n        }\n    }\n\n### Example 4: ###\n\nIn this example we change the port to 80 which is the default http port. \nThis also allows HTTP PUT from the local machine and 10.211.55.2. \n\n    Devices = MyDevices.xml\n    Port = 80\n    AllowPutFrom = localhost, 10.211.55.2\n\n    Adapters\n    {\n        ...\n\nFor browsers you will no longer need to specify the port to connect to.\n\n### Example 5: ###\n\nIf multiple devices are specified in the XML file, there must be an\nadapter feeding each device.\n\n    Devices = MyDevices.xml\n\n    Adapters\n    {\n        VMC-3Axis\n        {\n            Host = 192.168.10.22\n        }\n    \n        HMC-5Axis\n        {\n            Host = 192.168.10.24\n        }\n    }\n\nThis will associate the adapters for these two machines to the VMC\nand HMC devices in `MyDevices.xml` file. The ports are defaulted to\n7878, so we are not required to specify them.\n\n### Example 6: ###\n\nIn this example we  demonstrate how to change the service name of the agent. This \nallows a single machine to run multiple agents and/or customize the name of the service. \nMultiple configuration files can be created for each service, each with a different \nServiceName. The configuration file must be referenced as follows:\n\n    C:\u003e agent install myagent.cfg\n\nIf myagent.cfg contains the following statements:\n\n    Devices = MyDevices.xml\n    ServiceName = MTC Agent 1\n\n    Adapters\n    {\n        ...\n\n\nThe service will now be displayed as \"MTC Agent 1\" as opposed to \"MTConnect Agent\"\nand it will automatically load the contents of myagent.cfg with it starts. You can now \nuse the following command to start this from a command prompt:\n\n    C:\u003e net start \"MTC Agent 1\"\n\nTo remove the service, do the following:\n\n    C:\u003e agent remove myagent.cfg\n\n### Example 7: ###\n\nLogging configuration is specified using the `logger_config` block. You\ncan change the `logging_level` to specify the verbosity of the logging\nas well as the destination of the logging output.\n\n    logger_config\n    {\n        logging_level = debug\n        output = file debug.log\n    }\n\nThis will log everything from debug to fatal to the file\ndebug.log. For only fatal errors you can specify the following:\n\n    logger_config\n    {\n        logging_level = fatal\n    }\n\nThe default file is agent.log in the same directory as the agent.exe\nfile resides. The default logging level is `info`. To have the agent log\nto the command window:\n\n    logger_config\n    {\n        logging_level = debug\n        output = cout\n    }\n\nThis will log debug level messages to the current console window. When\nthe agent is run with debug, it sets the logging configuration to\ndebug and outputs to the standard output as specified above.\n\n### Example: 8 ###\n\nThe MTConnect C++ Agent supports extensions by allowing you to specify your\nown XSD schema files. These files must include the MTConnect schema and the top\nlevel node is required to be MTConnect. The \"x\" in this case is the namespace. You\nMUST NOT use the namespace \"m\" since it is reserved for MTConnect. See example 9\nfor an example of changing the MTConnect schema file location.\n\nThere are four namespaces in MTConnect: Devices, Streams, Assets, and Error. In \nthis example we will replace the Streams and Devices namespace with our own namespace\nso we can have validatable XML documents. \n\n\tStreamsNamespaces {\n\t  x {\n\t    Urn = urn:example.com:ExampleStreams:1.2\n\t    Location = /schemas/ExampleStreams_1.2.xsd\n\t    Path = ./ExampleStreams_1.2.xsd\n\t  }\n\t}\n\n\tDevicesNamespaces {\n\t  x {\n\t    Urn = urn:example.com:ExampleDevices:1.2\n\t    Location = /schemas/ExampleDevices_1.2.xsd\n\t    Path = ./ExampleDevices_1.2.xsd\n\t  }\n\t}\n\t\nFor each schema file we have three options we need to specify. The Urn\nis the urn in the schema file that will be used in the header. The Location\nis the path specified in the URL when requesting the schema file from the \nHTTP client and the Path is the path on the local file system.\n\n### Example: 9 ###\n\nIf you only want to change the schema location of the MTConnect schema files and \nserve them from your local agent and not from the default internet location, you\ncan use the namespace \"m\" and give the new schema file location. This MUST be the \nMTConnect schema files and the urn will always be the MTConnect urn for the \"m\" \nnamespace -- you cannot change it.\n\n\tStreamsNamespaces {\n\t  m {\n\t    Location = /schemas/MTConnectStreams_2.0.xsd\n\t    Path = ./MTConnectStreams_2.0.xsd\n\t  }\n\t}\n\n\tDevicesNamespaces {\n\t  m {\n\t    Location = /schemas/MTConnectDevices_2.0.xsd\n\t    Path = ./MTConnectDevices_2.0.xsd\n\t  }\n\t}\n    \nThe MTConnect agent will now serve the standard MTConnect schema files\nfrom the local directory using the schema path /schemas/MTConnectDevices_2.0.xsd.\n\n\n### Example: 10 ###\n\nWe can also serve files from the MTConnect Agent as well. In this example\nwe can assume we don't have access to the public internet and we would still \nlike to provide the MTConnect streams and devices files but have the MTConnect\nAgent serve them up locally. \n\n\tDevicesNamespaces {\n\t  x {\n\t    Urn = urn:example.com:ExampleDevices:2.0\n\t    Location = /schemas/ExampleDevices_2.0.xsd\n\t    Path = ./ExampleDevices_2.0.xsd\n\t  }\n\n\tFiles {\n\t  stream { \n\t    Location = /schemas/MTConnectStreams_2.0.xsd\n\t    Path = ./MTConnectStreams_2.0.xsd\n\t  }\n\t  device { \n\t    Location = /schemas/MTConnectDevices_2.0.xsd\n\t    Path = ./MTConnectDevices_2.0.xsd\n\t  }\n\t}\n\t\nOr use the short form for all files:\n\n        Files {\n          schemas { \n            Location = /schemas/MTConnectStreams_2.0.xsd\n            Path = ./MTConnectStreams_2.0.xsd\n          }\n        }\n    \nIf you have specified in your xs:include schemaLocation inside the \nExampleDevices_2.0.xsd file the location \"/schemas/MTConnectStreams_2.0.xsd\",\nthis will allow it to be served properly. This can also be done using the \nDevices namespace:\n\n\tDevicesNamespaces {\n\t  m {\n\t    Location = /schemas/MTConnectDevices_2.0.xsd\n\t    Path = ./MTConnectDevices_2.0.xsd\n\t  }\n\t}\n\nThe MTConnect agent will allow you to serve any other files you wish as well. You \ncan specify a new static file you would like to deliver:\n\n\tFiles {\n\t  myfile { \n\t    Location = /files/xxx.txt\n\t    Path = ./files/xxx.txt\n\t  }\n\nThe agent will not serve all files from a directory and will not provide an index \nfunction as this is insecure and not the intended function of the agent.\n\nRuby\n---------\n\nIf the \"-o with_ruby=True\" build is selected, then use to following configuration:\n\n    Ruby {\n      module = path/to/module.rb\n    }\n\nThe module specified at the path given will be loaded. There are examples in the test/Resources/ruby directory in \ngithub: [Ruby Tests](https://github.com/mtconnect/cppagent/tree/master/test/resources/ruby).\n\nThe current functionality is limited to the pipeline transformations from the adapters. Future changes will include adding sources and sinks.\n\nThe following is a complete example for fixing the Execution of a machine:\n\n```ruby\nclass AlertTransform \u003c MTConnect::RubyTransform\n  def initialize(name, filter)\n    @cache = Hash.new\n    super(name, filter)\n  end\n\n  @@count = 0\n  def transform(obs)\n    @@count += 1\n    if @@count % 10000 == 0\n      puts \"---------------------------\"\n      puts \"\u003e  #{ObjectSpace.count_objects}\"\n      puts \"---------------------------\"\n    end\n    \n    dataItemId = obs.properties[:dataItemId]\n    if dataItemId == 'servotemp1' or dataItemId == 'Xfrt' or dataItemId == 'Xload'\n      @cache[dataItemId] = obs.value\n      device = MTConnect.agent.default_device\n      \n      di = device.data_item('xaxisstate')\n      if @cache['servotemp1'].to_f \u003e 10.0 or @cache['Xfrt'].to_f \u003e 10.0 or @cache['Xload'].to_f \u003e 10\n        newobs = MTConnect::Observation.new(di, \"ERROR\")\n      else\n        newobs = MTConnect::Observation.new(di, \"OK\")\n      end\n      forward(newobs)\n    end\n    forward(obs)\n  end\nend\n    \nMTConnect.agent.sources.each do |s|\n  pipe = s.pipeline\n  puts \"Splicing the pipeline\"\n  trans = AlertTransform.new('AlertTransform', :Sample)\n  puts trans\n  pipe.splice_before('DeliverObservation', trans)\nend\n```\n\nConfiguration Parameters\n---------\n\n### Top level configuration items ####\n\n* `AgentDeviceUUID` - Set the UUID of the agent device\n\n    *Default*: UUID derived from the IP address and port of the agent\n\n* `BufferSize` - The 2^X number of slots available in the circular\n  buffer for samples, events, and conditions.\n\n    *Default*: 17 -\u003e 2^17 = 131,072 slots.\n\n* `CheckpointFrequency` - The frequency checkpoints are created in the\n  stream. This is used for current with the at argument. This is an\n  advanced configuration item and should not be changed unless you\n  understand the internal workings of the agent.\n\n    *Default*: 1000\n      \n* `CreateUniqueIds`: Changes all the ids in each element to a UUID that will be unique across devices. This is used for merging devices from multiple sources.\n\n    *Default*: `false`\n\n* `Devices` - The XML file to load that specifies the devices and is\n  supplied as the result of a probe request. If the key is not found\n  the defaults are tried.\n\n    *Defaults*: probe.xml or Devices.xml \n    \n* `DisableAgentDevice` - When the schema version is \u003e= 1.7, disable the \n  creation of the Agent device.\n  \n    *Default*: false\n\n* `JsonVersion`     - JSON Printer format. Old format: 1, new format: 2\n\n    *Default*: 2\n    \n* `LogStreams` - Debugging flag to log the streamed data to a file. Logs to a file named: `Stream_` + timestamp + `.log` in the current working directory. This is only for the Rest Sink.\n\n    *Default*: `false`\n\n* `MaxAssets` - The maximum number of assets the agent can hold in its buffer. The\n  number is the actual count, not an exponent.\n\n    *Default*: 1024\n    \n* `MaxCachedFileSize` - The maximum size of a raw file to cache in memory.\n\n    *Default*: 20 kb\n    \n* `MinCompressFileSize` - The file size where we begin compressing raw files sent to the client.\n\n    *Default*: 100 kb\n\n* `MinimumConfigReloadAge` - The minimum age of a config file before an agent reload is triggered (seconds).\n\n    *Default*: 15 seconds\n\n* `MonitorConfigFiles` - Monitor agent.cfg and Devices.xml files and restart agent if they change.\n\n    *Default*: false\n    \n* `MonitorInterval` - The interval between checks if the agent.cfg or Device.xml files have changed.\n\n    *Default*: 10 seconds\n\n* `Pretty` - Pretty print the output with indententation\n\n    *Default*: false\n\n* `PidFile` - UNIX only. The full path of the file that contains the\n  process id of the daemon. This is not supported in Windows.\n\n    *Default*: agent.pid\n    \n* `SchemaVersion` - Change the schema version to a different version number.\n\n    *Default*: 2.0\n\n* `Sender` - The value for the sender header attribute.\n\n    *Default*: Local machine name\n\n* `ServiceName` - Changes the service name when installing or removing \n  the service. This allows multiple agents to run as services on the same machine.\n\n    *Default*: MTConnect Agent\n\n* `SuppressIPAddress` - Suppress the Adapter IP Address and port when creating the Agent Device ids and names. This applies to all adapters.\n\n    *Default*: `false`\n    \n* `VersionDeviceXml` - Create a new versioned file every time the Device.xml file changes from an external source.\n\n    *Default*: `false`\n    \n* `Validation` - Turns on validation of model components and observations\n\n    *Default*: `false`\n\n* `WorkerThreads` - The number of operating system threads dedicated to the Agent\n\n    *Default*: 1\n    \n#### Adapter General Configuration\n\nThese can be overridden on a per-adapter basis\n\n* `Protocol` –Specify protocol. Options: [`shdr`|`mqtt`]\n\n    *Default*: shdr\n\n* `ConversionRequired` - Global default for data item units conversion in the agent. \n  Assumes the adapter has already done unit conversion.\n\n    *Default*: true\n    \n* `EnableSourceDeviceModels` - Allow adapters and data sources to supply Device \n  configuration\n\n    *Default*: false\n    \n* `Heartbeat` – Overrides the heartbeat interval sent back from the adapter in the \n   `* PONG \u003chb\u003e`. The heartbeat will always be this value in milliseconds.\n\n    *Default*: _None_\n    \n* `IgnoreTimestamps` - Overwrite timestamps with the agent time. This will correct\n  clock drift but will not give as accurate relative time since it will not take into\n  consideration network latencies. This can be overridden on a per adapter basis.\n  \n    *Default*: false\n\n* `LegacyTimeout`\t- The default length of time an adapter can be silent before it\n  is disconnected. This is only for legacy adapters that do not support heartbeats.\n\n    *Default*: 600\n\n* `PreserveUUID` - Do not overwrite the UUID with the UUID from the adapter, preserve\n  the UUID in the Devices.xml file. This can be overridden on a per adapter basis.\n\n    *Default*: true\n    \n* `ReconnectInterval` - The amount of time between adapter reconnection attempts. \n  This is useful for implementation of high performance adapters where availability\n  needs to be tracked in near-real-time. Time is specified in milliseconds (ms).\n      \n    *Default*: 10000\n      \n* `ShdrVersion` - Specifies the SHDR protocol version used by the adapter. When greater than one (1), \n  allows multiple complex observations, like `Condition` and `Message` on the same line. If it equials one (1), \n  then any observation requiring more than a key/value pair need to be on separate lines. This is the default for all adapters.\n\n    *Default*: 1\t\n\t\n* `UpcaseDataItemValue` - Always converts the value of the data items to upper case.\n\n    *Default*: true\n\n#### REST Service Configuration\n\n* `AllowPut`\t- Allow HTTP PUT or POST of data item values or assets.\n\n    *Default*: false\n\n* `AllowPutFrom`\t- Allow HTTP PUT or POST from a specific host or \n  list of hosts. Lists are comma (,) separated and the host names will\n  be validated by translating them into IP addresses.\n\n    *Default*: none\n    \n* `HttpHeaders`     - Additional headers to add to the HTTP Response for CORS Security\n\n    \u003e Example: ```\n    \u003e HttpHeaders {\n    \u003e   Access-Control-Allow-Origin = *\n    \u003e   Access-Control-Allow-Methods = GET\n    \u003e   Access-Control-Allow-Headers = Content-Type\n    \u003e }```\n\n* `Port`\t- The port number the agent binds to for requests.\n\n    *Default*: 5000\n    \n* `ServerIp` - The server IP Address to bind to. Can be used to select the interface in IPV4 or IPV6.\n\n    *Default*: 0.0.0.0\n\n\n#### Configuration Pameters for TLS (https) Support ####\n\nThe following parameters must be present to enable https requests. If there is no password on the certificate, `TlsCertificatePassword` may be omitted.\n\t\n* `TlsCertificateChain` - The name of the file containing the certificate chain created from signing authority\n\n    *Default*: *NULL*\n\n* `TlsCertificatePassword` -  The password used when creating the certificate. If none was supplied, do not use.\n\n    *Default*: *NULL*\n\n* `TlsClientCAs` - For `TlsVerifyClientCertificate`, specifies a file that contains additional certificate authorities for verification\n\n    *Default*: *NULL*\n    \n* `TlsDHKey` -  The name of the file containing the Diffie–Hellman key\n\n    *Default*: *NULL*\n\n* `TlsOnly` -  Only allow secure connections, http requests will be rejected\n\n    *Default*: `false`\n\n* `TlsPrivateKey` -  The name of the file containing the private key for the certificate\n\n    *Default*: *NULL*\n\n* `TlsVerifyClientCertificate` - Request and verify the client certificate against root authorities\n\n    *Default*: false\n\n### MQTT Configuration\n\n* `MqttCaCert` - CA Certificate for MQTT TLS connection to the MTT Broker\n\n    *Default*: *NULL*\n\n* `MqttHost` - IP Address or name of the MQTT Broker\n\n    *Default*: 127.0.0.1\n  \n* `MqttPort` - Port number of MQTT Broker\n\n    *Default*: 1883\n  \n* `MqttTls` - TLS Certificate for secure connection to the MQTT Broker\n\n    *Default*: `false`\n\n* `MqttWs` - Instructs MQTT to connect using web sockets\n\n    *Default*: `false`\n\n#### MQTT Sink\n\nEnabled in `agent.cfg` by specifying:\n\n```\nSinks {\n  MqttService {\n    # Configuration Options below...\n  }\n}\n```\n\n* `DeviceTopic` - Prefix for the Device Model topic\n\n    *Default*: `MTConnect/Device/`\n\n* `ObservationTopic` - Prefix for the Streams events, samples, and conditions\n\n    *Default*: `MTConnect/Observation/`\n\n* `AssetTopic` - Prefix for the Assets\n\n    *Default*: `MTConnect/Asset/`\n\n#### MQTT Sink 2\n\nEnabled in `agent.cfg` by specifying:\n\n```\nSinks {\n  Mqtt2Service {\n    # Configuration Options...\n  }\n}\n```\n\n* `AssetTopic` - Prefix for the Assets\n\n    *Default*: `MTConnect/Asset/[device]`\n    \n* `CurrentTopic` - Prefix for the Current \n\n    *Default*: `MTConnect/Current/[device]`\n\n* `ProbeTopic` or `DeviceTopic` - Prefix for the Device Model topic\n\n    \u003e Note: `[device]` will be replaced with the uuid of each device. Other patterns can be created, \n    \u003e for example: `MTConnect/[device]/Probe` will group by device instead of operation.\n    \u003e `DeviceTopic` will also work.\n\n    *Default*: `MTConnect/Probe/[device]`\n\n* `SampleTopic` - Prefix for the Sample \n\n    *Default*: `MTConnect/Sample/[device]`\n\n* `MqttLastWillTopic` - The topic used for the last will and testement for an agent\n\n    \u003e Note: The value will be `AVAILABLE` when the Agent is publishing and connected and will\n    \u003e publish `UNAVAILABLE` when the agent disconnects from the broker.\n\n    *Default*: `MTConnect/Probe/[device]/Availability\"`\n\n* `MqttCurrentInterval` - The frequency to publish currents. Acts like a keyframe in a video stream.\n\n    *Default*: 10000ms\n    \n* `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.\n\n    *Default*: 500ms\n\n* `MqttSampleCount` - The maxmimum number of observations to publish at one time.\n\n    *Default*: 1000\n    \n* `MqttRetain` - For the MQTT Sinks, sets the retain flag for publishing.\n\n    *Default*: True\n    \n* `MqttQOS`: - For the MQTT Sinks, sets the Quality of Service. Must be one of `at_least_once`, `at_most_once`, `exactly_once`.\n\n    *Default*: `at_least_once`\n    \n* `MqttXPath`: - The xpath filter to apply to all current and samples published to MQTT. If the XPath is invalid, it will fall back to publishing all data items.\n\n    *Default*: All data items\n\n### Adapter Configuration Items ###\n\n* `Adapters` - Contains a list of device blocks. If there are no Adapters\n  specified and the Devices file contains one device, the Agent defaults\n  to an adapter located on the localhost at port 7878.  Data passed from\n  the Adapter is associated with the default device.\n\n    *Default*: localhost 7878, associated with the default device\n\n    * `Device` - The name of the device that corresponds to the name of\n      the device in the Devices file. Each adapter can map to one\n      device. Specifying a \"*\" will map to the default device.\n\n        *Default*: The name of the block for this adapter or if that is\n        not found the default device if only one device is specified\n        in the devices file.\n\n    * `Host` - The host the adapter is located on.\n\n        *Default*: localhost\n\n    * `Port` - The port to connect to the adapter.\n\n        *Default*: 7878\n\n    * `Manufacturer` - Replaces the manufacturer attribute in the device XML.\n\n        *Default*: Current value in device XML.\n\n    * `Station` - Replaces the Station attribute in the device XML.\n\n        *Default*: Current value in device XML.\n\n    * `SerialNumber` - Replaces the SerialNumber attribute in the device XML.\n\n        *Default*: Current value in device XML.\n        \n    * `UUID` - Replaces the UUID attribute in the device XML.\n\n        *Default*: Current value in device XML.\n\n    * `AutoAvailable` - For devices that do not have the ability to provide available events, if `yes`, this sets the `Availability` to AVAILABLE upon connection.\n\n        *Default*: no (new in 1.2, if AVAILABILITY is not provided for device it will be automatically added and this will default to yes)\n\n    * `AdditionalDevices` - Comma separated list of additional devices connected to this adapter. This provides availability support when one adapter feeds multiple devices.\n\n        *Default*: nothing\n\n    * `FilterDuplicates` - If value is `yes`, filters all duplicate values for data items. This is to support adapters that are not doing proper duplicate filtering.\n\n        *Default*: no\n\n    * `LegacyTimeout` - length of time an adapter can be silent before it\n        is disconnected. This is only for legacy adapters that do not support \n        heartbeats. If heartbeats are present, this will be ignored.\n\n        *Default*: 600\n\n    * `ReconnectInterval` - The amount of time between adapter reconnection attempts. \n       This is useful for implementation of high performance adapters where availability\n       needs to be tracked in near-real-time. Time is specified in milliseconds (ms).\n       Defaults to the top level ReconnectInterval.\n      \n        *Default*: 10000\n        \n    * `IgnoreTimestamps` - Overwrite timestamps with the agent time. This will correct\n      clock drift but will not give as accurate relative time since it will not take into\n      consideration network latencies. This can be overridden on a per adapter basis.\n\n        *Default*: Top Level Setting\n        \n    * `PreserveUUID` - Do not overwrite the UUID with the UUID from the adapter, preserve\n\t\t  the UUID in the Devices.xml file. This can be overridden on a per adapter basis.\n\n\t\t    *Default*: false\n\t\t\n    * `RealTime` - Boost the thread priority of this adapter so that events are handled faster.\n\n        *Default*: false\n    \n    * `RelativeTime` - The timestamps will be given as relative offsets represented as a floating \n      point number of milliseconds. The offset will be added to the arrival time of the first \n      recorded event.\n\n        *Default*: false\n\n    * `ConversionRequired` - Adapter setting for data item units conversion in the agent. \n      Assumes the adapter has already done unit conversion. Defaults to global.\n\n        *Default*: Top Level Setting\n        \n    * `UpcaseDataItemValue` - Always converts the value of the data items to upper case.\n\n        *Default*: Top Level Setting\n\n    * `ShdrVersion` - Specifies the SHDR protocol version used by the adapter. When greater than one \n      (1), allows  multiple complex observations, like `Condition` and `Message` on the same line. \n      If it equials one (1), then any observation requiring more than a key/value pair need to be on \n      separate lines. Applies to only this adapter.\n\n\t    *Default*: 1\n\n    * `SuppressIPAddress` - Suppress the Adapter IP Address and port when creating the Agent Device ids and names.\n      \n        *Default*: false\n\t\t\n\t* `AdapterIdentity` - Adapter Identity name used to prefix dataitems within the Agent device ids and names.\n\n        *Default*:\n\t\t* If `SuppressIPAddress` == false:\\\n\t\t`AdapterIdentity` = ```_ {IP}_{PORT}```\\\n\t\texample:`_localhost_7878`\n\n\t\t* If `SuppressIPAddress` == true:\\\n\t\t`AdapterIdentity` = ```_ sha1digest({IP}_{PORT})```\\\n\t\texample: `__71020ed1ed`\n\n#### MQTT Adapter/Source\n\n* `MqttHost` - IP Address or name of the MQTT Broker\n\n    *Default*: 127.0.0.1\n  \n* `MqttPort` - Port number of MQTT Broker\n\n    *Default*: 1883\n\n* `topics` - list of topics to subscribe to. Note : Only raw SHDR strings supported at this time\n\n    *Required*\n\n* `MqttClientId` - Port number of MQTT Broker\n\n    *Default*: Auto-generated\n\n\t\u003e **⚠️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`\n\t\u003e\n\n\tExample mqtt adapter block:\n\t```json\n\tmydevice {\n\t\t\tProtocol = mqtt\n\t\t\tMqttHost = localhost\n\t\t\tMqttPort = 1883\n\t\t\tMqttClientId = myUniqueID\n\t\t\tTopics = /ingest\n\t\t}\n\t```\n\n* `AdapterIdentity` - Adapter Identity name used to prefix dataitems within the Agent device ids and names.\n\n\t*Default*:\n\t* If `SuppressIPAddress` == false:\\\n\t`AdapterIdentity` = ```_ {IP}_{PORT}```\\\n\texample:`_localhost_7878`\n\n\t* If `SuppressIPAddress` == true:\\\n\t`AdapterIdentity` = ```_ sha1digest({IP}_{PORT})```\\\n\texample: `__71020ed1ed`\n\n### Agent Adapter Configuration\n\n* `Url` - The URL of the source agent. `http:` or `https:` are accepted for the protocol.\n* `SourceDevice` – The Device name or UUID for the source of the data\n* `Count` – the number of items request during a single sample\n\n    *Default*: 1000  \n    \n* `Polling Interval` – The interval used for streaming or polling in milliseconds\n\n    *Default*: 500ms\n    \n* `Reconnect Interval` – The interval between reconnection attampts in milliseconds\n\n    *Default*: 10000ms\n    \n* `Use Polling` – Force the adapter to use polling instead of streaming. Only set to `true` if x-multipart-replace blocked.\n\n    *Default*: false\n    \n* `Heartbeat` – The heartbeat interval from the server\n\n    *Default*: 10000ms\n\nlogger_config configuration items\n-----\n\n* `logger_config` - The logging configuration section.\n\n    * `logging_level` - The logging level: `trace`, `debug`, `info`, `warn`,\n        `error`, or `fatal`.\n\n        *Default*: `info`\n\n        Note: when running Agent with `agent debug`, `logging_level` will be set to `debug`.\n\n    * `output` - The output file or stream. If using a file, specify\n      as: `\"file \u003cfilename\u003e\"`. cout and cerr can be used to specify the\n      standard output and standard error streams. *Default*s to the same\n      directory as the executable.\n\n        *Default*: file `adapter.log`\n        \n    * `max_size` - The maximum log file size. Suffix can be K for kilobytes, M for megabytes, or\n      G for gigabytes. No suffix will default to bytes (B). Case is ignored.\n    \n        *Default*: 10M\n        \n    * `max_index` - The maximum number of log files to keep.\n\n        *Default*: 9\n        \n    * `schedule` - The scheduled time to start a new file. Can be DAILY, WEEKLY, or NEVER.\n            \n        *Default*: NEVER\n    \n# Agent-Adapter Protocols\n## SHDR Version 2.0\n\nThe 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.\n\nA simple set of events and samples will look something like this:\n\n\t2009-06-15T00:00:00.000000|power|ON|execution|ACTIVE|line|412|Xact|-1.1761875153|Yact|1766618937\n\nA 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:\n\nIf 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:\n\n        2009-06-15T00:00:00.000000|description|\"Text with \\| (pipe) character.\"\n\nConditions require six (6) fields as follows:\n\n\t\u003ctimestamp\u003e|\u003cdata_item_name\u003e|\u003clevel\u003e|\u003cnative_code\u003e|\u003cnative_severity\u003e|\u003cqualifier\u003e|\u003cmessage\u003e\n\t\n\tCondition id and native code are set to the same value given as \u003cnative_code\u003e\n\n\t\u003ctimestamp\u003e|\u003cdata_item_name\u003e|\u003clevel\u003e|\u003cnative_code\u003e:\u003ccondition_id\u003e|\u003cnative_severity\u003e|\u003cqualifier\u003e|\u003cmessage\u003e\n\t\n\tCondition id is set to condition_id and native code is set to native_code\n\t\n\t\u003ctimestamp\u003e|\u003cdata_item_name\u003e|\u003clevel\u003e|\u003ccondition_id\u003e|\u003cnative_severity\u003e|\u003cqualifier\u003e|\u003cmessage\u003e\n\t\n\tCondition id is set to condition_id and native code is not set\n\t\n\t\nFor a complete description of these fields, see the standard. An example line will look like this:\n\n\t2014-09-29T23:59:33.460470Z|htemp|WARNING|HTEMP-1-HIGH|HTEMP|1|HIGH|Oil Temperature High\n\t\nThe next special format is the Message. There is one additional field, native_code, which needs to be included:\n\n\t2014-09-29T23:59:33.460470Z|message|CHG_INSRT|Change Inserts\n\t\nTime 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:\n\n\t2014-09-29T23:59:33.460470Z|current|10|100|1 2 3 4 5 6 7 8 9 10\n\nThe 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`:\n\n\t2014-09-29T23:59:33.460470Z|device1:current|12|device2:current|11|device3:current|10\n\nAll data items follow the formatting requirements in the MTConnect standard for the vocabulary and coordinates like PathPosition.\n\nA 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:\n\n\t2014-09-29T23:59:33.460470Z|pcount|0:DAY\n\t\nTo specify the duration of the static, indicate it with an `@` sign after the timestamp as follows:\n\n\t2014-09-29T23:59:33.460470Z@100.0|pcount|0:DAY\n\t\n### `DATA_SET` Representation ###\n\nA 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:\n\n\t2014-09-29T23:59:33.460470Z|vars|v1=10 v2=20 v3=30\n\nThis will create a set of three values. To remove a value\n\n\t2014-09-29T23:59:33.460470Z|vars|v2 v3=\n\nThis 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.\n\n\t2014-09-29T23:59:33.460470Z|vars|:MANUAL\n\nThis will remove all the values from the current set. The set can also be reset to a specific set of values:\n\n\t2014-09-29T23:59:33.460470Z|vars|:MANUAL v5=1 v6=2\n\nThis will remove all the old values from the set and set the current set. Values will accumulate when addition pairs are given as in:\n\n\t2014-09-29T23:59:33.460470Z|vars|v8=1 v9=2 v5=10\n\nThis 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.\n\n\t2014-09-29T23:59:33.460470Z|vars|v8=1 v9=2 v5=0\n\nWill 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:\n\n\t2014-09-29T23:59:33.460470Z|vars|v8=1 v9=3 v5=10\n\nWill be effectively the same as specifying:\n\n\t2014-09-29T23:59:33.460470Z|vars|v9=2\n\nAnd the streams will only have the one value when a sample is request is made at that point in the stream.\n\nWhen 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.\n\nOne can quote values using the following methods: `\"\u003ctext\u003e\"`, `'\u003ctext\u003e'`, and `{\u003ctext\u003e}`. 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\"`.\n\n### `TABLE` Representation ###\n\nA `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:\n\n    \u003ctimestamp\u003e|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}\n\nUsing 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.\n\nAll the reset rules of data set apply to tables and the values are treated as a unit.\n\n## Assets\n\nAssets 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:\n\n\t2012-02-21T23:59:33.460470Z|@ASSET@|KSSP300R.1|CuttingTool|\u003cCuttingTool\u003e...\n\nThis 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:\n\n\t\t2012-02-21T23:59:33.460470Z|@ASSET@|KSSP300R.1|CuttingTool|--multiline--0FED07ACED\n\t\t\u003cCuttingTool\u003e\n\t\t...\n\t\t\u003c/CuttingTool\u003e\n\t\t--multiline--0FED07ACED\n\t\t\nThe 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:\n\n\t2012-02-21T23:59:33.460470Z|@REMOVE_ASSET@|KSSP300R.1\n\nOr all assets can be removed in one shot for a certain asset type:\n\n\t2012-02-21T23:59:33.460470Z|@REMOVE_ALL_ASSETS@|CuttingTool\n\nPartial 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:\n\n\t2012-02-21T23:59:33.460470Z|@UPDATE_ASSET@|KSSP300R.1|OverallToolLength|323.64|CuttingDiameterMax|76.211\n\n## MQTT JSON Ingress Protocol Version 2.0\n\nIn general the data format is {\"timestamp\": \"YYYY-MM-DDThh:mm:ssZ\",\"dataItemId\":\"value\", \"dataItemId\":{\"key1\":\"value1\", ..., \"keyn\":\"valuen}} \n\n**NOTE**: See the standard for the complete description of the fields for the data item representations below.\n\nA simple set of events and samples will look something like this:\n\n```json\n{\n\t\"timestamp\": \"2023-11-06T12:12:44Z\",\t\t\t//Time Stamp\n\t\"tempId\": 22.6,\t\t\t\t\t\t\t\t//Temperature\n\t\"positionId\": 1002.345,\t\t\t\t\t\t//X axis position\n\t\"executionId\": \"ACTIVE\"\t\t\t\t\t\t//Execution state\n}\n```\n\t\nA `CONDITION` requires the key to be the dataItemId and requires the 6 fields as shown in the example below\n\n```json\n{\n\t\"timestamp\": \"2023-11-06T12:12:44Z\",\n\t\"dataItemId\": {\n\t\t\"level\": \"fault\",\n\t\t\"conditionId\":\"ac324\",\n\t\t\"nativeSeverity\": \"1000\",\n\t\t\"qualifier\": \"HIGH\",\n\t\t\"nativeCode\": \"ABC\",\n\t\t\"message\": \"something went wrong\"\n\t}\n}\n```\nA `MESSAGE` requires the key to be the dataItemId and requires the nativeCode field as shown in the example below\n\n```json\n{\n\t\"timestamp\": \"2023-11-06T12:12:44Z\",\n\t\"messsageId\": {\n\t\t\"nativeCode\": \"ABC\",\n\t\t\"message\": \"something went wrong\"\n\t}\n}\n```\n\t\nThe `TimeSeries` `REPRESENTATION` requires the key to be the dataItemId and requires 2 fields \"count\" and \"values\" and 1 to n comma delimited values.  \n\u003e**NOTE**: The \"frequency\" field is optional.\n\n```json\n{\n\t\"timestamp\": \"2023-11-06T12:12:44Z\",\n\t\"timeSeries1\": {\n\t\t\"count\": 10,\n\t\t\"frequency\": 100,\n\t\t\"values\": [1,2,3,4,5,6,7,8,9,10]\n\t}\n}\n```\nThe `DataSet` `REPRESENTATION` requires the the dataItemId as the key and the \"values\" field.   It may also have the optional \"resetTriggered\" field.\n\n```json\n{\n{\n\t\"timestamp\": \"2023-11-09T11:20:00Z\",\n\t\"dataSetId\": {\n\t\t\"key1\": 123,\n\t\t\"key2\": 456,\n\t\t\"key3\": 789\n\t}\n}\n```\n\nExample with the optional \"resetTriggered\" filed:\t\n\n```json\n{\n\t\"timestamp\": \"2023-11-09T11:20:00Z\",\n\t\"cncregisterset1\": {\n\t\t\"resetTriggered\": \"NEW\",\n\t\t\"value\": {\"r1\":\"v1\", \"r2\":\"v2\", \"r3\":\"v3\" }\n\t}\n}\n```\n\nThe `Table` `REPRESENTATION` requires the the dataItemId as the key and the \"values\" field.   It may also have the optional \"resetTriggered\" field.\n\n```json\n\n{\n\t\"timestamp\":\"2023-11-06T12:12:44Z\",\n\t\"tableId\":{\n\t\t\"row1\":{\n\t\t\"cell1\":\"Some Text\",\n\t\t\"cell2\":3243\n\t\t},\n\t\t\"row2\": {\n\t\t\"cell1\":\"Some Other Text\",\n\t\t\"cell2\":243        \n\t\t}      \n\t}\n}\n```\n\nExample with the optional resetTriggered field:\n\n```json\n{\n\t\"timestamp\": \"2023-11-09T11:20:00Z\",\n\t\"a1\": {\n\t\t\"resetTriggered\": \"NEW\",\n\t\t\"value\": {\n\t\t\t\"r1\": {\n\t\t\t\t\"k1\": 123.45,\n\t\t\t\t\"k3\": 6789\n\t\t\t},\n\t\t\t\"r2\": null\n\t\t}\n\t}\n}\n```\n\n## Adapter Commands\nThere are a number of commands that can be sent as part of the adapter stream over the SHDR port connection. 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 \u003ckey\u003e: \u003cvalue\u003e. They are as follows:\n\n* Specify the Adapter Software Version the adapter supports:\n\n\t`* adapterVersion: \u003cversion\u003e`\n\n* Set the calibration in the device component of the associated device:\n \n\t`* calibration: XXX`\n\n* Tell the agent that the data coming from this adapter requires conversion:\n \n\t`* conversionRequired: \u003cyes|no\u003e`\n\n* Set the description in the device header of the associated device:\n \n\t`* description: XXX`\n\n* Specify the default device for this adapter. The device can be specified as either the device name or UUID:\n\n\t`* device: \u003cuuid|name\u003e`\n\n* Tell the agent to load a new device XML model:\n\n\t`* devicemodel: \u003cdeviceXML\u003e`\n\n* Set the manufacturer in the device header of the associated device:\n \n\t`* manufacturer: XXX`\n\n* Specify the MTConnect Version the adapter supports:\n\n\t`* mtconnectVersion: \u003cversion\u003e`\n\n* Set the nativeName in the device component of the associated device:\n \n\t`* nativeName: XXX`\n\n* Tell the agent that the data coming from this adapter would like real-time priority:\n \n\t`* realTime: \u003cyes|no\u003e`\n\n* Tell the agent that the data coming from this adapter is specified in relative time:\n \n\t`* relativeTime: \u003cyes|no\u003e`\n\n* Set the serialNumber in the device header of the associated device:\n \n\t`* serialNumber: XXX`\n\n* Specify the version of the SHDR protocol delivered by the adapter. See `ShdrVersion` above:\n\n\t`* shdrVersion: \u003cversion\u003e`\n\n* Set the station in the device header of the associated device:\n \n\t`* station: XXX`\n\n* Set the uuid in the device header of the associated device if preserveUuid = false:\n \n\t`* uuid: XXX`\n\nAny other command will be logged as a warning.\n\n## Heartbeat Protocol\n\nThe 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 \u003ctimeout\u003e` where `\u003ctimeout\u003e` is specified in milliseconds. So if the following communications are given:\n\nAgent:\n\n\t* PING\n\nAdapter:\n\n\t* PONG 10000\n\nThis 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.\n\t\nJust as with the SHDR protocol, these messages must end with an LF (ASCII 10) or CR-LF (ASCII 15 followed by ASCII 10).\n\nHTTP PUT/POST Method of Uploading Data\n-----\n\nThere 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\nmachines, you can list the IP Addresses that are allowed to `POST` data to the agent. \n\nAn example would be:\n\n    AllowPut = yes\n    AllowPutFrom = 192.168.1.72, 192.168.1.73\n  \nThis 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.\n\nFor 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 `\u003cdata_item_name\u003e=\u003cdata_item_value\u003e` to set the values, as follows:\n\n    curl -d 'avail=AVAILABLE\u0026program_1=XXX' 'http://localhost:5000/ExampleDevice'\n    \nBy 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:\n\n    \u003cAvailability dataItemId=\"dtop_3\" timestamp=\"2015-05-18T18:20:12.278236Z\" name=\"avail\" sequence=\"65\"\u003eAVAILABLE\u003c/Availability\u003e\n    ...\n    \u003cProgram dataItemId=\"path_51\" timestamp=\"2015-05-18T18:20:12.278236Z\" name=\"program_1\" sequence=\"66\"\u003eXXX\u003c/Program\u003e\n    \nThe full raw data being passed over looks like this:\n\n    =\u003e Send header, 161 bytes (0xa1)\n    0000: POST /ExampleDevice HTTP/1.1\n    001e: User-Agent: curl/7.37.1\n    0037: Host: localhost:5000\n    004d: Accept: */*\n    005a: Content-Length: 29\n    006e: Content-Type: application/x-www-form-urlencoded\n    009f: \n    =\u003e Send data, 29 bytes (0x1d)\n    0000: avail=AVAILABLE\u0026program_1=XXX\n    == Info: upload completely sent off: 29 out of 29 bytes\n    == Info: HTTP 1.0, assume close after body\n    \u003c= Recv header, 17 bytes (0x11)\n    0000: HTTP/1.0 200 OK\n    \u003c= Recv header, 20 bytes (0x14)\n    0000: Content-Length: 10\n    \u003c= Recv header, 24 bytes (0x18)\n    0000: Content-Type: text/xml\n    \u003c= Recv header, 2 bytes (0x2)\n    0000: \n    \u003c= Recv data, 10 bytes (0xa)\n    0000: \u003csuccess/\u003e\n    \u003e== Info: Closing connection 0\n    \nThis is using the --trace - to dump the internal data. The response will be a simple `\u003csuccess/\u003e` or `\u003cfail/\u003e`.\n    \nAny data item can be set in this fashion. Similarly conditions are set using the following syntax:\n\n    curl -d 'system=fault|XXX|1|LOW|Feeling%20low' 'http://localhost:5000/ExampleDevice'\n    \nOne thing to note, the data and values are URL encoded, so the space needs to be encoded as a %20 to appear correctly. \n\n    \u003cFault dataItemId=\"controller_46\" timestamp=\"2015-05-18T18:24:48.407898Z\" name=\"system\" sequence=\"67\" nativeCode=\"XXX\" nativeSeverity=\"1\" qualifier=\"LOW\" type=\"SYSTEM\"\u003eFeeling Low\u003c/Fault\u003e\n\nAssets 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:\n\n    curl -d @B732A08500HP.xml 'http://localhost:5000/asset/B732A08500HP.1?device=ExampleDevice\u0026type=CuttingTool'\n\nThe @... 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.\n\nProgrammatically, 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: \n\n    =\u003e Send header, 230 bytes (0xe6)\n    0000: POST /asset/B732A08500HP.1?device=ExampleDevice\u0026type=CuttingTool\n    0040:  HTTP/1.1\n    004b: User-Agent: curl/7.37.1\n    0064: Host: localhost:5000\n    007a: Accept: */*\n    0087: Content-Length: 2057\n    009d: Content-Type: application/x-www-form-urlencoded\n    00ce: Expect: 100-continue\n    00e4: \n    == Info: Done waiting for 100-continue\n    =\u003e Send data, 2057 bytes (0x809)\n    0000: (file data sent here, see below...)\n    == Info: HTTP 1.0, assume close after body\n    \u003c= Recv header, 17 bytes (0x11)\n    0000: HTTP/1.0 200 OK\n    \u003c= Recv header, 20 bytes (0x14)\n    0000: Content-Length: 10\n    \u003c= Recv header, 24 bytes (0x18)\n    0000: Content-Type: text/xml\n    \u003c= Recv header, 2 bytes (0x2)\n    0000: \n    \u003c= Recv data, 10 bytes (0xa)\n    0000: \u003csuccess/\u003e\n    \u003csuccess/\u003e== Info: Closing connection 0\n\nThe file that was included looks like this:\n\n    \u003cCuttingTool serialNumber=\"1 \" toolId=\"B732A08500HP\" timestamp=\"2011-05-11T13:55:22\" assetId=\"B732A08500HP.1\" manufacturers=\"KMT\"\u003e\n    \t\u003cDescription\u003e\n    \t\tStep Drill KMT, B732A08500HP Grade KC7315\n    \t\tAdapter KMT CV50BHPVTT12M375\n    \t\u003c/Description\u003e\n    \t\u003cCuttingToolLifeCycle\u003e\n    \t\t\u003cCutterStatus\u003e\u003cStatus\u003eNEW\u003c/Status\u003e\u003c/CutterStatus\u003e\n    \t\t\u003cProcessSpindleSpeed nominal=\"5893\"\u003e5893\u003c/ProcessSpindleSpeed\u003e\n    \t\t\u003cProcessFeedRate nominal=\"2.5\"\u003e2.5\u003c/ProcessFeedRate\u003e\n    \t\t\u003cConnectionCodeMachineSide\u003eCV50 Taper\u003c/ConnectionCodeMachineSide\u003e\n    \t\t\u003cMeasurements\u003e\n    \t\t\t\u003cBodyDiameterMax code=\"BDX\"\u003e31.8\u003c/BodyDiameterMax\u003e\n    \t\t\t\u003cBodyLengthMax code=\"LBX\" nominal=\"120.825\" maximum=\"126.325\" minimum=\"115.325\"\u003e120.825\u003c/BodyLengthMax\u003e\n    \t\t\t\u003cProtrudingLength code=\"LPR\" nominal=\"155.75\" maximum=\"161.25\" minimum=\"150.26\"\u003e158.965\u003c/ProtrudingLength\u003e\n    \t\t\t\u003cFlangeDiameterMax code=\"DF\" nominal=\"98.425\"\u003e98.425\u003c/FlangeDiameterMax\u003e\n    \t\t\t\u003cOverallToolLength nominal=\"257.35\" minimum=\"251.85\" maximum=\"262.85\" code=\"OAL\"\u003e257.35\u003c/OverallToolLength\u003e\n    \t\t\u003c/Measurements\u003e\n    \t\t\u003cCuttingItems count=\"2\"\u003e\n    \t\t\t\u003cCuttingItem indices=\"1\" manufacturers=\"KMT\" grade=\"KC7315\"\u003e\n    \t\t\t\t\u003cMeasurements\u003e\n    \t\t\t\t\t\u003cCuttingDiameter code=\"DC1\" nominal=\"8.5\" maximum=\"8.521\" minimum=\"8.506\"\u003e8.513\u003c/CuttingDiameter\u003e\n    \t\t\t\t\t\u003cStepIncludedAngle code=\"STA1\" nominal=\"90\" maximum=\"91\" minimum=\"89\"\u003e89.8551\u003c/StepIncludedAngle\u003e\n    \t\t\t\t\t\u003cFunctionalLength code=\"LF1\" nominal=\"154.286\" minimum=\"148.786\" maximum=\"159.786\"\u003e157.259\u003c/FunctionalLength\u003e\n    \t\t\t\t\t\u003cStepDiameterLength code=\"SDL1\" nominal=\"9\"\u003e9\u003c/StepDiameterLength\u003e\n    \t\t\t\t\t\u003cPointAngle code=\"SIG\" nominal=\"135\" minimum=\"133\" maximum=\"137\"\u003e135.1540\u003c/PointAngle\u003e\n    \t\t\t\t\u003c/Measurements\u003e\n    \t\t\t\u003c/CuttingItem\u003e\n    \t\t\t\u003cCuttingItem indices=\"2\" manufacturers=\"KMT\" grade=\"KC7315\"\u003e\n    \t\t\t\t\u003cMeasurements\u003e\n    \t\t\t\t\t\u003cCuttingDiameter code=\"DC2\" nominal=\"12\" maximum=\"12.011\" minimum=\"12\"\u003e11.999\u003c/CuttingDiameter\u003e\n    \t\t\t\t\t\u003cFunctionalLength code=\"LF2\" nominal=\"122.493\" maximum=\"127.993\" minimum=\"116.993\"\u003e125.500\u003c/FunctionalLength\u003e\n    \t\t\t\t\t\u003cStepDiameterLength code=\"SDL2\" nominal=\"9\"\u003e9\u003c/StepDiameterLength\u003e\n    \t\t\t\t\u003c/Measurements\u003e\n    \t\t\t\u003c/CuttingItem\u003e\n    \t\t\u003c/CuttingItems\u003e\n    \t\u003c/CuttingToolLifeCycle\u003e\n    \u003c/CuttingTool\u003e\n\nAn example in ruby is as follows:\n\n    \u003e require 'net/http'\n    =\u003e true\n    \u003e h = Net::HTTP.new('localhost', 5000)\n    =\u003e #\u003cNet::HTTP localhost:5000 open=false\u003e\n    \u003e r = h.post('/asset/B732A08500HP.1?type=CuttingTool\u0026device=ExampleDevice', File.read('B732A08500HP.xml'))\n    =\u003e #\u003cNet::HTTPOK 200 OK readbody=true\u003e\n    \u003e r.body\n    =\u003e \"\u003csuccess/\u003e\"\n\t\n# Building the agent\n\n## Overview\n\nThe agent build is dependent on the following utilities:\n\n* C++ Compiler compliant with C++ 17\n* git is optional but suggested to download source and update when changes occur\n* cmake for build generator and testing\n* python 3 and pip to support conan for dependency and package management\n* ruby and rake for mruby to support building the embedded scripting engine [not required if -o with_ruby=False]\n\n## Conan MTConnect Options (set using `-o \u003coption\u003e=\u003cvalue\u003e`)\n\n* `agent_prefix`: Prefix the agent and agent_lib executable. For example `-o agent_prefix=mtc` create mtcagent.exe and mtcagent_lib.lib\n\n    *default*: ''\n\n* `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`.\n\n    *default*: False\n\n* `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`.\n\n    *default*: False\n\n* `fPIC`: Enables Position Independent Code on *NIX platforms allowing the machine code to be dynamically relocate on load. Values: `True` or `False`.\n\n    *default*: True\n\n* `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`. \n\n    *default*: False\n\n* `winver`: For windows, version of the minimum target operating system version. Defaults to Windows Vista.\n\n    *default*: 0x600\n\n* `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`. \n\n    *default*: False\n\n* `with_ruby`: Enable mruby extensions for dynamic scripting. Values: `True` or `False`. \n\n    *default*: True\n\n* `without_ipv6`: Disable IPV6 support when building on operating systems that disable IPV6 services. Some docker images disable IPV6. Values: `True` or `False`. \n\n    *default*: False\n\n* `cpack_destination`: The destination directory for the package\n\n   *default*: _Package build directory_\n\n* `cpack_name`: The name of the package generated by cpack\n\n   *default*: _Default package name: agent_{version}_{OS}_\n\n* `cpack_generator`:\n\n    *default*: `ZIP` for windows and `TGZ` for *NIX\n\n\n### Conan useful settings (set using `-s \u003csetting\u003e=\u003cvalue\u003e`)\n\n* `build_type`: Changes the debug or release build type. Values: `Release`, `Debug`, `RelWithDebInfo`, and `MinSizeRel`. See CMake documentation for explanations.\n\n    *default*: `Release`\n    \n### Conan useful configurations (set using `-c \u003cconfig\u003e=\u003cvalue\u003e`)\n\n* `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.\n\n    *default*: `False`\n\n* `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.\n\n    *default*: _number of processes_\n\n## Building on Windows\n\nThe MTConnect Agent uses the conan package manager to install dependencies:\n\n  [python 3](https://www.python.org/downloads/) and [Conan Package Manager Downloads](https://conan.io/downloads.html)\n\nDownload the Windows installer for your platform and run the installer.\n\nYou also need [git](https://git-scm.com/download/win) and [ruby](https://rubyinstaller.org) if you want to embed mruby.\n\nCMake is installed as part of Visual Studio. If you are using Visual Studio for the build, use the bundled version. Otherwise download from CMake [CMake](https://cmake.org/download/).\n\n### Setting up build\n\nInstall dependencies from the downloads above. Make sure python, ruby, and cmake are in your path.\n\n\tpip install --upgrade pip\n\tpip install conan\n\nClone the agent to another directory:\n\n\tgit clone https://github.com/mtconnect/cppagent.git\n\t\n####  To build for 64 bit Windows\n\nThe 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.\n\t\nMake sure to setup the environment:\n\n    \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Professional\\VC\\Auxiliary\\Build\\vcvars64.bat\"\n\nor\n\n    \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat\"\n   \tconan create cppagent -pr cppagent/conan/profiles/vs64 --build=missing -o cpack=True -o zip_destination=.\n\n#### To build for 32 bit Windows\n\n    \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Professional\\VC\\Auxiliary\\Build\\vcvars32.bat\"\n\nor\n\n    \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars32.bat\"\n   \tconan create cppagent -pr cppagent/conan/profiles/vs32 --build=missing -o cpack=True -o zip_destination=.\n\n## *NIX Builds\n\nThe minimum memory (main + swap) when building with on CPU is 3GB. Less than that will likely cause the build to fail.\n\nIf the build runs out of resources, there are two options, you can add swap or set the following command line option:\n\n    -c tools.build:jobs=1\n\t\nto instruct conan to not parallelize the builds. Some of the modules that include boost beast require significant resources to build.\n\n## Building on Ubuntu on 20.04 LTS\n\n### Setup the build\n\n    sudo apt install -y build-essential cmake gcc-11 g++-11 python3 python3-pip autoconf automake ruby ruby rake \n    python3 -m pip install conan\n    echo 'export PATH=$HOME/.local/bin:$PATH' \u003e\u003e .bashrc\n\n### Download the source\n\n\tgit clone https://github.com/mtconnect/cppagent.git\n\t\n### Build the agent\n\t\n\tconan create cppagent -pr cppagent/conan/profiles/gcc --build=missing\n\t\n## Building on Mac OS\n\nInstall brew and xcode command line tools\n\t\n\t/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"\n\txcode-select —install\n\n### Setup the build\n\n    brew install git\n    brew install cmake\n\tpip3 install conan\n\n### Download the source\n\n\tgit clone https://github.com/mtconnect/cppagent.git\n\t\n### Build the agent\n\t\n\tconan create cppagent -pr cppagent/conan/profiles/macos --build=missing\n    \n### Generate an xcode project for debugging\n\t\n\tconan build . -pr conan/profiles/xcode -s build_type=Debug --build=missing -o development=True\n\n## Building on Fedora Alpine\n\n### As Root\n\n\tapk add g++ python3 cmake git linux-headers make perl ruby\n\tgem install rake\n\t\n\tpython3 -m ensurepip\n\tpython3 -m pip install --upgrade pip\n\n### As the user\n\t\n\texport PATH=~/.local/bin:$PATH\n\tpip3 install conan\t\n\tgit clone https://github.com/mtconnect/cppagent.git\n\n### Build the agent\n\n\tconan create cppagent -pr cppagent/conan/profiles/gcc --build=missing\n\n## For some examples, see the CI/CD workflows in `.github/workflows/build.yml`\n\n# Creating Test Certifications (see resources gen_certs shell script)\n\nThis 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.\n\nNOTE: The certificates must be generated with OpenSSL version 1.1.1 or later. LibreSSL 2.8.3 is not compatible with \n      more recent version of SSL on raspian (Debian).\n\n## Server Creating self-signed certificate chain\n\n### Create Signing authority key and certificate\n\n\topenssl 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\"\n\n### User Key\n\n    openssl genrsa -out user.key 3072\n\n#### Signing Request\n\n    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\"\n\n#### User Certificate using root signing certificate\n\n    openssl x509 -req -in user.csr -CA rootca.crt -CAkey rootca.key -CAcreateserial -out user.crt -days 3650\n\n### Create DH Parameters\n\n    openssl dhparam -out dh2048.pem 3072\n\n### Verify\n\n    openssl verify -CAfile rootca.crt rootca.crt\n    openssl verify -CAfile rootca.crt user.crt\n\n## Client Certificate\n\n### Create Signing authority key\n\n    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\"\n\n### Create client key\n\n    openssl genrsa -out client.key 3072\n\n### Create client signing request\n\n    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\"\n\n### Create Client Certificate\n\nFor client.cnf\n\n    basicConstraints = CA:FALSE\n    nsCertType = client, email\n    nsComment = \"OpenSSL Generated Client Certificate\"\n    subjectKeyIdentifier = hash\n    authorityKeyIdentifier = keyid,issuer\n    keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment\n    extendedKeyUsage = clientAuth, emailProtection\n\n### Create the cert\n\n    openssl x509 -req -in client.csr -CA clientca.crt -CAkey clientca.key -out client.crt -CAcreateserial -days 3650 -sha256 -extfile client.cnf\n\n### Verify\n\n    openssl verify -CAfile clientca.crt clientca.crt\n    openssl verify -CAfile clientca.crt client.crt\n\n# Docker\n\nSee [demo ](demo) or [docker](docker)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmtconnect%2Fcppagent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmtconnect%2Fcppagent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmtconnect%2Fcppagent/lists"}