Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
da9243c
List "Arduino_Opta_Blueprint" as dependendy, which in turn requires "…
aentinger Jul 23, 2024
d507ac1
Install Arduino_Opta_Blueprint and required dependencies for CI build.
aentinger Jul 23, 2024
939f2fe
Scan for and print number of expansion modules detected.
aentinger Jul 23, 2024
1290037
Iterate over all expansion modules and print type and I2C address.
aentinger Jul 23, 2024
b7cc798
Provide conversion of expansion type to string for easier reading.
aentinger Jul 23, 2024
cdb5bf4
Automatically register and expose mechanical relays of expansion boar…
aentinger Jul 24, 2024
5d4e58c
Expose solid state relays via OPC/UA.
aentinger Jul 24, 2024
8210d70
Creating intermediate object layer of digital expansion boards.
aentinger Jul 24, 2024
7e96288
Creating intermediate object layer of digital expansion boards / soli…
aentinger Jul 24, 2024
9078f8b
Fix: array was designed too small for holding the full expansion name.
aentinger Jul 24, 2024
831febc
Expose general purpose inputs/outputs via OPC/UA.
aentinger Jul 25, 2024
d5f48a1
Group functionality for analog inputs under new subfolder io/analog.
aentinger Jul 25, 2024
2a34f44
Group all relay related functionality under new sub-folder "io/relay".
aentinger Jul 25, 2024
6e917f8
Group all LED related functionality under sub-folder "io/led".
aentinger Jul 25, 2024
6537421
Group digital input related code under new sub-folder "io/digital".
aentinger Jul 25, 2024
35b53f8
Move button related functionality under "io/button".
aentinger Jul 25, 2024
e4a7bb8
Move time related utility functions under "util\time".
aentinger Jul 25, 2024
a150e97
Move o1heap into subfolder "util".
aentinger Jul 25, 2024
2aa7700
Move all open62541 support code into subfolder open62541.
aentinger Jul 25, 2024
9212c9e
Move expansion related code under sub-folder "expansion".
aentinger Jul 25, 2024
be4aaf8
Considerably clean up digital expansion code by moving common code to…
aentinger Jul 25, 2024
a24fc6d
Register digital inputs via OPC/UA.
aentinger Jul 25, 2024
4d00402
Unify code that's shared between mechamical and solid state expansion…
aentinger Jul 26, 2024
8355711
Prefix inputs with "I" where applicable, to match markings on the cas…
aentinger Jul 26, 2024
e7a8c63
Move Arduino Opta Expansion boards up to the same hierarchical level …
aentinger Jul 26, 2024
46935e6
Move stringify related code ("toStr") into subfolder of "util".
aentinger Jul 26, 2024
efcaa8b
Drop the Arduino prefix since it adds no added value (just makes the …
aentinger Jul 26, 2024
6f43859
Extract glue code into separately compiled file "glue.cpp".
aentinger Jul 26, 2024
e8235f3
Extract o1heap_wrapper glue code into separate module.
aentinger Jul 26, 2024
9d0e2dc
Implement model name, manufacturer name and status to be displayed fo…
aentinger Jul 26, 2024
3b46184
Fix: regression, relays are not marked with "I".
aentinger Jul 26, 2024
38abe0d
Lay groundwork for exposing analog expansion as well.
aentinger Jul 26, 2024
e6ff951
Write full name incl Arduino Opta for object node name.
aentinger Jul 26, 2024
29edc1d
Fix: can and should reinterpret cast to base class.
aentinger Jul 30, 2024
238cb0f
Opta: display model name as object node name and SKU as ModelName.
aentinger Jul 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/compile-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ jobs:
with:
fqbn: ${{ matrix.board.fqbn }}
platforms: ${{ matrix.board.platforms }}
libraries: |
- source-path: ./
- name: Arduino_Opta_Blueprint
- name: Arduino_SerialUpdater
- name: Arduino_DebugUtils
enable-deltas-report: true
github-token: ${{ secrets.GITHUB_TOKEN }}
sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }}
Expand Down
261 changes: 112 additions & 149 deletions examples/opcua_server/opcua_server.ino

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions library.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ url=https://github.com/bcmi-labs/Arduino_open62541
ldflags=-lopen62541
includes=Arduino_open62541.h
precompiled=true
depends=Arduino_Opta_Blueprint
14 changes: 9 additions & 5 deletions src/Arduino_open62541.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,16 @@
**************************************************************************************/

#include "open62541.h"
#include "o1heap/o1heap.h"
#include "NTPUtils.h"
#include "cvt_time.h"

#include "ArduinoOpta.h"
#include "ArduinoOptaVariant.h"
#include "util/o1heap/o1heap.h"
#include "util/o1heap/o1heap_wrapper.h"
#include "util/time/cvt_time.h"
#include "util/time/NTPUtils.h"
#include "util/toStr/ExpansionType.h"

#include "Opta.h"
#include "OptaVariant.h"
#include "OptaExpansionManager.h"

/**************************************************************************************
* DEFINES
Expand Down
40 changes: 20 additions & 20 deletions src/ArduinoOpta.cpp → src/Opta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* INCLUDE
**************************************************************************************/

#include "ArduinoOpta.h"
#include "Opta.h"

/**************************************************************************************
* NAMESPACE
Expand All @@ -24,7 +24,7 @@ namespace opcua
* CTOR/DTOR
**************************************************************************************/

ArduinoOpta::ArduinoOpta(UA_Server * server, UA_NodeId const & node_id)
Opta::Opta(UA_Server * server, UA_NodeId const & node_id)
: _server{server}
, _node_id{node_id}
, _analog_input_mgr{nullptr}
Expand All @@ -34,33 +34,33 @@ ArduinoOpta::ArduinoOpta(UA_Server * server, UA_NodeId const & node_id)
{
_usr_button = opcua::UserButton::create(_server, _node_id);
if (!_usr_button)
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "ArduinoOpta::Ctor: UserButton::create(...) failed.");
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Opta::Ctor: UserButton::create(...) failed.");
}

/**************************************************************************************
* PUBLIC MEMBER FUNCTIONS
**************************************************************************************/

ArduinoOpta::SharedPtr ArduinoOpta::create(UA_Server * server, ArduinoOptaVariant::Type const opta_type)
Opta::SharedPtr Opta::create(UA_Server * server, OptaVariant::Type const opta_type)
{
UA_StatusCode rc = UA_STATUSCODE_GOOD;

UA_ObjectAttributes oAttr = UA_ObjectAttributes_default;
oAttr.displayName = UA_LOCALIZEDTEXT("en-US", "Arduino Opta");
oAttr.displayName = UA_LOCALIZEDTEXT("en-US", (char *)OptaVariant::toString(opta_type).c_str());
UA_NodeId node_id;
rc = UA_Server_addObjectNode(server,
UA_NODEID_NULL,
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
UA_QUALIFIEDNAME(1, "ArduinoOpta"),
UA_QUALIFIEDNAME(1, "Opta"),
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),
oAttr,
NULL,
&node_id);
if (UA_StatusCode_isBad(rc))
{
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
"ArduinoOpta::create: UA_Server_addObjectNode(...) failed with %s",
"Opta::create: UA_Server_addObjectNode(...) failed with %s",
UA_StatusCode_name(rc));
return nullptr;
}
Expand All @@ -81,13 +81,13 @@ ArduinoOpta::SharedPtr ArduinoOpta::create(UA_Server * server, ArduinoOptaVarian
if (UA_StatusCode_isBad(rc))
{
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
"ArduinoOpta::create: UA_Server_addVariableNode(..., \"ManufacturerName\", ...) failed with %s",
"Opta::create: UA_Server_addVariableNode(..., \"ManufacturerName\", ...) failed with %s",
UA_StatusCode_name(rc));
return nullptr;
}

