Skip to content

Commit 0783872

Browse files
authored
Merge pull request #11 from bcmi-labs/feature/opta-expansion-opcua
Feature: automatic detection of Opta expansion modules and exposure via OPC/UA
2 parents 5407a89 + 238cb0f commit 0783872

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1101
-217
lines changed

.github/workflows/compile-examples.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ jobs:
2525
with:
2626
fqbn: ${{ matrix.board.fqbn }}
2727
platforms: ${{ matrix.board.platforms }}
28+
libraries: |
29+
- source-path: ./
30+
- name: Arduino_Opta_Blueprint
31+
- name: Arduino_SerialUpdater
32+
- name: Arduino_DebugUtils
2833
enable-deltas-report: true
2934
github-token: ${{ secrets.GITHUB_TOKEN }}
3035
sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }}

examples/opcua_server/opcua_server.ino

Lines changed: 112 additions & 149 deletions
Large diffs are not rendered by default.

library.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ url=https://github.com/bcmi-labs/Arduino_open62541
1010
ldflags=-lopen62541
1111
includes=Arduino_open62541.h
1212
precompiled=true
13+
depends=Arduino_Opta_Blueprint

src/Arduino_open62541.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,16 @@
1414
**************************************************************************************/
1515

1616
#include "open62541.h"
17-
#include "o1heap/o1heap.h"
18-
#include "NTPUtils.h"
19-
#include "cvt_time.h"
2017

21-
#include "ArduinoOpta.h"
22-
#include "ArduinoOptaVariant.h"
18+
#include "util/o1heap/o1heap.h"
19+
#include "util/o1heap/o1heap_wrapper.h"
20+
#include "util/time/cvt_time.h"
21+
#include "util/time/NTPUtils.h"
22+
#include "util/toStr/ExpansionType.h"
23+
24+
#include "Opta.h"
25+
#include "OptaVariant.h"
26+
#include "OptaExpansionManager.h"
2327

2428
/**************************************************************************************
2529
* DEFINES
Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* INCLUDE
1212
**************************************************************************************/
1313

14-
#include "ArduinoOpta.h"
14+
#include "Opta.h"
1515

1616
/**************************************************************************************
1717
* NAMESPACE
@@ -24,7 +24,7 @@ namespace opcua
2424
* CTOR/DTOR
2525
**************************************************************************************/
2626

27-
ArduinoOpta::ArduinoOpta(UA_Server * server, UA_NodeId const & node_id)
27+
Opta::Opta(UA_Server * server, UA_NodeId const & node_id)
2828
: _server{server}
2929
, _node_id{node_id}
3030
, _analog_input_mgr{nullptr}
@@ -34,33 +34,33 @@ ArduinoOpta::ArduinoOpta(UA_Server * server, UA_NodeId const & node_id)
3434
{
3535
_usr_button = opcua::UserButton::create(_server, _node_id);
3636
if (!_usr_button)
37-
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "ArduinoOpta::Ctor: UserButton::create(...) failed.");
37+
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Opta::Ctor: UserButton::create(...) failed.");
3838
}
3939

4040
/**************************************************************************************
4141
* PUBLIC MEMBER FUNCTIONS
4242
**************************************************************************************/
4343

