From 5b7a659769c1edcad03e5df6c5734eddaad57bfd Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Wed, 12 Jun 2024 10:46:19 +0200 Subject: [PATCH 1/8] Implement OPC/UA LED and LedManager in order to allow control of the USER led. --- examples/opcua_server/opcua_server.ino | 3 + src/ArduinoOpta.cpp | 5 + src/ArduinoOpta.h | 3 + src/Led.cpp | 129 +++++++++++++++++++++++++ src/Led.h | 57 +++++++++++ src/LedManager.cpp | 86 +++++++++++++++++ src/LedManager.h | 55 +++++++++++ src/Relay.h | 1 - 8 files changed, 338 insertions(+), 1 deletion(-) create mode 100644 src/Led.cpp create mode 100644 src/Led.h create mode 100644 src/LedManager.cpp create mode 100644 src/LedManager.h diff --git a/examples/opcua_server/opcua_server.ino b/examples/opcua_server/opcua_server.ino index d78aecc..fb96ff4 100644 --- a/examples/opcua_server/opcua_server.ino +++ b/examples/opcua_server/opcua_server.ino @@ -234,6 +234,9 @@ void setup() arduino_opta_opcua->relay_mgr()->add_relay_output(opc_ua_server, "Relay 3", [](bool const value) { pinMode(RELAY3, OUTPUT); digitalWrite(RELAY3, value); pinMode(LED_D2, OUTPUT); digitalWrite(LED_D2, value);}); arduino_opta_opcua->relay_mgr()->add_relay_output(opc_ua_server, "Relay 4", [](bool const value) { pinMode(RELAY4, OUTPUT); digitalWrite(RELAY4, value); pinMode(LED_D3, OUTPUT); digitalWrite(LED_D3, value);}); + /* Add the various LED outputs. */ + arduino_opta_opcua->led_mgr()->add_led_output(opc_ua_server, "User LED", [](bool const value) { pinMode(LEDB, OUTPUT); digitalWrite(LEDB, value); }); + /* Print some threading related message. */ UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "stack: size = %d | free = %d | used = %d | max = %d", diff --git a/src/ArduinoOpta.cpp b/src/ArduinoOpta.cpp index aea4bf1..10264fa 100644 --- a/src/ArduinoOpta.cpp +++ b/src/ArduinoOpta.cpp @@ -46,6 +46,11 @@ ArduinoOpta::ArduinoOpta(UA_Server * server, UA_NodeId const & node_id) if (!_relay_mgr) { UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "ArduinoOpta::Ctor: RelayManager::create(...) failed."); } + + _led_mgr = opcua::LedManager::create(server, _node_id); + if (!_led_mgr) { + UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "ArduinoOpta::Ctor: LedManager::create(...) failed."); + } } /************************************************************************************** diff --git a/src/ArduinoOpta.h b/src/ArduinoOpta.h index 6f3ab97..5f21076 100644 --- a/src/ArduinoOpta.h +++ b/src/ArduinoOpta.h @@ -17,6 +17,7 @@ #include +#include "LedManager.h" #include "RelayManager.h" #include "AnalogInputManager.h" #include "DigitalInputManager.h" @@ -45,6 +46,7 @@ class ArduinoOpta inline AnalogInputManager::SharedPtr analog_input_mgr() const { return _analog_input_mgr; } inline DigitalInputManager::SharedPtr digital_input_mgr() const { return _digital_input_mgr; } inline RelayManager::SharedPtr relay_mgr() const { return _relay_mgr; } + inline LedManager::SharedPtr led_mgr() const { return _led_mgr; } private: @@ -53,6 +55,7 @@ class ArduinoOpta AnalogInputManager::SharedPtr _analog_input_mgr; DigitalInputManager::SharedPtr _digital_input_mgr; RelayManager::SharedPtr _relay_mgr; + LedManager::SharedPtr _led_mgr; }; /************************************************************************************** diff --git a/src/Led.cpp b/src/Led.cpp new file mode 100644 index 0000000..e481ca1 --- /dev/null +++ b/src/Led.cpp @@ -0,0 +1,129 @@ +/* + * 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 "Led.h" + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +namespace opcua +{ + +/************************************************************************************** + * FUNCTION DEFINITION + **************************************************************************************/ + +static void relay_on_write_request(UA_Server *server, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeid, + void *nodeContext, + const UA_NumericRange *range, + const UA_DataValue *data) +{ + bool const value = *(UA_Boolean *)(data->value.data) == true; + Led * this_ptr = reinterpret_cast(nodeContext); + this_ptr->onWriteRequest(server, nodeid, value); +} + +/************************************************************************************** + * CTOR/DTOR + **************************************************************************************/ + +Led::Led(UA_NodeId const & node_id, OnSetLedStateFunc const on_set_led_state) + : _node_id{node_id} + , _on_set_led_state{on_set_led_state} +{ + +} + +/************************************************************************************** + * PUBLIC MEMBER FUNCTIONS + **************************************************************************************/ + +Led::SharedPtr Led::create(UA_Server *server, + UA_NodeId const &parent_node_id, + const char *display_name, + OnSetLedStateFunc const on_set_led_state) +{ + UA_StatusCode rc = UA_STATUSCODE_GOOD; + + UA_VariableAttributes relay_value_attr = UA_VariableAttributes_default; + + UA_Boolean relay_value = false; + UA_Variant_setScalar(&relay_value_attr.value, &relay_value, &UA_TYPES[UA_TYPES_BOOLEAN]); + + relay_value_attr.displayName = UA_LOCALIZEDTEXT("en-US", (char *)display_name); + relay_value_attr.dataType = UA_TYPES[UA_TYPES_BOOLEAN].typeId; + relay_value_attr.accessLevel = + UA_ACCESSLEVELMASK_READ | + UA_ACCESSLEVELMASK_WRITE | UA_ACCESSLEVELMASK_STATUSWRITE | + UA_ACCESSLEVELMASK_TIMESTAMPWRITE; /* Status and timestamp write access necessary for opcua-client. */ + + UA_NodeId node_id; + rc = UA_Server_addVariableNode(server, + UA_NODEID_NULL, + parent_node_id, + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), + UA_QUALIFIEDNAME(1, "Value"), + UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), + relay_value_attr, + NULL, + &node_id); + if (UA_StatusCode_isBad(rc)) + { + UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, + "Led::create: UA_Server_addVariableNode(...) failed with %s", UA_StatusCode_name(rc)); + return nullptr; + } + + /* Create an instance of Led here. */ + auto const instance_ptr = std::make_shared(node_id, on_set_led_state); + + rc = UA_Server_setNodeContext(server, node_id, reinterpret_cast(instance_ptr.get())); + if (UA_StatusCode_isBad(rc)) + { + UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, + "Led::create: UA_Server_setNodeContext(...) failed with %s", + UA_StatusCode_name(rc)); + return nullptr; + } + + UA_ValueCallback callback; + callback.onRead = NULL; + callback.onWrite = relay_on_write_request; + rc = UA_Server_setVariableNode_valueCallback(server, node_id, callback); + if (UA_StatusCode_isBad(rc)) + { + UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, + "Led::create: UA_Server_setVariableNode_valueCallback(...) failed with %s", + UA_StatusCode_name(rc)); + return nullptr; + } + + return instance_ptr; +} + +void Led::onWriteRequest(UA_Server * server, UA_NodeId const * node_id, bool const value) +{ + /* Some debug output. */ + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Led::onWriteRequest: value = %d", value); + _on_set_led_state(value); +} + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +} /* opcua */ diff --git a/src/Led.h b/src/Led.h new file mode 100644 index 0000000..f0b4185 --- /dev/null +++ b/src/Led.h @@ -0,0 +1,57 @@ +/* + * 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 +#include + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +namespace opcua +{ + +/************************************************************************************** + * CLASS DECLARATION + **************************************************************************************/ + +class Led +{ +public: + typedef std::shared_ptr SharedPtr; + typedef std::function OnSetLedStateFunc; + + static SharedPtr create(UA_Server *server, + UA_NodeId const &parent_node_id, + const char *display_name, + OnSetLedStateFunc const on_set_led_state); + + Led(UA_NodeId const &node_id, OnSetLedStateFunc const on_set_led_state); + + void onWriteRequest(UA_Server * server, UA_NodeId const * node_id, bool const value); + + +private: + UA_NodeId _node_id; + OnSetLedStateFunc const _on_set_led_state; +}; + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +} /* opcua */ diff --git a/src/LedManager.cpp b/src/LedManager.cpp new file mode 100644 index 0000000..75e336f --- /dev/null +++ b/src/LedManager.cpp @@ -0,0 +1,86 @@ +/* + * 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 "LedManager.h" + +#include + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +namespace opcua +{ + +/************************************************************************************** + * CTOR/DTOR + **************************************************************************************/ + +LedManager::LedManager(UA_NodeId const & node_id) +: _node_id{node_id} +{ + /* Nothing happens here. */ +} + +/************************************************************************************** + * PUBLIC MEMBER FUNCTIONS + **************************************************************************************/ + +LedManager::SharedPtr LedManager::create(UA_Server * server, UA_NodeId const parent_node_id) +{ + UA_StatusCode rc = UA_STATUSCODE_GOOD; + + UA_ObjectAttributes oAttr = UA_ObjectAttributes_default; + oAttr.displayName = UA_LOCALIZEDTEXT("en-US", "LEDs"); + UA_NodeId node_id; + rc = UA_Server_addObjectNode(server, + UA_NODEID_NULL, + parent_node_id, + UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), + UA_QUALIFIEDNAME(1, "LEDs"), + 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, + "LedManager::create: UA_Server_addObjectNode(...) failed with %s", UA_StatusCode_name(rc)); + return nullptr; + } + + auto const instance_ptr = std::make_shared(node_id); + return instance_ptr; +} + +/************************************************************************************** + * PUBLIC MEMBER FUNCTIONS + **************************************************************************************/ + +void LedManager::add_led_output(UA_Server * server, + const char * display_name, + Led::OnSetLedStateFunc const on_set_led_state) +{ + auto const led = Led::create(server, _node_id, display_name, on_set_led_state); + if (!led) { + UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "LedManager::add_led_output: Led::create(...) failed: returned nullptr"); + return; + } + _led_list.push_back(led); +} + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +} /* opcua */ diff --git a/src/LedManager.h b/src/LedManager.h new file mode 100644 index 0000000..50b073b --- /dev/null +++ b/src/LedManager.h @@ -0,0 +1,55 @@ +/* + * 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 +#include + +#include "Led.h" + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +namespace opcua +{ + +/************************************************************************************** + * CLASS DECLARATION + **************************************************************************************/ + +class LedManager +{ +public: + typedef std::shared_ptr SharedPtr; + + static SharedPtr create(UA_Server * server, UA_NodeId const parent_node_id); + + LedManager(UA_NodeId const & node_id); + + void add_led_output(UA_Server * server, const char * display_name, Led::OnSetLedStateFunc const on_set_led_state); + + +private: + UA_NodeId _node_id; + std::list _led_list; +}; + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +} /* opcua */ diff --git a/src/Relay.h b/src/Relay.h index 8beca5a..2e27176 100644 --- a/src/Relay.h +++ b/src/Relay.h @@ -55,4 +55,3 @@ class Relay **************************************************************************************/ } /* opcua */ - From 3ddaac80bf663c7de2229e87b6a93a2d0b3e8f5e Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Wed, 12 Jun 2024 12:56:40 +0200 Subject: [PATCH 2/8] Implement module to determine the variant of Opta this board is running on. --- src/ArduinoOptaVariant.cpp | 58 ++++++++++++++++++++++++++++++++++++++ src/ArduinoOptaVariant.h | 38 +++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 src/ArduinoOptaVariant.cpp create mode 100644 src/ArduinoOptaVariant.h diff --git a/src/ArduinoOptaVariant.cpp b/src/ArduinoOptaVariant.cpp new file mode 100644 index 0000000..d3bc510 --- /dev/null +++ b/src/ArduinoOptaVariant.cpp @@ -0,0 +1,58 @@ +/* + * 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 "ArduinoOptaVariant.h" + +#if __has_include("opta_info.h") +# include +# include "opta_info.h" +extern "C" OptaBoardInfo * boardInfo(); +#else +# error "Can not find include file \"opta_info.h\"" +#endif + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +namespace opcua +{ + +/************************************************************************************** + * PUBLIC MEMBER FUNCTIONS + **************************************************************************************/ + +bool ArduinoOptaVariant::get_opta_variant(Type & type) +{ + OptaBoardInfo * info = boardInfo(); + + if (info->_board_functionalities.ethernet && info->_board_functionalities.wifi && info->_board_functionalities.rs485) { + type = ArduinoOptaVariant::Type::WiFi; + } + else if (info->_board_functionalities.ethernet && info->_board_functionalities.rs485) { + type = ArduinoOptaVariant::Type::RS485; + } + else if (info->_board_functionalities.ethernet) { + type = ArduinoOptaVariant::Type::Lite; + } + else + return false; + + return true; +} + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +} /* opcua */ diff --git a/src/ArduinoOptaVariant.h b/src/ArduinoOptaVariant.h new file mode 100644 index 0000000..a951f75 --- /dev/null +++ b/src/ArduinoOptaVariant.h @@ -0,0 +1,38 @@ +/* + * 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 + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +namespace opcua +{ + +/************************************************************************************** + * CLASS DECLARATION + **************************************************************************************/ + +class ArduinoOptaVariant +{ +public: + ArduinoOptaVariant() = delete; + ArduinoOptaVariant(ArduinoOptaVariant const &) = delete; + + enum class Type { Lite, RS485, WiFi }; + + static bool get_opta_variant(Type & type); +}; + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +} /* opcua */ From d2b4b7aec9125e462146abac35a97aae842f2a75 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Wed, 12 Jun 2024 13:01:46 +0200 Subject: [PATCH 3/8] Extend class to allow converting a variant type to a std::string. --- src/ArduinoOptaVariant.cpp | 11 +++++++++++ src/ArduinoOptaVariant.h | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/src/ArduinoOptaVariant.cpp b/src/ArduinoOptaVariant.cpp index d3bc510..d39e3c3 100644 --- a/src/ArduinoOptaVariant.cpp +++ b/src/ArduinoOptaVariant.cpp @@ -51,6 +51,17 @@ bool ArduinoOptaVariant::get_opta_variant(Type & type) return true; } +std::string ArduinoOptaVariant::toString(Type const type) +{ + switch(type) + { + case ArduinoOptaVariant::Type::WiFi: return std::string("Arduino Opta WiFi"); break; + case ArduinoOptaVariant::Type::RS485: return std::string("Arduino Opta RS485"); break; + case ArduinoOptaVariant::Type::Lite: return std::string("Arduino Opta Lite"); break; + default: __builtin_unreachable(); break; + } +} + /************************************************************************************** * NAMESPACE **************************************************************************************/ diff --git a/src/ArduinoOptaVariant.h b/src/ArduinoOptaVariant.h index a951f75..e5d87c8 100644 --- a/src/ArduinoOptaVariant.h +++ b/src/ArduinoOptaVariant.h @@ -9,6 +9,12 @@ #pragma once +/************************************************************************************** + * INCLUDE + **************************************************************************************/ + +#include + /************************************************************************************** * NAMESPACE **************************************************************************************/ @@ -29,6 +35,8 @@ class ArduinoOptaVariant enum class Type { Lite, RS485, WiFi }; static bool get_opta_variant(Type & type); + + static std::string toString(Type const type); }; /************************************************************************************** From a4271b07d0cbd1700bff98d91d9fbcbd86efcddb Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Wed, 12 Jun 2024 13:02:33 +0200 Subject: [PATCH 4/8] Fix: delete - now - superfluous variable "rc". --- examples/opcua_server/opcua_server.ino | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/opcua_server/opcua_server.ino b/examples/opcua_server/opcua_server.ino index fb96ff4..7c7fcae 100644 --- a/examples/opcua_server/opcua_server.ino +++ b/examples/opcua_server/opcua_server.ino @@ -197,8 +197,6 @@ void setup() UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Arduino Opta IP: %s", Ethernet.localIP().toString().c_str()); - UA_StatusCode rc = UA_STATUSCODE_GOOD; - /* Define the Arduino Opta as a OPC/UA object. */ arduino_opta_opcua = opcua::ArduinoOpta::create(opc_ua_server); if (!arduino_opta_opcua) { From b94128298d1a75d0cf7c454d6fe5d2be8e40b6ca Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Wed, 12 Jun 2024 13:06:38 +0200 Subject: [PATCH 5/8] Fix: no extern C, as the compiler is name-mangling the original definition which is not extern C either -> linker error. --- src/ArduinoOptaVariant.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ArduinoOptaVariant.cpp b/src/ArduinoOptaVariant.cpp index d39e3c3..fb1b503 100644 --- a/src/ArduinoOptaVariant.cpp +++ b/src/ArduinoOptaVariant.cpp @@ -16,7 +16,7 @@ #if __has_include("opta_info.h") # include # include "opta_info.h" -extern "C" OptaBoardInfo * boardInfo(); +OptaBoardInfo * boardInfo(); #else # error "Can not find include file \"opta_info.h\"" #endif From c79edd5f97131ea917a45d30f237566e8098edd3 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Wed, 12 Jun 2024 13:08:13 +0200 Subject: [PATCH 6/8] Include ArduinoOptaVariant in top-level include file (and clean-out outdated ones). --- examples/opcua_server/opcua_server.ino | 8 ++++++++ src/Arduino_open62541.h | 5 ++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/examples/opcua_server/opcua_server.ino b/examples/opcua_server/opcua_server.ino index 7c7fcae..ffccfc7 100644 --- a/examples/opcua_server/opcua_server.ino +++ b/examples/opcua_server/opcua_server.ino @@ -197,6 +197,14 @@ void setup() UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Arduino Opta IP: %s", Ethernet.localIP().toString().c_str()); + /* Determine the Arduino OPC/UA hardware variant. */ + opcua::ArduinoOptaVariant::Type opta_type; + if (!opcua::ArduinoOptaVariant::get_opta_variant(opta_type)) { + UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "opcua::ArduinoOptaVariant::get_opta_variant(...) failed"); + return; + } + UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Arduino Opta Variant: %s", opcua::ArduinoOptaVariant::toString(opta_type).c_str()); + /* Define the Arduino Opta as a OPC/UA object. */ arduino_opta_opcua = opcua::ArduinoOpta::create(opc_ua_server); if (!arduino_opta_opcua) { diff --git a/src/Arduino_open62541.h b/src/Arduino_open62541.h index b29b627..4ca5ed8 100644 --- a/src/Arduino_open62541.h +++ b/src/Arduino_open62541.h @@ -15,10 +15,9 @@ #include "open62541.h" #include "o1heap/o1heap.h" -#include "Relay.h" + #include "ArduinoOpta.h" -#include "AnalogInputManager.h" -#include "DigitalInputManager.h" +#include "ArduinoOptaVariant.h" /************************************************************************************** * DEFINES From 8fcdeb5100a27f00f776b53e629195001cb235d6 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Wed, 12 Jun 2024 13:11:35 +0200 Subject: [PATCH 7/8] Only expose Arduino Opta USER LED for the WiFi variant. --- examples/opcua_server/opcua_server.ino | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/opcua_server/opcua_server.ino b/examples/opcua_server/opcua_server.ino index ffccfc7..22bbb7e 100644 --- a/examples/opcua_server/opcua_server.ino +++ b/examples/opcua_server/opcua_server.ino @@ -241,7 +241,9 @@ void setup() arduino_opta_opcua->relay_mgr()->add_relay_output(opc_ua_server, "Relay 4", [](bool const value) { pinMode(RELAY4, OUTPUT); digitalWrite(RELAY4, value); pinMode(LED_D3, OUTPUT); digitalWrite(LED_D3, value);}); /* Add the various LED outputs. */ - arduino_opta_opcua->led_mgr()->add_led_output(opc_ua_server, "User LED", [](bool const value) { pinMode(LEDB, OUTPUT); digitalWrite(LEDB, value); }); + if (opta_type == opcua::ArduinoOptaVariant::Type::WiFi) { + arduino_opta_opcua->led_mgr()->add_led_output(opc_ua_server, "User LED", [](bool const value) { pinMode(LEDB, OUTPUT); digitalWrite(LEDB, value); }); + } /* Print some threading related message. */ UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, From 0e3174f2480fdc97d7dbd8bf8a8d439ec69c8114 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Wed, 12 Jun 2024 13:25:18 +0200 Subject: [PATCH 8/8] Fix: remove copy'n'paste residues for relay from "Led". --- src/Led.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Led.cpp b/src/Led.cpp index e481ca1..a48be11 100644 --- a/src/Led.cpp +++ b/src/Led.cpp @@ -24,13 +24,13 @@ namespace opcua * FUNCTION DEFINITION **************************************************************************************/ -static void relay_on_write_request(UA_Server *server, - const UA_NodeId *sessionId, - void *sessionContext, - const UA_NodeId *nodeid, - void *nodeContext, - const UA_NumericRange *range, - const UA_DataValue *data) +static void led_on_write_request(UA_Server *server, + const UA_NodeId *sessionId, + void *sessionContext, + const UA_NodeId *nodeid, + void *nodeContext, + const UA_NumericRange *range, + const UA_DataValue *data) { bool const value = *(UA_Boolean *)(data->value.data) == true; Led * this_ptr = reinterpret_cast(nodeContext); @@ -53,20 +53,20 @@ Led::Led(UA_NodeId const & node_id, OnSetLedStateFunc const on_set_led_state) **************************************************************************************/ Led::SharedPtr Led::create(UA_Server *server, - UA_NodeId const &parent_node_id, - const char *display_name, - OnSetLedStateFunc const on_set_led_state) + UA_NodeId const &parent_node_id, + const char *display_name, + OnSetLedStateFunc const on_set_led_state) { UA_StatusCode rc = UA_STATUSCODE_GOOD; - UA_VariableAttributes relay_value_attr = UA_VariableAttributes_default; + UA_VariableAttributes led_value_attr = UA_VariableAttributes_default; - UA_Boolean relay_value = false; - UA_Variant_setScalar(&relay_value_attr.value, &relay_value, &UA_TYPES[UA_TYPES_BOOLEAN]); + UA_Boolean led_value = false; + UA_Variant_setScalar(&led_value_attr.value, &led_value, &UA_TYPES[UA_TYPES_BOOLEAN]); - relay_value_attr.displayName = UA_LOCALIZEDTEXT("en-US", (char *)display_name); - relay_value_attr.dataType = UA_TYPES[UA_TYPES_BOOLEAN].typeId; - relay_value_attr.accessLevel = + led_value_attr.displayName = UA_LOCALIZEDTEXT("en-US", (char *)display_name); + led_value_attr.dataType = UA_TYPES[UA_TYPES_BOOLEAN].typeId; + led_value_attr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE | UA_ACCESSLEVELMASK_STATUSWRITE | UA_ACCESSLEVELMASK_TIMESTAMPWRITE; /* Status and timestamp write access necessary for opcua-client. */ @@ -78,7 +78,7 @@ Led::SharedPtr Led::create(UA_Server *server, UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_QUALIFIEDNAME(1, "Value"), UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), - relay_value_attr, + led_value_attr, NULL, &node_id); if (UA_StatusCode_isBad(rc)) @@ -102,7 +102,7 @@ Led::SharedPtr Led::create(UA_Server *server, UA_ValueCallback callback; callback.onRead = NULL; - callback.onWrite = relay_on_write_request; + callback.onWrite = led_on_write_request; rc = UA_Server_setVariableNode_valueCallback(server, node_id, callback); if (UA_StatusCode_isBad(rc)) {