UA_VariableAttributes modelAttr = UA_VariableAttributes_default;
UA_String modelName = UA_STRING((char *)ArduinoOptaVariant::toString(opta_type).c_str());
UA_String modelName = UA_STRING((char *)OptaVariant::toSKUString(opta_type).c_str());
UA_Variant_setScalar(&modelAttr.value, &modelName, &UA_TYPES[UA_TYPES_STRING]);
modelAttr.displayName = UA_LOCALIZEDTEXT("en-US", "ModelName");
rc = UA_Server_addVariableNode(server,
Expand All @@ -102,7 +102,7 @@ ArduinoOpta::SharedPtr ArduinoOpta::create(UA_Server * server, ArduinoOptaVarian
if (UA_StatusCode_isBad(rc))
{
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
"ArduinoOpta::create: UA_Server_addVariableNode(..., \"ModelName\", ...) failed with %s",
"Opta::create: UA_Server_addVariableNode(..., \"ModelName\", ...) failed with %s",
UA_StatusCode_name(rc));
return nullptr;
}
Expand All @@ -123,58 +123,58 @@ ArduinoOpta::SharedPtr ArduinoOpta::create(UA_Server * server, ArduinoOptaVarian
if (UA_StatusCode_isBad(rc))
{
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
"ArduinoOpta::create: UA_Server_addVariableNode(..., \"Status\", ...) failed with %s",
"Opta::create: UA_Server_addVariableNode(..., \"Status\", ...) failed with %s",
UA_StatusCode_name(rc));
return nullptr;
}

auto const instance_ptr = std::make_shared<ArduinoOpta>(server, node_id);
auto const instance_ptr = std::make_shared<Opta>(server, node_id);
return instance_ptr;
}

AnalogInputManager::SharedPtr ArduinoOpta::analog_input_mgr()
AnalogInputManager::SharedPtr Opta::analog_input_mgr()
{
if (!_analog_input_mgr)
{
_analog_input_mgr = opcua::AnalogInputManager::create(_server, _node_id);
if (!_analog_input_mgr)
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "ArduinoOpta::analog_input_mgr: AnalogInputManager::create(...) failed.");
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Opta::analog_input_mgr: AnalogInputManager::create(...) failed.");
}

return _analog_input_mgr;
}

DigitalInputManager::SharedPtr ArduinoOpta::digital_input_mgr()
DigitalInputManager::SharedPtr Opta::digital_input_mgr()
{
if (!_digital_input_mgr)
{
_digital_input_mgr = opcua::DigitalInputManager::create(_server, _node_id);
if (!_digital_input_mgr)
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "ArduinoOpta::digital_input_mgr: DigitalInputManager::create(...) failed.");
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Opta::digital_input_mgr: DigitalInputManager::create(...) failed.");
}

return _digital_input_mgr;
}

RelayManager::SharedPtr ArduinoOpta::relay_mgr()
RelayManager::SharedPtr Opta::relay_mgr()
{
if (!_relay_mgr)
{
_relay_mgr = opcua::RelayManager::create(_server, _node_id);
if (!_relay_mgr)
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "ArduinoOpta::relay_mgr: RelayManager::create(...) failed.");
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Opta::relay_mgr: RelayManager::create(...) failed.");
}

return _relay_mgr;
}

LedManager::SharedPtr ArduinoOpta::led_mgr()
LedManager::SharedPtr Opta::led_mgr()
{
if (!_led_mgr)
{
_led_mgr = opcua::LedManager::create(_server, _node_id);
if (!_led_mgr)
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "ArduinoOpta::led_mgr: LedManager::create(...) failed.");
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Opta::led_mgr: LedManager::create(...) failed.");
}

return _led_mgr;
Expand Down
26 changes: 16 additions & 10 deletions src/ArduinoOpta.h → src/Opta.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@

#include <memory>

#include "LedManager.h"
#include "RelayManager.h"
#include "AnalogInputManager.h"
#include "DigitalInputManager.h"
#include "UserButton.h"
#include "ArduinoOptaVariant.h"
#include "io/led/LedManager.h"
#include "io/button/UserButton.h"
#include "io/relay/RelayManager.h"
#include "io/analog/AnalogInputManager.h"
#include "io/digital/DigitalInputManager.h"

#include "OptaVariant.h"

/**************************************************************************************
* NAMESPACE
Expand All @@ -35,22 +36,27 @@ namespace opcua
* CLASS DECLARATION
**************************************************************************************/

