Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
osie
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Martin Manchev
osie
Commits
8b91d7cc
Commit
8b91d7cc
authored
Oct 29, 2021
by
Balakrishna Balakrishna
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into feature/opcua
parents
da969acf
a5ef183a
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
216 additions
and
128 deletions
+216
-128
coupler/opc-ua-server/opc-ua-server.py
coupler/opc-ua-server/opc-ua-server.py
+0
-26
coupler/opc-ua-server/server.c
coupler/opc-ua-server/server.c
+216
-102
No files found.
coupler/opc-ua-server/opc-ua-server.py
deleted
100644 → 0
View file @
da969acf
"""
Simple OPC UA server with one paremeter (temp).
"""
from
opcua
import
Server
from
random
import
randint
import
time
server
=
Server
()
url
=
"opc.tcp://0.0.0.0:4840"
server
.
set_endpoint
(
url
)
name
=
"OPCUA_SIMULATION_SERVER"
addspace
=
server
.
register_namespace
(
name
)
node
=
server
.
get_objects_node
()
Param
=
node
.
add_object
(
addspace
,
"Parameters"
)
Temp
=
Param
.
add_variable
(
addspace
,
"Temperature"
,
0
)
Temp
.
set_writable
()
server
.
start
()
print
(
"started at %s"
%
url
)
while
1
:
Temp
.
set_value
(
randint
(
10
,
50
))
time
.
sleep
(
10
)
coupler/opc-ua-server/server.c
View file @
8b91d7cc
...
...
@@ -16,18 +16,26 @@
#include "open62541.h"
// global relay state
uint8_t
myrelay
=
0
;
uint8_t
I2C_0_RELAYS_STATE
=
0
;
// state of 4 relays at I2C slave 0
uint8_t
I2C_1_RELAYS_STATE
=
0
;
// state of 4 relays at I2C slave 1
static
int
setRelayState
(
int
command
)
{
// the default addresses of MOD-IOs
const
int
I2C_0_ADDR
=
0x58
;
const
int
I2C_1_ADDR
=
0x59
;
// the block device at host machine
static
const
char
I2C_BLOCK_DEVICE_NAME
[]
=
"/dev/i2c-1"
;
static
int
setRelayState
(
int
command
,
int
i2c_addr
)
{
/*
* Set relays' state over I2C
*/
int
file
;
int
adapter_nr
=
1
;
/* probably dynamically determined */
char
filename
[
20
];
// step 1: open device
snprintf
(
filename
,
19
,
"/dev/i2c-%d"
,
adapter_nr
);
snprintf
(
filename
,
19
,
I2C_BLOCK_DEVICE_NAME
);
file
=
open
(
filename
,
O_RDWR
);
if
(
file
<
0
)
{
/* ERROR HANDLING; you can check errno to see what went wrong */
...
...
@@ -36,8 +44,7 @@ static int setRelayState(int command) {
}
// step 2: address the slave by its address
int
addr
=
0x58
;
/* The I2C address */
if
(
ioctl
(
file
,
I2C_SLAVE
,
addr
)
<
0
)
{
if
(
ioctl
(
file
,
I2C_SLAVE
,
i2c_addr
)
<
0
)
{
/* ERROR HANDLING; you can check errno to see what went wrong */
printf
(
"Error addressing i2c slave."
);
exit
(
1
);
...
...
@@ -65,61 +72,109 @@ static void addVariable(UA_Server *server) {
UA_NodeId
parentNodeId
=
UA_NODEID_NUMERIC
(
0
,
UA_NS0ID_OBJECTSFOLDER
);
UA_NodeId
parentReferenceNodeId
=
UA_NODEID_NUMERIC
(
0
,
UA_NS0ID_ORGANIZES
);
// relay 0
//
I2C0 /
relay 0
UA_VariableAttributes
attr0
=
UA_VariableAttributes_default
;
UA_Variant_setScalar
(
&
attr0
.
value
,
&
myInteger
,
&
UA_TYPES
[
UA_TYPES_INT32
]);
attr0
.
description
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"Relay 0"
);
attr0
.
displayName
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"Relay 0"
);
attr0
.
description
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"
I2C0 /
Relay 0"
);
attr0
.
displayName
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"
I2C0 /
Relay 0"
);
attr0
.
dataType
=
UA_TYPES
[
UA_TYPES_INT32
].
typeId
;
attr0
.
accessLevel
=
UA_ACCESSLEVELMASK_READ
|
UA_ACCESSLEVELMASK_WRITE
;
UA_NodeId
myIntegerNodeId0
=
UA_NODEID_STRING
(
1
,
"relay0"
);
UA_QualifiedName
myIntegerName0
=
UA_QUALIFIEDNAME
(
1
,
"Relay 0"
);
UA_NodeId
myIntegerNodeId0
=
UA_NODEID_STRING
(
1
,
"i2c0.relay0"
);
UA_QualifiedName
myIntegerName0
=
UA_QUALIFIEDNAME
(
1
,
"I2C0 / Relay 0"
);
UA_Server_addVariableNode
(
server
,
myIntegerNodeId0
,
parentNodeId
,
parentReferenceNodeId
,
myIntegerName0
,
UA_NODEID_NUMERIC
(
0
,
UA_NS0ID_BASEDATAVARIABLETYPE
),
attr0
,
NULL
,
NULL
);
// relay 1
//
I2C0 /
relay 1
UA_VariableAttributes
attr1
=
UA_VariableAttributes_default
;
UA_Variant_setScalar
(
&
attr1
.
value
,
&
myInteger
,
&
UA_TYPES
[
UA_TYPES_INT32
]);
attr1
.
description
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"Relay 1"
);
attr1
.
displayName
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"Relay 1"
);
attr1
.
description
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"
I2C0 /
Relay 1"
);
attr1
.
displayName
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"
I2C0 /
Relay 1"
);
attr1
.
dataType
=
UA_TYPES
[
UA_TYPES_INT32
].
typeId
;
attr1
.
accessLevel
=
UA_ACCESSLEVELMASK_READ
|
UA_ACCESSLEVELMASK_WRITE
;
UA_NodeId
myIntegerNodeId1
=
UA_NODEID_STRING
(
1
,
"relay1"
);
UA_QualifiedName
myIntegerName1
=
UA_QUALIFIEDNAME
(
1
,
"Relay 1"
);
UA_NodeId
myIntegerNodeId1
=
UA_NODEID_STRING
(
1
,
"i2c0.relay1"
);
UA_QualifiedName
myIntegerName1
=
UA_QUALIFIEDNAME
(
1
,
"I2C0 / Relay 1"
);
UA_Server_addVariableNode
(
server
,
myIntegerNodeId1
,
parentNodeId
,
parentReferenceNodeId
,
myIntegerName1
,
UA_NODEID_NUMERIC
(
0
,
UA_NS0ID_BASEDATAVARIABLETYPE
),
attr1
,
NULL
,
NULL
);
// relay 2
//
I2C0 /
relay 2
UA_VariableAttributes
attr2
=
UA_VariableAttributes_default
;
UA_Variant_setScalar
(
&
attr2
.
value
,
&
myInteger
,
&
UA_TYPES
[
UA_TYPES_INT32
]);
attr2
.
description
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"Relay 2"
);
attr2
.
displayName
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"Relay 2"
);
attr2
.
description
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"
I2C0 /
Relay 2"
);
attr2
.
displayName
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"
I2C0 /
Relay 2"
);
attr2
.
dataType
=
UA_TYPES
[
UA_TYPES_INT32
].
typeId
;
attr2
.
accessLevel
=
UA_ACCESSLEVELMASK_READ
|
UA_ACCESSLEVELMASK_WRITE
;
UA_NodeId
myIntegerNodeId2
=
UA_NODEID_STRING
(
1
,
"relay2"
);
UA_QualifiedName
myIntegerName2
=
UA_QUALIFIEDNAME
(
1
,
"Relay 2"
);
UA_NodeId
myIntegerNodeId2
=
UA_NODEID_STRING
(
1
,
"i2c0.relay2"
);
UA_QualifiedName
myIntegerName2
=
UA_QUALIFIEDNAME
(
1
,
"I2C0 / Relay 2"
);
UA_Server_addVariableNode
(
server
,
myIntegerNodeId2
,
parentNodeId
,
parentReferenceNodeId
,
myIntegerName2
,
UA_NODEID_NUMERIC
(
0
,
UA_NS0ID_BASEDATAVARIABLETYPE
),
attr2
,
NULL
,
NULL
);
// relay 3
//
I2C0 /
relay 3
UA_VariableAttributes
attr3
=
UA_VariableAttributes_default
;
UA_Variant_setScalar
(
&
attr3
.
value
,
&
myInteger
,
&
UA_TYPES
[
UA_TYPES_INT32
]);
attr3
.
description
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"Relay 3"
);
attr3
.
displayName
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"Relay 3"
);
attr3
.
description
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"
I2C0 /
Relay 3"
);
attr3
.
displayName
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"
I2C0 /
Relay 3"
);
attr3
.
dataType
=
UA_TYPES
[
UA_TYPES_INT32
].
typeId
;
attr3
.
accessLevel
=
UA_ACCESSLEVELMASK_READ
|
UA_ACCESSLEVELMASK_WRITE
;
UA_NodeId
myIntegerNodeId3
=
UA_NODEID_STRING
(
1
,
"relay3"
);
UA_QualifiedName
myIntegerName3
=
UA_QUALIFIEDNAME
(
1
,
"Relay 3"
);
UA_NodeId
myIntegerNodeId3
=
UA_NODEID_STRING
(
1
,
"i2c0.relay3"
);
UA_QualifiedName
myIntegerName3
=
UA_QUALIFIEDNAME
(
1
,
"I2C0 / Relay 3"
);
UA_Server_addVariableNode
(
server
,
myIntegerNodeId3
,
parentNodeId
,
parentReferenceNodeId
,
myIntegerName3
,
UA_NODEID_NUMERIC
(
0
,
UA_NS0ID_BASEDATAVARIABLETYPE
),
attr3
,
NULL
,
NULL
);
// I2C1 / relay 0
UA_VariableAttributes
attr4
=
UA_VariableAttributes_default
;
UA_Variant_setScalar
(
&
attr4
.
value
,
&
myInteger
,
&
UA_TYPES
[
UA_TYPES_INT32
]);
attr4
.
description
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"I2C1 / Relay 0"
);
attr4
.
displayName
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"I2C1 / Relay 0"
);
attr4
.
dataType
=
UA_TYPES
[
UA_TYPES_INT32
].
typeId
;
attr4
.
accessLevel
=
UA_ACCESSLEVELMASK_READ
|
UA_ACCESSLEVELMASK_WRITE
;
UA_NodeId
myIntegerNodeId4
=
UA_NODEID_STRING
(
1
,
"i2c1.relay0"
);
UA_QualifiedName
myIntegerName4
=
UA_QUALIFIEDNAME
(
1
,
"I2C1 / Relay 0"
);
UA_Server_addVariableNode
(
server
,
myIntegerNodeId4
,
parentNodeId
,
parentReferenceNodeId
,
myIntegerName4
,
UA_NODEID_NUMERIC
(
0
,
UA_NS0ID_BASEDATAVARIABLETYPE
),
attr4
,
NULL
,
NULL
);
// I2C1 / relay 1
UA_VariableAttributes
attr5
=
UA_VariableAttributes_default
;
UA_Variant_setScalar
(
&
attr5
.
value
,
&
myInteger
,
&
UA_TYPES
[
UA_TYPES_INT32
]);
attr5
.
description
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"I2C1 / Relay 1"
);
attr5
.
displayName
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"I2C1 / Relay 1"
);
attr5
.
dataType
=
UA_TYPES
[
UA_TYPES_INT32
].
typeId
;
attr5
.
accessLevel
=
UA_ACCESSLEVELMASK_READ
|
UA_ACCESSLEVELMASK_WRITE
;
UA_NodeId
myIntegerNodeId5
=
UA_NODEID_STRING
(
1
,
"i2c1.relay1"
);
UA_QualifiedName
myIntegerName5
=
UA_QUALIFIEDNAME
(
1
,
"I2C1 / Relay 1"
);
UA_Server_addVariableNode
(
server
,
myIntegerNodeId5
,
parentNodeId
,
parentReferenceNodeId
,
myIntegerName5
,
UA_NODEID_NUMERIC
(
0
,
UA_NS0ID_BASEDATAVARIABLETYPE
),
attr5
,
NULL
,
NULL
);
// I2C1 / relay 2
UA_VariableAttributes
attr6
=
UA_VariableAttributes_default
;
UA_Variant_setScalar
(
&
attr6
.
value
,
&
myInteger
,
&
UA_TYPES
[
UA_TYPES_INT32
]);
attr6
.
description
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"I2C1 / Relay 2"
);
attr6
.
displayName
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"I2C1 / Relay 2"
);
attr6
.
dataType
=
UA_TYPES
[
UA_TYPES_INT32
].
typeId
;
attr6
.
accessLevel
=
UA_ACCESSLEVELMASK_READ
|
UA_ACCESSLEVELMASK_WRITE
;
UA_NodeId
myIntegerNodeId6
=
UA_NODEID_STRING
(
1
,
"i2c1.relay2"
);
UA_QualifiedName
myIntegerName6
=
UA_QUALIFIEDNAME
(
1
,
"I2C1 / Relay 2"
);
UA_Server_addVariableNode
(
server
,
myIntegerNodeId6
,
parentNodeId
,
parentReferenceNodeId
,
myIntegerName6
,
UA_NODEID_NUMERIC
(
0
,
UA_NS0ID_BASEDATAVARIABLETYPE
),
attr6
,
NULL
,
NULL
);
// I2C1 / relay 3
UA_VariableAttributes
attr7
=
UA_VariableAttributes_default
;
UA_Variant_setScalar
(
&
attr7
.
value
,
&
myInteger
,
&
UA_TYPES
[
UA_TYPES_INT32
]);
attr7
.
description
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"I2C1 / Relay 3"
);
attr7
.
displayName
=
UA_LOCALIZEDTEXT
(
"en-US"
,
"I2C1 / Relay 3"
);
attr7
.
dataType
=
UA_TYPES
[
UA_TYPES_INT32
].
typeId
;
attr7
.
accessLevel
=
UA_ACCESSLEVELMASK_READ
|
UA_ACCESSLEVELMASK_WRITE
;
UA_NodeId
myIntegerNodeId7
=
UA_NODEID_STRING
(
1
,
"i2c1.relay3"
);
UA_QualifiedName
myIntegerName7
=
UA_QUALIFIEDNAME
(
1
,
"I2C1 / Relay 3"
);
UA_Server_addVariableNode
(
server
,
myIntegerNodeId7
,
parentNodeId
,
parentReferenceNodeId
,
myIntegerName7
,
UA_NODEID_NUMERIC
(
0
,
UA_NS0ID_BASEDATAVARIABLETYPE
),
attr7
,
NULL
,
NULL
);
}
/* Connect to variables to physical relays
...
...
@@ -134,144 +189,207 @@ static void beforeReadTime(UA_Server *server,
// XXX: having afterWriteTime{0..3} is not needed and maybe with introspection of context we can
// write only one callback function
static
void
afterWriteTime0
(
UA_Server
*
server
,
static
void
afterWriteTimeI2C0_0
(
UA_Server
*
server
,
const
UA_NodeId
*
sessionId
,
void
*
sessionContext
,
const
UA_NodeId
*
nodeId
,
void
*
nodeContext
,
const
UA_NumericRange
*
range
,
const
UA_DataValue
*
data
)
{
if
(
data
->
value
.
type
==
&
UA_TYPES
[
UA_TYPES_INT32
])
{
UA_Int32
hrValue
=
*
(
UA_Int32
*
)
data
->
value
.
data
;
if
(
hrValue
>
0
){
I2C_0_RELAYS_STATE
|=
1UL
<<
0
;
setRelayState
(
I2C_0_RELAYS_STATE
,
I2C_0_ADDR
);
}
else
{
I2C_0_RELAYS_STATE
&=
~
(
1UL
<<
0
);
setRelayState
(
I2C_0_RELAYS_STATE
,
I2C_0_ADDR
);
}
}
}
static
void
afterWriteTimeI2C0_1
(
UA_Server
*
server
,
const
UA_NodeId
*
sessionId
,
void
*
sessionContext
,
const
UA_NodeId
*
nodeId
,
void
*
nodeContext
,
const
UA_NumericRange
*
range
,
const
UA_DataValue
*
data
)
{
if
(
data
->
value
.
type
==
&
UA_TYPES
[
UA_TYPES_INT32
])
{
UA_Int32
hrValue
=
*
(
UA_Int32
*
)
data
->
value
.
data
;
if
(
hrValue
>
0
){
I2C_0_RELAYS_STATE
|=
1UL
<<
1
;
setRelayState
(
I2C_0_RELAYS_STATE
,
I2C_0_ADDR
);
}
else
{
I2C_0_RELAYS_STATE
&=
~
(
1UL
<<
1
);
setRelayState
(
I2C_0_RELAYS_STATE
,
I2C_0_ADDR
);
}
}
}
static
void
afterWriteTimeI2C0_2
(
UA_Server
*
server
,
const
UA_NodeId
*
sessionId
,
void
*
sessionContext
,
const
UA_NodeId
*
nodeId
,
void
*
nodeContext
,
const
UA_NumericRange
*
range
,
const
UA_DataValue
*
data
)
{
if
(
data
->
value
.
type
==
&
UA_TYPES
[
UA_TYPES_INT32
])
{
UA_Int32
hrValue
=
*
(
UA_Int32
*
)
data
->
value
.
data
;
if
(
hrValue
>
0
){
I2C_0_RELAYS_STATE
|=
1UL
<<
2
;
setRelayState
(
I2C_0_RELAYS_STATE
,
I2C_0_ADDR
);
}
else
{
I2C_0_RELAYS_STATE
&=
~
(
1UL
<<
2
);
setRelayState
(
I2C_0_RELAYS_STATE
,
I2C_0_ADDR
);
}
}
}
static
void
afterWriteTimeI2C0_3
(
UA_Server
*
server
,
const
UA_NodeId
*
sessionId
,
void
*
sessionContext
,
const
UA_NodeId
*
nodeId
,
void
*
nodeContext
,
const
UA_NumericRange
*
range
,
const
UA_DataValue
*
data
)
{
//UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "The variable was updated");
if
(
data
->
value
.
type
==
&
UA_TYPES
[
UA_TYPES_INT32
])
{
UA_Int32
hrValue
=
*
(
UA_Int32
*
)
data
->
value
.
data
;
if
(
hrValue
>
0
){
myrelay
|=
1UL
<<
0
;
// relay0
setRelayState
(
myrelay
);
I2C_0_RELAYS_STATE
|=
1UL
<<
3
;
setRelayState
(
I2C_0_RELAYS_STATE
,
I2C_0_ADDR
);
}
else
{
myrelay
&=
~
(
1UL
<<
0
);
// relay0
setRelayState
(
myrelay
);
I2C_0_RELAYS_STATE
&=
~
(
1UL
<<
3
);
setRelayState
(
I2C_0_RELAYS_STATE
,
I2C_0_ADDR
);
}
}
}
static
void
afterWriteTime1
(
UA_Server
*
server
,
// I2C1
static
void
afterWriteTimeI2C1_0
(
UA_Server
*
server
,
const
UA_NodeId
*
sessionId
,
void
*
sessionContext
,
const
UA_NodeId
*
nodeId
,
void
*
nodeContext
,
const
UA_NumericRange
*
range
,
const
UA_DataValue
*
data
)
{
//UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "The variable was updated");
if
(
data
->
value
.
type
==
&
UA_TYPES
[
UA_TYPES_INT32
])
{
UA_Int32
hrValue
=
*
(
UA_Int32
*
)
data
->
value
.
data
;
if
(
hrValue
>
0
){
myrelay
|=
1UL
<<
1
;
setRelayState
(
myrelay
);
I2C_1_RELAYS_STATE
|=
1UL
<<
0
;
setRelayState
(
I2C_1_RELAYS_STATE
,
I2C_1_ADDR
);
}
else
{
myrelay
&=
~
(
1UL
<<
1
);
setRelayState
(
myrelay
);
I2C_1_RELAYS_STATE
&=
~
(
1UL
<<
0
);
setRelayState
(
I2C_1_RELAYS_STATE
,
I2C_1_ADDR
);
}
}
}
static
void
afterWriteTime
2
(
UA_Server
*
server
,
static
void
afterWriteTime
I2C1_1
(
UA_Server
*
server
,
const
UA_NodeId
*
sessionId
,
void
*
sessionContext
,
const
UA_NodeId
*
nodeId
,
void
*
nodeContext
,
const
UA_NumericRange
*
range
,
const
UA_DataValue
*
data
)
{
//UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "The variable was updated");
if
(
data
->
value
.
type
==
&
UA_TYPES
[
UA_TYPES_INT32
])
{
UA_Int32
hrValue
=
*
(
UA_Int32
*
)
data
->
value
.
data
;
if
(
hrValue
>
0
){
myrelay
|=
1UL
<<
2
;
setRelayState
(
myrelay
);
I2C_1_RELAYS_STATE
|=
1UL
<<
1
;
setRelayState
(
I2C_1_RELAYS_STATE
,
I2C_1_ADDR
);
}
else
{
myrelay
&=
~
(
1UL
<<
2
);
setRelayState
(
myrelay
);
I2C_1_RELAYS_STATE
&=
~
(
1UL
<<
1
);
setRelayState
(
I2C_1_RELAYS_STATE
,
I2C_1_ADDR
);
}
}
}
static
void
afterWriteTime
3
(
UA_Server
*
server
,
static
void
afterWriteTime
I2C1_2
(
UA_Server
*
server
,
const
UA_NodeId
*
sessionId
,
void
*
sessionContext
,
const
UA_NodeId
*
nodeId
,
void
*
nodeContext
,
const
UA_NumericRange
*
range
,
const
UA_DataValue
*
data
)
{
//UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "The variable was updated");
if
(
data
->
value
.
type
==
&
UA_TYPES
[
UA_TYPES_INT32
])
{
UA_Int32
hrValue
=
*
(
UA_Int32
*
)
data
->
value
.
data
;
if
(
hrValue
>
0
){
myrelay
|=
1UL
<<
3
;
setRelayState
(
myrelay
);
I2C_1_RELAYS_STATE
|=
1UL
<<
2
;
setRelayState
(
I2C_1_RELAYS_STATE
,
I2C_1_ADDR
);
}
else
{
myrelay
&=
~
(
1UL
<<
3
);
setRelayState
(
myrelay
);
I2C_1_RELAYS_STATE
&=
~
(
1UL
<<
2
);
setRelayState
(
I2C_1_RELAYS_STATE
,
I2C_1_ADDR
);
}
}
}
static
void
afterWriteTimeI2C1_3
(
UA_Server
*
server
,
const
UA_NodeId
*
sessionId
,
void
*
sessionContext
,
const
UA_NodeId
*
nodeId
,
void
*
nodeContext
,
const
UA_NumericRange
*
range
,
const
UA_DataValue
*
data
)
{
if
(
data
->
value
.
type
==
&
UA_TYPES
[
UA_TYPES_INT32
])
{
UA_Int32
hrValue
=
*
(
UA_Int32
*
)
data
->
value
.
data
;
if
(
hrValue
>
0
){
I2C_1_RELAYS_STATE
|=
1UL
<<
3
;
setRelayState
(
I2C_1_RELAYS_STATE
,
I2C_1_ADDR
);
}
else
{
I2C_1_RELAYS_STATE
&=
~
(
1UL
<<
3
);
setRelayState
(
I2C_1_RELAYS_STATE
,
I2C_1_ADDR
);
}
}
}
static
void
addValueCallbackToCurrentTimeVariable
(
UA_Server
*
server
)
{
// I2C0
// relay 0
UA_NodeId
currentNodeId0
=
UA_NODEID_STRING
(
1
,
"relay0"
);
UA_NodeId
currentNodeId0
=
UA_NODEID_STRING
(
1
,
"
i2c0.
relay0"
);
UA_ValueCallback
callback0
;
callback0
.
onRead
=
beforeReadTime
;
callback0
.
onWrite
=
afterWriteTime0
;
callback0
.
onWrite
=
afterWriteTime
I2C0_
0
;
UA_Server_setVariableNode_valueCallback
(
server
,
currentNodeId0
,
callback0
);
// relay 1
UA_NodeId
currentNodeId1
=
UA_NODEID_STRING
(
1
,
"relay1"
);
UA_NodeId
currentNodeId1
=
UA_NODEID_STRING
(
1
,
"
i2c0.
relay1"
);
UA_ValueCallback
callback1
;
callback1
.
onRead
=
beforeReadTime
;
callback1
.
onWrite
=
afterWriteTime1
;
callback1
.
onWrite
=
afterWriteTime
I2C0_
1
;
UA_Server_setVariableNode_valueCallback
(
server
,
currentNodeId1
,
callback1
);
// relay 2
UA_NodeId
currentNodeId2
=
UA_NODEID_STRING
(
1
,
"relay2"
);
UA_NodeId
currentNodeId2
=
UA_NODEID_STRING
(
1
,
"
i2c0.
relay2"
);
UA_ValueCallback
callback2
;
callback2
.
onRead
=
beforeReadTime
;
callback2
.
onWrite
=
afterWriteTime2
;
callback2
.
onWrite
=
afterWriteTime
I2C0_
2
;
UA_Server_setVariableNode_valueCallback
(
server
,
currentNodeId2
,
callback2
);
// relay 3
UA_NodeId
currentNodeId3
=
UA_NODEID_STRING
(
1
,
"relay3"
);
UA_NodeId
currentNodeId3
=
UA_NODEID_STRING
(
1
,
"
i2c0.
relay3"
);
UA_ValueCallback
callback3
;
callback3
.
onRead
=
beforeReadTime
;
callback3
.
onWrite
=
afterWriteTime3
;
callback3
.
onWrite
=
afterWriteTime
I2C0_
3
;
UA_Server_setVariableNode_valueCallback
(
server
,
currentNodeId3
,
callback3
);
}
// I2C1
// relay 0
UA_NodeId
currentNodeId4
=
UA_NODEID_STRING
(
1
,
"i2c1.relay0"
);
UA_ValueCallback
callback4
;
callback4
.
onRead
=
beforeReadTime
;
callback4
.
onWrite
=
afterWriteTimeI2C1_0
;
UA_Server_setVariableNode_valueCallback
(
server
,
currentNodeId4
,
callback4
);
/**
* Now we change the value with the write service. This uses the same service
* implementation that can also be reached over the network by an OPC UA client.
*/
// relay 1
UA_NodeId
currentNodeId5
=
UA_NODEID_STRING
(
1
,
"i2c1.relay1"
);
UA_ValueCallback
callback5
;
callback5
.
onRead
=
beforeReadTime
;
callback5
.
onWrite
=
afterWriteTimeI2C1_1
;
UA_Server_setVariableNode_valueCallback
(
server
,
currentNodeId5
,
callback5
);
// relay 2
UA_NodeId
currentNodeId6
=
UA_NODEID_STRING
(
1
,
"i2c1.relay2"
);
UA_ValueCallback
callback6
;
callback6
.
onRead
=
beforeReadTime
;
callback6
.
onWrite
=
afterWriteTimeI2C1_2
;
UA_Server_setVariableNode_valueCallback
(
server
,
currentNodeId6
,
callback6
);
static
void
writeVariable
(
UA_Server
*
server
)
{
UA_NodeId
myIntegerNodeId
=
UA_NODEID_STRING
(
1
,
"relay0"
);
// relay 2
UA_NodeId
currentNodeId7
=
UA_NODEID_STRING
(
1
,
"i2c1.relay3"
);
UA_ValueCallback
callback7
;
callback7
.
onRead
=
beforeReadTime
;
callback7
.
onWrite
=
afterWriteTimeI2C1_3
;
UA_Server_setVariableNode_valueCallback
(
server
,
currentNodeId7
,
callback7
);
/* Write a different integer value */
UA_Int32
myInteger
=
0
;
UA_Variant
myVar
;
UA_Variant_init
(
&
myVar
);
UA_Variant_setScalar
(
&
myVar
,
&
myInteger
,
&
UA_TYPES
[
UA_TYPES_INT32
]);
UA_Server_writeValue
(
server
,
myIntegerNodeId
,
myVar
);
/* Set the status code of the value to an error code. The function
* UA_Server_write provides access to the raw service. The above
* UA_Server_writeValue is syntactic sugar for writing a specific node
* attribute with the write service. */
UA_WriteValue
wv
;
UA_WriteValue_init
(
&
wv
);
wv
.
nodeId
=
myIntegerNodeId
;
wv
.
attributeId
=
UA_ATTRIBUTEID_VALUE
;
wv
.
value
.
status
=
UA_STATUSCODE_BADNOTCONNECTED
;
wv
.
value
.
hasStatus
=
true
;
UA_Server_write
(
server
,
&
wv
);
/* Reset the variable to a good statuscode with a value */
wv
.
value
.
hasStatus
=
false
;
wv
.
value
.
value
=
myVar
;
wv
.
value
.
hasValue
=
true
;
UA_Server_write
(
server
,
&
wv
);
}
static
volatile
UA_Boolean
running
=
true
;
static
void
stopHandler
(
int
sign
)
{
...
...
@@ -281,7 +399,7 @@ static void stopHandler(int sign) {
int
main
(
void
)
{
// set all relays to OFF at startup
setRelayState
(
0x00
);
setRelayState
(
0x00
,
I2C_0_ADDR
);
signal
(
SIGINT
,
stopHandler
);
signal
(
SIGTERM
,
stopHandler
);
...
...
@@ -290,12 +408,8 @@ int main(void) {
UA_ServerConfig_setDefault
(
UA_Server_getConfig
(
server
));
UA_ServerConfig
*
config
=
UA_Server_getConfig
(
server
);
config
->
verifyRequestTimestamp
=
UA_RULEHANDLING_ACCEPT
;
//#ifdef UA_ENABLE_WEBSOCKET_SERVER
// UA_ServerConfig_addNetworkLayerWS(UA_Server_getConfig(server), 7681, 0, 0, NULL, NULL);
//#endif
addVariable
(
server
);
writeVariable
(
server
);
addValueCallbackToCurrentTimeVariable
(
server
);
UA_StatusCode
retval
=
UA_Server_run
(
server
,
&
running
);
...
...
@@ -303,7 +417,7 @@ int main(void) {
UA_Server_delete
(
server
);
// set all relays to OFF at startup
setRelayState
(
0x00
);
setRelayState
(
0x00
,
I2C_0_ADDR
);
return
retval
==
UA_STATUSCODE_GOOD
?
EXIT_SUCCESS
:
EXIT_FAILURE
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment