Closed techvoipit closed 10 months ago
Hi @techvoipit. If I understand you well, you are asking for a sample code to write values, like the sample code on main page is prepared to read values.
If this is what you need, I have prepared a sample code for you. I have refactored the main sample code into smaller methods to increase readability. And also this code should be considered as learning material only (not production ready as-is).
The sample is prepared to:
You can adapt it to other node types simply modifying the code in Main method. I hope you can find it useful enough.
Don't forget to add your server data here at the beginning:
const string endpointUrl = "<your OPC UA endpoint>";
const string nodeId = "<a bool node id (for this sample)>";
Read-Write sample code:
using Workstation.ServiceModel.Ua;
using Workstation.ServiceModel.Ua.Channels;
namespace WriteNodeTest
{
internal static class Program
{
public static async Task Main(string[] args)
{
const string endpointUrl = "<your OPC UA endpoint>";
const string nodeId = "<a bool node id (for this sample)>";
var channel = GetAnonymousChannel(endpointUrl);
bool nodeValue = false;
bool newNodeValue = false;
try
{
await channel.OpenAsync();
nodeValue = await ReadNodeValue<bool>(channel, nodeId);
await WriteNodeValue(channel, nodeId, !nodeValue);
newNodeValue = await ReadNodeValue<bool>(channel, nodeId);
await channel.CloseAsync();
}
catch (Exception ex)
{
await channel.AbortAsync();
Console.WriteLine(ex.Message);
}
Console.WriteLine($"First value was {nodeValue} and now is {newNodeValue}");
}
private static async Task WriteNodeValue<T>(ClientSessionChannel channel, string nodeId, T newNodeValue)
{
var writeRequest = new WriteRequest
{
NodesToWrite = new[]
{
new WriteValue
{
NodeId = NodeId.Parse(nodeId),
AttributeId = AttributeIds.Value,
Value = new DataValue(newNodeValue)
}
}
};
await channel.WriteAsync(writeRequest);
}
private static async Task<T> ReadNodeValue<T>(ClientSessionChannel channel, string nodeId)
{
var readRequest = new ReadRequest
{
NodesToRead = new[] {
new ReadValueId
{
NodeId = NodeId.Parse(nodeId),
AttributeId = AttributeIds.Value
}
}
};
var readResult = await channel.ReadAsync(readRequest);
return readResult.Results[0].GetValueOrDefault<T>();
}
private static ClientSessionChannel GetAnonymousChannel(string endpointUrl)
{
var clientDescription = GetClientDescription();
// create a 'ClientSessionChannel', a client-side channel that opens a 'session' with the server.
return new ClientSessionChannel(
clientDescription,
null, // no x509 certificates
new AnonymousIdentity(), // no user identity
endpointUrl,
SecurityPolicyUris.None); // no encryption
}
private static ApplicationDescription GetClientDescription()
{
// describe this client application.
return new ApplicationDescription
{
ApplicationName = "Workstation.UaClient.FeatureTests",
ApplicationUri = $"urn:{System.Net.Dns.GetHostName()}:Workstation.UaClient.FeatureTests",
ApplicationType = ApplicationType.Client
};
}
}
}
Hi @ismdiego, thank you for the code I tried (at the moment I can play only with int) the procedure is working (no errors) but value is not updated this is my code:
public async Task<string> scriviAsync(ClientSessionChannel channel, string nodo, string valorenodo)
{
val = null;
if (channel == null)
{
// Canale non inizializzato, gestire l'errore.
Console.WriteLine("Errore: Canale non inizializzato.");
return val;
}
var writeRequest = new WriteRequest
{
NodesToWrite = new[]
{
new WriteValue
{
NodeId = NodeId.Parse(nodo),
AttributeId = AttributeIds.Value,
Value = new DataValue(valorenodo)
}
}
};
try
{
await channel.WriteAsync(writeRequest);
}
catch (Exception ex)
{
await channel.AbortAsync();
Console.WriteLine(ex.Message);
}
return val;
}
@techvoipit you say "(at the moment I can play only with int)", but I see that here "valorenodo" is defined as string, not int. Maybe this is the problem you are having?
public async Task<string> scriviAsync( ClientSessionChannel channel, string nodo, string valorenodo) ... Value = new DataValue(valorenodo)
Try changing valorenodo to int and see what happens.
And other question, can you read the value with the provided channel and/or nodeId?
Hi, i would like to change values to nodes, i have a look to sample code but i didn't find anything can you please publish a sample code how I can do it ?