class ArduinoOpta
class Opta
{
public:
typedef std::shared_ptr<ArduinoOpta> SharedPtr;
typedef std::shared_ptr<Opta> SharedPtr;


static SharedPtr create(UA_Server * server, OptaVariant::Type const opta_type);

static SharedPtr create(UA_Server * server, ArduinoOptaVariant::Type const opta_type);

ArduinoOpta(UA_Server * server, UA_NodeId const & node_id);
Opta(UA_Server * server, UA_NodeId const & node_id);


AnalogInputManager::SharedPtr analog_input_mgr();
DigitalInputManager::SharedPtr digital_input_mgr();
RelayManager::SharedPtr relay_mgr();
LedManager::SharedPtr led_mgr();


[[nodiscard]] UA_NodeId node_id() const { return _node_id; }


private:
UA_Server * _server;
UA_NodeId _node_id;
Expand Down
64 changes: 64 additions & 0 deletions src/OptaExpansionManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2024 Arduino
*
* SPDX-License-Identifier: MPL-2.0
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

/**************************************************************************************
* INCLUDE
**************************************************************************************/

#include "OptaExpansionManager.h"

/**************************************************************************************
* NAMESPACE
**************************************************************************************/

namespace opcua
{

/**************************************************************************************
* PUBLIC MEMBER FUNCTIONS
**************************************************************************************/

DigitalMechExpansion::SharedPtr OptaExpansionManager::create_digital_mechanical_expansion(uint8_t const exp_num)
{
auto const exp_mech_opcua = opcua::DigitalMechExpansion::create(
_server,
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
exp_num);

_dig_mech_exp_list.push_back(exp_mech_opcua);
return exp_mech_opcua;
}

DigitalStSolidExpansion::SharedPtr OptaExpansionManager::create_digital_solid_state_expansion(uint8_t const exp_num)
{
auto const exp_solid_state_opcua = opcua::DigitalStSolidExpansion::create(
_server,
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
exp_num);

_dig_solid_state_exp_list.push_back(exp_solid_state_opcua);
return exp_solid_state_opcua;
}

AnalogExpansion::SharedPtr OptaExpansionManager::create_analog_expansion(uint8_t const exp_num)
{
auto const exp_analog_opcua = opcua::AnalogExpansion::create(
_server,
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
exp_num);

_analog_exp_list.push_back(exp_analog_opcua);
return exp_analog_opcua;
}

/**************************************************************************************
* NAMESPACE
**************************************************************************************/

} /* opcua */
67 changes: 67 additions & 0 deletions src/OptaExpansionManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2024 Arduino
*
* SPDX-License-Identifier: MPL-2.0
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#pragma once

/**************************************************************************************
* INCLUDE
**************************************************************************************/

#include "open62541.h"

#include <memory>

#include "expansion/AnalogExpansion.h"
#include "expansion/DigitalMechExpansion.h"
#include "expansion/DigitalStSolidExpansion.h"

/**************************************************************************************
* NAMESPACE
**************************************************************************************/

namespace opcua
{

/**************************************************************************************
* CLASS DECLARATION
**************************************************************************************/

class OptaExpansionManager
{
public:
typedef std::shared_ptr<OptaExpansionManager> SharedPtr;


static SharedPtr create(UA_Server * server) {
return std::make_shared<OptaExpansionManager>(server);
}


OptaExpansionManager(UA_Server * server)
: _server{server}
{ }


DigitalMechExpansion::SharedPtr create_digital_mechanical_expansion(uint8_t const exp_num);
DigitalStSolidExpansion::SharedPtr create_digital_solid_state_expansion(uint8_t const exp_num);
AnalogExpansion::SharedPtr create_analog_expansion(uint8_t const exp_num);

private:
UA_Server * _server;

std::list<DigitalMechExpansion::SharedPtr> _dig_mech_exp_list;
std::list<DigitalStSolidExpansion::SharedPtr> _dig_solid_state_exp_list;
std::list<AnalogExpansion::SharedPtr> _analog_exp_list;
};

/**************************************************************************************
* NAMESPACE
**************************************************************************************/

} /* opcua */
Loading