44-
ArduinoOpta::SharedPtr ArduinoOpta::create(UA_Server * server, ArduinoOptaVariant::Type const opta_type)
44+
Opta::SharedPtr Opta::create(UA_Server * server, OptaVariant::Type const opta_type)
4545
{
4646
UA_StatusCode rc = UA_STATUSCODE_GOOD;
4747

4848
UA_ObjectAttributes oAttr = UA_ObjectAttributes_default;
49-
oAttr.displayName = UA_LOCALIZEDTEXT("en-US", "Arduino Opta");
49+
oAttr.displayName = UA_LOCALIZEDTEXT("en-US", (char *)OptaVariant::toString(opta_type).c_str());
5050
UA_NodeId node_id;
5151
rc = UA_Server_addObjectNode(server,
5252
UA_NODEID_NULL,
5353
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
5454
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
55-
UA_QUALIFIEDNAME(1, "ArduinoOpta"),
55+
UA_QUALIFIEDNAME(1, "Opta"),
5656
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),
5757
oAttr,
5858
NULL,
5959
&node_id);
6060
if (UA_StatusCode_isBad(rc))
6161
{
6262
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
63-
"ArduinoOpta::create: UA_Server_addObjectNode(...) failed with %s",
63+
"Opta::create: UA_Server_addObjectNode(...) failed with %s",
6464
UA_StatusCode_name(rc));
6565
return nullptr;
6666
}
@@ -81,13 +81,13 @@ ArduinoOpta::SharedPtr ArduinoOpta::create(UA_Server * server, ArduinoOptaVarian
8181
if (UA_StatusCode_isBad(rc))
8282
{
8383
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
84-
"ArduinoOpta::create: UA_Server_addVariableNode(..., \"ManufacturerName\", ...) failed with %s",
84+
"Opta::create: UA_Server_addVariableNode(..., \"ManufacturerName\", ...) failed with %s",
8585
UA_StatusCode_name(rc));
8686
return nullptr;
8787
}
8888

8989
UA_VariableAttributes modelAttr = UA_VariableAttributes_default;
90-
UA_String modelName = UA_STRING((char *)ArduinoOptaVariant::toString(opta_type).c_str());
90+
UA_String modelName = UA_STRING((char *)OptaVariant::toSKUString(opta_type).c_str());
9191
UA_Variant_setScalar(&modelAttr.value, &modelName, &UA_TYPES[UA_TYPES_STRING]);
9292
modelAttr.displayName = UA_LOCALIZEDTEXT("en-US", "ModelName");
9393
rc = UA_Server_addVariableNode(server,
@@ -102,7 +102,7 @@ ArduinoOpta::SharedPtr ArduinoOpta::create(UA_Server * server, ArduinoOptaVarian
102102
if (UA_StatusCode_isBad(rc))
103103
{
104104
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
105-
"ArduinoOpta::create: UA_Server_addVariableNode(..., \"ModelName\", ...) failed with %s",
105+
"Opta::create: UA_Server_addVariableNode(..., \"ModelName\", ...) failed with %s",
106106
UA_StatusCode_name(rc));
107107
return nullptr;
108108
}
@@ -123,58 +123,58 @@ ArduinoOpta::SharedPtr ArduinoOpta::create(UA_Server * server, ArduinoOptaVarian
123123
if (UA_StatusCode_isBad(rc))
124124
{
125125
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
126-
"ArduinoOpta::create: UA_Server_addVariableNode(..., \"Status\", ...) failed with %s",
126+
"Opta::create: UA_Server_addVariableNode(..., \"Status\", ...) failed with %s",
127127
UA_StatusCode_name(rc));
128128
return nullptr;
129129
}
130130

131-
auto const instance_ptr = std::make_shared<ArduinoOpta>(server, node_id);
131+
auto const instance_ptr = std::make_shared<Opta>(server, node_id);
132132
return instance_ptr;
133133
}
134134

135-
AnalogInputManager::SharedPtr ArduinoOpta::analog_input_mgr()
135+
AnalogInputManager::SharedPtr Opta::analog_input_mgr()
136136
{
137137
if (!_analog_input_mgr)
138138
{
139139
_analog_input_mgr = opcua::AnalogInputManager::create(_server, _node_id);
140140
if (!_analog_input_mgr)
141-
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "ArduinoOpta::analog_input_mgr: AnalogInputManager::create(...) failed.");
141+
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Opta::analog_input_mgr: AnalogInputManager::create(...) failed.");
142142
}
143143

144144
return _analog_input_mgr;
145145
}
146146

147-
DigitalInputManager::SharedPtr ArduinoOpta::digital_input_mgr()
147+
DigitalInputManager::SharedPtr Opta::digital_input_mgr()
148148
{
149149
if (!_digital_input_mgr)
150150
{
151151
_digital_input_mgr = opcua::DigitalInputManager::create(_server, _node_id);
152152
if (!_digital_input_mgr)
153-
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "ArduinoOpta::digital_input_mgr: DigitalInputManager::create(...) failed.");
153+
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Opta::digital_input_mgr: DigitalInputManager::create(...) failed.");
154154
}
155155

156156
return _digital_input_mgr;
157157
}
158158

159-
RelayManager::SharedPtr ArduinoOpta::relay_mgr()
159+
RelayManager::SharedPtr Opta::relay_mgr()
160160
{
161161
if (!_relay_mgr)
162162
{
163163
_relay_mgr = opcua::RelayManager::create(_server, _node_id);
164164
if (!_relay_mgr)
165-
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "ArduinoOpta::relay_mgr: RelayManager::create(...) failed.");
165+
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Opta::relay_mgr: RelayManager::create(...) failed.");
166166
}
167167

168168
return _relay_mgr;
169169
}
170170

171-
LedManager::SharedPtr ArduinoOpta::led_mgr()
171+
LedManager::SharedPtr Opta::led_mgr()
172172
{
173173
if (!_led_mgr)
174174
{
175175
_led_mgr = opcua::LedManager::create(_server, _node_id);
176176
if (!_led_mgr)
177-
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "ArduinoOpta::led_mgr: LedManager::create(...) failed.");
177+
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Opta::led_mgr: LedManager::create(...) failed.");
178178
}
179179

180180
return _led_mgr;

src/ArduinoOpta.h renamed to src/Opta.h

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717

1818
#include <memory>
1919

20-
#include "LedManager.h"
21-
#include "RelayManager.h"
22-
#include "AnalogInputManager.h"
23-
#include "DigitalInputManager.h"
24-
#include "UserButton.h"
25-
#include "ArduinoOptaVariant.h"
20+
#include "io/led/LedManager.h"
21+
#include "io/button/UserButton.h"
22+
#include "io/relay/RelayManager.h"
23+
#include "io/analog/AnalogInputManager.h"
24+
#include "io/digital/DigitalInputManager.h"
25+
26+
#include "OptaVariant.h"
2627

2728
/**************************************************************************************
2829
* NAMESPACE
@@ -35,22 +36,27 @@ namespace opcua
3536
* CLASS DECLARATION
3637
**************************************************************************************/
3738

38-
class ArduinoOpta
39+
class Opta
3940
{
4041
public:
41-
typedef std::shared_ptr<ArduinoOpta> SharedPtr;
42+
typedef std::shared_ptr<Opta> SharedPtr;
43+
44+
45+
static SharedPtr create(UA_Server * server, OptaVariant::Type const opta_type);
4246

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

45-
ArduinoOpta(UA_Server * server, UA_NodeId const & node_id);
48+
Opta(UA_Server * server, UA_NodeId const & node_id);
49+
4650

4751
AnalogInputManager::SharedPtr analog_input_mgr();
4852
DigitalInputManager::SharedPtr digital_input_mgr();
4953
RelayManager::SharedPtr relay_mgr();
5054
LedManager::SharedPtr led_mgr();
5155

56+
5257
[[nodiscard]] UA_NodeId node_id() const { return _node_id; }
5358

59+
5460
private:
5561
UA_Server * _server;
5662
UA_NodeId _node_id;

src/OptaExpansionManager.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright (c) 2024 Arduino
3+
*
4+
* SPDX-License-Identifier: MPL-2.0
5+
* This Source Code Form is subject to the terms of the Mozilla Public
6+
* License, v. 2.0. If a copy of the MPL was not distributed with this
7+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
8+
*/
9+
10+
/**************************************************************************************
11+
* INCLUDE
12+
**************************************************************************************/
13+
14+
#include "OptaExpansionManager.h"
15+
16+
/**************************************************************************************
17+
* NAMESPACE
18+
**************************************************************************************/
19+
20+
namespace opcua
21+
{
22+
23+
/**************************************************************************************
24+
* PUBLIC MEMBER FUNCTIONS
25+
**************************************************************************************/
26+
27+
DigitalMechExpansion::SharedPtr OptaExpansionManager::create_digital_mechanical_expansion(uint8_t const exp_num)
28+
{
29+
auto const exp_mech_opcua = opcua::DigitalMechExpansion::create(
30+
_server,
31+
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
32+
exp_num);
33+
34+
_dig_mech_exp_list.push_back(exp_mech_opcua);
35+
return exp_mech_opcua;
36+
}
37+
38+
DigitalStSolidExpansion::SharedPtr OptaExpansionManager::create_digital_solid_state_expansion(uint8_t const exp_num)
39+
{
40+
auto const exp_solid_state_opcua = opcua::DigitalStSolidExpansion::create(
41+
_server,
42+
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
43+
exp_num);
44+
45+
_dig_solid_state_exp_list.push_back(exp_solid_state_opcua);
46+
return exp_solid_state_opcua;
47+
}
48+
49+
AnalogExpansion::SharedPtr OptaExpansionManager::create_analog_expansion(uint8_t const exp_num)
50+
{
51+
auto const exp_analog_opcua = opcua::AnalogExpansion::create(
52+
_server,
53+
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
54+
exp_num);
55+
56+
_analog_exp_list.push_back(exp_analog_opcua);
57+
return exp_analog_opcua;
58+
}
59+
60+
/**************************************************************************************
61+
* NAMESPACE
62+
**************************************************************************************/
63+
64+
} /* opcua */

src/OptaExpansionManager.h

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright (c) 2024 Arduino
3+
*
4+
* SPDX-License-Identifier: MPL-2.0
5+
* This Source Code Form is subject to the terms of the Mozilla Public
6+
* License, v. 2.0. If a copy of the MPL was not distributed with this
7+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
8+
*/
9+
10+
#pragma once
11+
12+
/**************************************************************************************
13+
* INCLUDE
14+
**************************************************************************************/
15+
16+
#include "open62541.h"
17+
18+
#include <memory>
19+
20+
#include "expansion/AnalogExpansion.h"
21+
#include "expansion/DigitalMechExpansion.h"
22+
#include "expansion/DigitalStSolidExpansion.h"
23+
24+
/**************************************************************************************
25+
* NAMESPACE
26+
**************************************************************************************/
27+
28+
namespace opcua
29+
{
30+
31+
/**************************************************************************************
32+
* CLASS DECLARATION
33+
**************************************************************************************/
34+
35+
class OptaExpansionManager
36+
{
37+
public:
38+
typedef std::shared_ptr<OptaExpansionManager> SharedPtr;
39+
40+
41+
static SharedPtr create(UA_Server * server) {
42+
return std::make_shared<OptaExpansionManager>(server);
43+
}
44+
45+
46+
OptaExpansionManager(UA_Server * server)
47+
: _server{server}
48+
{ }
49+
50+
51+
DigitalMechExpansion::SharedPtr create_digital_mechanical_expansion(uint8_t const exp_num);
52+
DigitalStSolidExpansion::SharedPtr create_digital_solid_state_expansion(uint8_t const exp_num);
53+
AnalogExpansion::SharedPtr create_analog_expansion(uint8_t const exp_num);
54+
55+
private:
56+
UA_Server * _server;
57+
58+
std::list<DigitalMechExpansion::SharedPtr> _dig_mech_exp_list;
59+
std::list<DigitalStSolidExpansion::SharedPtr> _dig_solid_state_exp_list;
60+
std::list<AnalogExpansion::SharedPtr> _analog_exp_list;
61+
};
62+
63+
/**************************************************************************************
64+
* NAMESPACE
65+
**************************************************************************************/
66+
67+
} /* opcua */

0 commit comments

Comments
 (0)