Muutoshistoria (vain ensimmäinen versio, julkaistu 1.11.2026)
- Ensimmäinen julkaisu
Lainaa tätä artikkelia(DOI: 10.5281/zenodo.23968421)
Tämä artikkeli on arkistoitu Zenodoon. Alla on sekä DOI, joka johtaa aina uusimpaan versioon, että DOI, joka on sidottu parhaillaan näytettävään versioon.
Go Komura (2026). OPC UA:n perusteet ── PLC:iden ja laitteiden tietojen keruu Windows-sovellukseen. KomuraSoft LLC. https://doi.org/10.5281/zenodo.23968421 https://comcomponent.com/fi/blog/opc-ua-windows-data-collection/
- DOI (uusin versio)
- 10.5281/zenodo.23968421
- DOI (tämä versio)
- 10.5281/zenodo.23968422
Kun PLC:iden tai laitteiden tietoja kerätään Windows-sovellukseen ja laitteessa on OPC UA -palvelin, jokaiselle valmistajalle ei välttämättä tarvitse kirjoittaa omaa tiedonsiirtoa. Pelkkä yhdistäminen ja arvojen lukeminen ei kuitenkaan riitä. Jos et tunne arvon mukana palaavaa tilaa ja aikaleimoja, muutoksista ilmoittavia tilauksia, yhteyksien sallimista varmenteilla ja katkoksista toipumista, kerättyihin tietoihin ei voi myöhemmin luottaa.
Tämä artikkeli selittää ne OPC UA:n osat, joita tiedonkeruussa tarvitaan, ja näyttää tulokset C#-asiakkaan todellisista ajoista. Asiakas käyttää OPC Foundationin .NET-kirjastoa, ja vastapuolena on simuloitu laitepalvelin. En ole kokeillut tätä millään tietyllä PLC:llä tai laitteella. Tarkista laitekohtaiset asetukset kyseisen laitteen dokumentaatiosta.
Kuvien keruuta GigE Vision- ja USB3 Vision -kameroista käsitellään artikkelissa “Dropped Frames with GigE Vision and USB3 Vision Cameras” ja sarjaliikennettä käyttäviä laitteita artikkelissa “Serial Communication App Pitfalls”.
OPC UA:n ja OPC Classicin ero
OPC Classicin määritykset välittävät tietoja ohjelmistokomponenttien välillä Windowsin COM/DCOM-tekniikalla. Prosessitietoja käsittelevä OPC DA, hälytyksiä käsittelevä OPC A&E ja historiatietoja käsittelevä OPC HDA on määritelty erillisinä määrityksinä1.
OPC Foundation julkaisi OPC UA:n (Unified Architecture) vuonna 2008. OPC UA on palvelukeskeinen arkkitehtuuri, joka ei ole sidottu tiettyyn alustaan ja joka kokoaa yhteen kunkin Classic-määrityksen toiminnot. Uudelleensuunnittelun syiksi OPC Foundation mainitsee muun muassa sen, että Microsoft alkoi painottaa COM/DCOMia enemmän alustariippumattomia tekniikoita, että järjestelmän piti toimia myös muissa kuin Microsoftin järjestelmissä ja sulautetuissa laitteissa ja että yhteyksiä piti voida muodostaa turvallisesti palomuurien läpi1.
OPC UA -määritys on myös IEC:n standardoima IEC 62541 -sarjana2. Tietoliikenneportiksi IANA on rekisteröinyt 4840/TCP:n nimellä opcua-tcp3.
flowchart TB
accTitle: OPC Classicin ja OPC UA:n ero
accDescr: Kaavio, joka näyttää, että OPC Classic perustuu Windowsin COM- ja DCOM-tekniikkaan ja jakautuu erillisiin DA-, A&E- ja HDA-määrityksiin, kun taas OPC UA kokoaa niiden toiminnot yhdeksi alustasta riippumattomaksi määritykseksi.
C["OPC Classic"] --> D["Toimii COM/DCOM:n päällä (Windows)"]
D --> DA["Jaettu DA-, A&E- ja HDA-määrityksiin"]
DA -->|"Toiminnot kootaan yhteen"| U["OPC UA (2008)"]
U --> P["Ei sidottu tiettyyn alustaan"]
P --> S["Standardoitu nimellä IEC 62541"]
Kuva 1: OPC Classic koostuu erillisistä määrityksistä COM/DCOM:n päällä, ja OPC UA kokoaa ne yhdeksi.
Jos olemassa olevassa laitteistossa on vain OPC DA -palvelin, tarvitaan COM/DCOMia käyttävä ratkaisu. Tämä artikkeli käsittelee vain OPC UA:ta.
Kaaviossa yhtenäinen viiva kuvaa suhdetta, joka pätee aina, ja katkoviiva ehdollista suhdetta (ehdot on kuvattu kunkin suhteen kohdalla yksityiskohtasivulla). Suhteiden täydellinen luettelo (yhteensä 13, todisteineen ja varmuustasoineen) sekä keskeisten käsitteiden määritelmät on koottu tietokartan yksityiskohtasivulle (japaniksi). Data: JSON-LD / Turtle
Kokeiltu kokoonpano
Ajoin seuraavan kokoonpanon.
| Rooli | Mitä käytin |
|---|---|
| Asiakas | C#, .NET 10 SDK 10.0.114, NuGet-paketti OPCFoundation.NetStandard.Opc.Ua.Client 2.0.1 |
| Palvelin | Pythonilla 3.13 ja asyncua 2.1.0:lla tehty simuloitu laite (portti 4840 samassa tietokoneessa) |
| Käyttöjärjestelmä | Linux (ajoa Windowsissa ei kokeiltu) |
Asiakaskirjasto on OPC Foundationin julkaisema .NET-toteutus. 2.0-sarjan käytössä noudatin saman tietovaraston Getting started -ohjeen tapaa4.
flowchart TB
accTitle: Kokeiltu kokoonpano
accDescr: Kaavio, joka näyttää C#-asiakkaan, joka käyttää OPC Foundationin .NET-kirjastoa ja yhdistää salatulla yhteydellä porttia 4840 kuuntelevaan asyncualla tehtyyn simuloituun laitepalvelimeen.
A["C#-asiakas (LineCollector)"] -->|"opc.tcp, SignAndEncrypt"| B["Simuloitu laitepalvelin (asyncua)"]
A -.-> L["OPC Foundationin .NET-kirjasto 2.0.1"]
B -.-> V["Neljä muuttujaa Line1:n alla"]
Kuva 2: C#-asiakas yhdisti simuloituun laitepalvelimeen saman tietokoneen sisällä.
Simuloitu laitepalvelin
Todellisen laitteen sijaan tein pienen palvelimen asyncualla5. Line1-nimisen objektin alla on neljä muuttujaa: lämpötila (Temperature), tuotemäärä (PartCount), käynnissä (Running) ja asetusarvo (Setpoint). Lämpötila muuttuu 0,5 sekunnin ja tuotemäärä 2 sekunnin välein. Suojaukseksi tarjosin kaksi vaihtoehtoa: ei salausta (None) sekä allekirjoitus ja salaus (Basic256Sha256:n SignAndEncrypt).
# Testaukseen tarkoitettu simuloitu laite. Se ei korvaa tuotantolaitteita tai PLC:itä.
import asyncio, math, random, socket
from pathlib import Path
from cryptography.x509.oid import ExtendedKeyUsageOID
from asyncua import Server, ua
from asyncua.crypto.cert_gen import setup_self_signed_certificate
HERE = Path(__file__).parent
APP_URI = "urn:komurasoft:demo-plc"
async def main():
key, cert = HERE / "server_key.pem", HERE / "server_cert.der"
await setup_self_signed_certificate(
key, cert, APP_URI, socket.gethostname(),
[ExtendedKeyUsageOID.SERVER_AUTH], {"commonName": "DemoPlcServer"})
server = Server()
await server.init()
server.set_endpoint("opc.tcp://0.0.0.0:4840/demo/")
server.set_server_name("DemoPlcServer")
await server.set_application_uri(APP_URI)
server.set_security_policy([
ua.SecurityPolicyType.NoSecurity,
ua.SecurityPolicyType.Basic256Sha256_SignAndEncrypt,
])
await server.load_certificate(str(cert))
await server.load_private_key(str(key))
ns = await server.register_namespace("urn:komurasoft:demo-plc:line1")
line1 = await server.nodes.objects.add_object(ua.NodeId("Line1", ns), "Line1")
temperature = await line1.add_variable(ua.NodeId("Line1.Temperature", ns), "Temperature", 25.0)
part_count = await line1.add_variable(
ua.NodeId("Line1.PartCount", ns), "PartCount", ua.Variant(0, ua.VariantType.UInt32))
await line1.add_variable(ua.NodeId("Line1.Running", ns), "Running", True)
setpoint = await line1.add_variable(ua.NodeId("Line1.Setpoint", ns), "Setpoint", 30.0)
await setpoint.set_writable()
async with server:
print("listening", flush=True)
t, count = 0, 0
while True:
await asyncio.sleep(0.5)
t += 1
value = 25.0 + 2.0 * math.sin(t / 4) + random.uniform(-0.05, 0.05)
await temperature.write_value(round(value, 2))
if t % 4 == 0:
count += 1
await part_count.write_value(ua.Variant(count, ua.VariantType.UInt32))
asyncio.run(main())
Tämä palvelin hyväksyy yhdistävien asiakkaiden varmenteet tarkistamatta niitä. Se on testiasetus, ja se poikkeaa tuotantolaitteiden toiminnasta.
C#-asiakas
Lisäsin projektitiedostoon nämä kaksi pakettia.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client" Version="2.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.0" />
</ItemGroup>
</Project>
Asiakas yhdistää, selaa, lukee, kirjoittaa ja tilaa tässä järjestyksessä. Seuraavat luvut selittävät, mitä kukin osa tarkoittaa.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Opc.Ua;
using Opc.Ua.Client;
using Opc.Ua.Client.Subscriptions;
using Opc.Ua.Client.Subscriptions.Streaming;
using MonitoredItemOptions = Opc.Ua.Client.Subscriptions.MonitoredItems.MonitoredItemOptions;
string url = args.Length > 0 ? args[0] : "opc.tcp://localhost:4840/demo/";
int notifications = args.Length > 1 ? int.Parse(args[1]) : 6;
const string LineNamespace = "urn:komurasoft:demo-plc:line1";
HostApplicationBuilder builder = Host.CreateApplicationBuilder();
builder.Logging.SetMinimumLevel(LogLevel.Warning);
builder.Services
.AddOpcUa()
.AddClient(options =>
{
options.ApplicationName = "LineCollector";
options.ApplicationUri = "urn:localhost:LineCollector";
options.ProductUri = "urn:komurasoft:LineCollector";
options.PkiRoot = Path.Combine(AppContext.BaseDirectory, "pki");
})
.AddDiscoveryAndConnect(options =>
{
options.DiscoveryUrl = url;
options.SecurityMode = MessageSecurityMode.SignAndEncrypt;
options.SecurityPolicyUri = SecurityPolicies.Basic256Sha256;
});
using IHost host = builder.Build();
await host.StartAsync();
using var timeout = new CancellationTokenSource(TimeSpan.FromMinutes(2));
CancellationToken ct = timeout.Token;
try
{
var connect = host.Services
.GetRequiredService<Func<CancellationToken, Task<ManagedSession>>>();
ManagedSession session = await connect(ct);
await using (session)
{
Console.WriteLine($"接続: {session.ConfiguredEndpoint?.EndpointUrl}");
// Palvelin päättää nimiavaruuden indeksin. Haetaan se URI:sta ja muodostetaan NodeIdit sen avulla
ushort ns = (ushort)session.NamespaceUris.GetIndex(LineNamespace);
var line1 = new NodeId("Line1", ns);
var temperature = new NodeId("Line1.Temperature", ns);
var partCount = new NodeId("Line1.PartCount", ns);
var setpoint = new NodeId("Line1.Setpoint", ns);
// Selaus: luetellaan Line1:n alla olevat muuttujat
var browser = new Browser(session)
{
BrowseDirection = BrowseDirection.Forward,
ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences,
IncludeSubtypes = true,
NodeClassMask = (uint)NodeClass.Variable,
};
Console.WriteLine("Line1 の変数:");
foreach (ReferenceDescription child in await browser.BrowseAsync(line1, ct))
{
Console.WriteLine($" {child.DisplayName} {child.NodeId}");
}
// Luku: katsotaan arvon lisäksi tila ja kaksi aikaleimaa
DataValue t = await session.ReadValueAsync(temperature, ct);
Console.WriteLine($"Temperature = {t.WrappedValue} 状態 {t.StatusCode}");
Console.WriteLine($" Source {Hms(t.SourceTimestamp)} / Server {Hms(t.ServerTimestamp)}");
// Olemattoman solmun lukeminen palauttaa arvon sijaan Bad-tilan
try
{
await session.ReadValueAsync(new NodeId("Line1.Pressure", ns), ct);
}
catch (ServiceResultException ex)
{
Console.WriteLine($"Line1.Pressure の読み取り: {ex.StatusCode}");
}
// Kirjoitus: asetetaan Setpoint arvoon 32.5
var write = new WriteValue
{
NodeId = setpoint,
AttributeId = Attributes.Value,
Value = new DataValue(new Variant(32.5)),
};
WriteResponse wr = await session.WriteAsync(null, new[] { write }, ct);
Console.WriteLine($"Setpoint の書き込み: {wr.Results[0]}");
// Tilaus: pyydetään palvelinta ottamaan näyte 500 ms:n välein ja ilmoittamaan muutoksista
Console.WriteLine($"購読({notifications}件まで):");
await foreach (DataValueChange change in session.DefaultStreaming
.SubscribeDataChangesAsync(new[] { temperature, partCount }, options: new MonitoredItemOptions
{
SamplingInterval = TimeSpan.FromMilliseconds(500),
QueueSize = 5,
}, ct: ct)
.TakeAsync(notifications)
.WithCancellation(ct))
{
DataValue v = change.Value;
string name = change.MonitoredItem?.Name.Split("s=")[^1] ?? "?";
Console.WriteLine($" {Hms(v.SourceTimestamp)} {name,-17} {v.WrappedValue,6} {v.StatusCode}");
}
}
}
catch (ServiceResultException ex)
{
Console.Error.WriteLine($"OPC UA エラー {ex.StatusCode}: {ex.Message}");
Environment.ExitCode = 1;
}
finally
{
await host.StopAsync();
}
static string Hms(DateTimeUtc time) => time.ToDateTime().ToString("HH:mm:ss.fff");
Ensimmäisellä ajokerralla yhteys ei onnistunut. Syy selitetään luvussa “Yhteyksien salliminen varmenteilla”. Alla on tuloste sen jälkeen, kun palvelimen varmenteeseen oli luotettu. Kirjaston varoituslokit on jätetty pois.
接続: opc.tcp://localhost:4840/demo/
Line1 の変数:
Temperature ns=2;s=Line1.Temperature
PartCount ns=2;s=Line1.PartCount
Running ns=2;s=Line1.Running
Setpoint ns=2;s=Line1.Setpoint
Temperature = 23.09 状態 Good [0x00000000]
Source 13:40:51.302 / Server 13:40:51.302
Line1.Pressure の読み取り: BadNodeIdUnknown [0x80340000]
Setpoint の書き込み: Good [0x00000000]
購読(6件まで):
13:40:51.302 Line1.Temperature 23.09 Good [0x00000000]
13:40:50.801 Line1.PartCount 67 Good [0x00000000]
13:40:51.802 Line1.Temperature 23.05 Good [0x00000000]
13:40:52.304 Line1.Temperature 23.07 Good [0x00000000]
13:40:52.806 Line1.Temperature 23.2 Good [0x00000000]
13:40:52.806 Line1.PartCount 68 Good [0x00000000]
Ajat ovat UTC-aikaa.
Laitteen tiedot näkyvät osoiteavaruuden solmuina
OPC UA -palvelin julkaisee hallussaan olevat tiedot solmujen joukkona. Tätä joukkoa kutsutaan osoiteavaruudeksi. Solmuja on eri lajeja, kuten kansioita tai laitteita kuvaavia objekteja ja arvoja sisältäviä muuttujia, ja solmut on yhdistetty toisiinsa viittauksilla. Asiakas seuraa viittauksia Browse-palvelulla ja selvittää, mitä solmuja on olemassa6.
Yllä olevassa tulosteessa asiakas seuraa hierarkkisia viittauksia Line1:stä ja löytää neljä muuttujaa.
flowchart TB
accTitle: Simuloidun laitteen osoiteavaruus
accDescr: Kaavio, joka näyttää Objects-kansion alla olevan Line1-objektin ja sen alla neljä muuttujaa: Temperature, PartCount, Running ja Setpoint.
O["Objects"] --> L["Line1 (objekti)"]
L --> T["Temperature (muuttuja)"]
L --> P["PartCount (muuttuja)"]
L --> R["Running (muuttuja)"]
L --> S["Setpoint (muuttuja, kirjoitettava)"]
Kuva 3: Simuloidun laitteen osoiteavaruus. Asiakas löytää solmut seuraamalla viittauksia Browse-palvelulla.
NodeId koostuu nimiavaruudesta ja tunnisteesta
Solmut tunnistetaan NodeIdillä. Tulosteen ns=2;s=Line1.Temperature tarkoittaa, että nimiavaruuden indeksi on 2 ja tunniste on merkkijono Line1.Temperature.
Nimiavaruus on pohjimmiltaan URI. Määrityksen mukaan nimiavaruuksien URI:t esitetään palveluissa numeroina, ja numero vastaa sijaintia palvelimen NamespaceArray-taulukossa. Indeksi 0 on OPC UA:n nimiavaruus http://opcfoundation.org/UA/7.
Siksi indeksin numeroa ei kannata kirjoittaa koodiin, vaan indeksi haetaan URI:sta. Yllä oleva koodi hakee URI:sta arvon 2 kutsulla session.NamespaceUris.GetIndex(LineNamespace) ja muodostaa NodeIdit sen avulla.
flowchart TB
accTitle: NodeIdin muodostaminen nimiavaruuden URI:sta
accDescr: Kaavio, joka näyttää, että asiakas hakee nimiavaruuden URI:n palvelimen NamespaceArray-taulukosta saadakseen indeksin ja yhdistää indeksin tunnisteeseen muodostaakseen NodeIdin.
U["Nimiavaruuden URI"] --> A["Palvelimen NamespaceArray"]
A --> I["Indeksi (tässä esimerkissä 2)"]
I --> N["NodeId ns=2;s=Line1.Temperature"]
K["Tunniste Line1.Temperature"] --> N
Kuva 4: Nimiavaruuden indeksi haetaan URI:sta ja yhdistetään tunnisteeseen NodeIdiksi.
Luku ja kirjoitus palauttavat arvon mukana tilan ja aikaleimat
Muuttujien arvoja luetaan ja kirjoitetaan Read- ja Write-palveluilla8. Luku palauttaa muutakin kuin arvon. Se palauttaa DataValue-nimisen rakenteen, jossa on arvo, tilakoodi, lähteen aikaleima ja palvelimen aikaleima9.
| Kohta | Merkitys |
|---|---|
| Arvo | Muuttujan arvo. Kun tilakoodi ilmaisee virheen, arvo jätetään huomiotta ja palvelin asettaa sen null-arvoksi |
| Tilakoodi (StatusCode) | Pystyikö palvelin hankkimaan ja toimittamaan arvon |
| SourceTimestamp | Aika, jonka tiedon lähde liitti arvoon |
| ServerTimestamp | Aika, jolloin palvelin vastaanotti arvon tai sai tietää sen olevan oikea |
Tilakoodin kaksi ylintä bittiä ilmaisevat tilan Good (onnistui), Uncertain (onnistui osittain, joihinkin käyttötarkoituksiin ei välttämättä kelpaa) tai Bad (epäonnistui)10. Tulosteen Good [0x00000000] on Good.
Kun luin olematonta Line1.Pressure-solmua, arvon sijaan palautui BadNodeIdUnknown [0x80340000]. Tämän kirjaston ReadValueAsync heittää poikkeuksen, kun tila on Bad4. Jos arvoja tallentava järjestelmä tallentaa jokaisen arvon rinnalle myös tilakoodin, Bad-tilan aikana tallennetut arvot voidaan myöhemmin erottaa muista.
flowchart TB
accTitle: Mitä DataValue sisältää
accDescr: Kaavio, joka näyttää, että luvun tai ilmoituksen palauttamassa DataValue-rakenteessa on neljä asiaa, arvo, tilakoodi, lähteen aikaleima ja palvelimen aikaleima, ja että arvo jätetään huomiotta, kun tilakoodi on Bad.
D["DataValue"] --> V["Arvo"]
D --> S["Tilakoodi"]
D --> TS["SourceTimestamp (lähteen aika)"]
D --> TV["ServerTimestamp (palvelimen aika)"]
S -->|"Jos Bad"| X["Arvo jätetään huomiotta"]
Kuva 5: Luvun tuloksessa on arvon lisäksi tilakoodi ja kaksi aikaleimaa.
Kirjoituksessa kirjoitin Setpoint-muuttujaan arvon 32.5, ja tuloksen tilakoodiksi palautui Good. Palvelin päättää, mitkä muuttujat ovat kirjoitettavissa. Tässä simuloidussa palvelimessa vain Setpoint on kirjoitettavissa. Se, saako laitteen asetusarvoja muuttaa ulkopuolelta, kuuluu laitteen turvallisuussuunnitteluun, joten tämä artikkeli ei käsittele sitä.
Ilmoitukset muutoksista: tilaukset ja MonitoredItemit
Arvojen muutosten seuraamiseksi asiakas voi toistaa Read-palvelua tasaisin väliajoin. Sen lisäksi OPC UA:ssa on mekanismi, joka jättää arvojen valvonnan palvelimelle ja pyytää sitä ilmoittamaan muutoksista. Tämä mekanismi on tilaukset (Subscription) ja MonitoredItemit.
MonitoredItem on yksi valvottava kohde, ja sillä on näytteenottoväli. Näytteenottoväli on nopein tahti, jolla palvelin ottaa lähteestä näytteitä arvoista, ja määritys kuvaa sitä “parhaan yrityksen” (best effort) jaksoksi11. Kun näyte täyttää suodattimen ehdot, syntyy ilmoitus. Jos suodatinta ei ole määritetty, ilmoitus lähetetään, kun arvo tai tila muuttuu12.
Ilmoitukset menevät ensin MonitoredItemin jonoon. Etukäteen päätetään, hylätäänkö jonon täyttyessä vanhin vai uusin ilmoitus, ja jos jonon koko on 2 tai enemmän, tilakoodiin asetetaan hylkäämisestä kertova Overflow-bitti13.
Tilaus kokoaa useita MonitoredItemejä ja lähettää jokaisella julkaisuvälillä asiakkaalle ne ilmoitukset, joita ei vielä ole lähetetty. Kun jaksoja kuluu ilman lähetettäviä ilmoituksia, se lähettää keep-alive-viestin osoittaakseen, että tilaus on yhä voimassa14.
flowchart TB
accTitle: Miten tilaukset ja MonitoredItemit toimivat
accDescr: Kaavio, joka näyttää, että MonitoredItem ottaa näytteitä lähteen arvosta näytteenottovälin mukaan ja lisää suodattimen läpäisseet ilmoitukset jonoon ja että tilaus lähettää ne yhdessä asiakkaalle julkaisuvälin mukaan ja lähettää keep-alive-viestin, kun ilmoituksia ei ole.
S["Lähde (laitteen arvo)"] --> M["MonitoredItem"]
M -->|"Näytteenottoväli"| F["Suodatin (oletus: arvon tai tilan muutos)"]
F --> Q["Jono (Overflow, kun täynnä)"]
Q --> SUB["Tilaus"]
SUB -->|"Julkaisuväli"| C["Asiakas"]
SUB -.->|"Jos ilmoituksia ei ole"| K["Keep-alive"]
Kuva 6: MonitoredItem ottaa näytteet ja jonottaa ne, ja tilaus lähettää ilmoitukset asiakkaalle yhdessä.
Yllä oleva koodi tilaa Temperature- ja PartCount-muuttujat 500 millisekunnin näytteenottovälillä ja jonon koolla 515. Tulosteessa lämpötila saapuu noin 0,5 sekunnin ja tuotemäärä noin 2 sekunnin välein. Kaksi ensimmäistä ilmoitusta olivat arvot, jotka muuttujilla oli tilauksen alkaessa. Tuotemäärän 13:40:50.801 on aika, jolloin sen arvo muuttui ennen tilauksen alkua. Koska ilmoituksissa näytetään lähteen aikaleima, niissä näkyy arvon muuttumisen aika eikä ilmoituksen vastaanottamisen aika.
Toistuvan luvun ja tilauksen valinta
Toistuvassa luvussa asiakas voi itse päättää välin, ja mekanismi on yksinkertainen. Toisaalta pyyntö ja vastaus kulkevat edestakaisin joka kerta, vaikka arvo ei olisi muuttunut, ja väliä lyhyemmät muutokset jäävät huomaamatta. Tilauksessa palvelin ottaa näytteet ja lähettää vain muutokset, joten liikenne ei juuri kasva harvoin muuttuvillakaan arvoilla. Tilauksessakaan näytteenottoväliä lyhyemmistä muutoksista ei kuitenkaan välttämättä ilmoiteta. Määritys sallii pyydettyä nopeamman näytteenoton mutta ei vaadi sitä11.
flowchart TB
accTitle: Toistuvan luvun ja tilauksen ero
accDescr: Kaavio, joka näyttää, että toistuvassa luvussa asiakas päättää välin ja lähettää pyynnön joka kerta, että tilauksessa palvelin ottaa näytteet näytteenottovälin mukaan ja lähettää vain muutokset ja että kumpikin voi ohittaa väliä lyhyemmät muutokset.
A["Arvojen muutosten seuranta"] --> R["Toistuva luku"]
A --> S["Tilaus"]
R --> R1["Asiakas päättää välin ja pyytää joka kerta"]
S --> S1["Palvelin ottaa näytteet ja lähettää vain muutokset"]
R1 --> X["Väliä lyhyemmät muutokset voivat jäädä huomaamatta"]
S1 --> X
Kuva 7: Kummallakin tavalla väliä lyhyemmät muutokset voivat jäädä huomaamatta.
Yhteyksien salliminen varmenteilla
OPC UA -yhteydessä viestien suojauksen taso valitaan MessageSecurityMode-asetuksella. Arvot ovat None, joka ei suojaa, Sign, joka vain allekirjoittaa, ja SignAndEncrypt, joka allekirjoittaa ja salaa16. Allekirjoituksessa ja salauksessa käytettävien algoritmien yhdistelmä määräytyy suojauskäytännön (security policy) mukaan, ja tässä artikkelissa käytetään Basic256Sha256:ta.
Allekirjoituksessa ja salauksessa käytetään sovelluskohtaista varmennetta. Asiakas ja palvelin tarkistavat toistensa varmenteet ja hylkäävät yhteydet osapuolilta, joihin ne eivät luota. OPC Foundationin .NET-kirjastolla tehty palvelin ei oletuksena tarjoa salaamatonta None-käytäntöä4.
Ensimmäinen yhteys pysähtyi virheeseen BadCertificateUntrusted
Ensimmäisellä ajokerralla asiakas ei luottanut palvelimen varmenteeseen, joten yhteys hylättiin. Tässä osa tulosteesta.
fail: Opc.Ua.CertificateValidationCore[91]
Certificate [Subject=CN=DemoPlcServer, CN=urn:komurasoft:demo-plc, Thumbprint=4E236DDA629FE2AB32D185BF681609FD6C525363, NotBefore=2026-11-01, NotAfter=2027-11-01, KeyAlgorithm=1.2.840.113549.1.1.1] validation failed with suppressible errors but was rejected. Reason=Id: BadCertificateUntrusted
...
OPC UA エラー BadCertificateUntrusted [0x801A0000]: [801A0000] (BadCertificateUntrusted) 'Could not verify security on OpenSecureChannel response.'
Tämä kirjasto tallentaa hylätyt varmenteet rejected-säilöön. Kun ylläpitäjä siirtää varmenteen sieltä trusted-säilöön, kirjasto alkaa luottaa kyseiseen osapuoleen17. Tällä kertaa siirsin palvelimen varmenteen kansiosta pki/rejected/certs kansioon pki/trusted/certs, ajoin ohjelman uudelleen ja sain yhteyden. Ennen siirtoa tarkista palvelimen ylläpitäjän kanssa tunnistearvo (thumbprint), joka on myös osa tiedostonimeä4.
flowchart TB
accTitle: Varmenteeseen luottamisen vaiheet
accDescr: Kaavio, joka näyttää, että ensimmäisessä yhteydessä asiakas hylkää palvelimen varmenteen ja tallentaa sen rejected-säilöön ja että kun tunnistearvo on tarkistettu ja varmenne siirretty trusted-säilöön, seuraava yhteys luottaa siihen ja onnistuu.
A["Ensimmäinen yhteys"] --> B["BadCertificateUntrusted"]
B --> C["Varmenne tallennetaan rejected-säilöön"]
C --> D["Tunnistearvo tarkistetaan palvelimen ylläpitäjän kanssa"]
D --> E["Varmenne siirretään trusted-säilöön"]
E --> F["Seuraava yhteys luottaa siihen ja onnistuu"]
Kuva 8: Kun hylätty varmenne on tarkistettu ja siirretty trusted-säilöön, asiakas luottaa kyseiseen osapuoleen.
On myös asetus AutoAcceptUntrustedCertificates, joka hyväksyy epäluotetut varmenteet automaattisesti. Sen oletusarvo on false, ja kirjaston dokumentaation mukaan se on hyödyllinen kehitysympäristöissä mutta sitä ei pidä käyttää tuotannossa17.
Lokin NotAfter=2027-11-01 on simuloidun palvelimen varmenteen viimeinen voimassaolopäivä. Se on asyncuan funktiolla luotu itse allekirjoitettu varmenne, jonka voimassaolo päättyi vuoden kuluttua luontipäivästä. Myös laitteiden varmenteet vanhenevat, joten osana käyttöä kannattaa päättää, miten ne vaihdetaan ennen vanhenemista ja miten vastapuoli saadaan luottamaan uusiin. Windowsin varmennesäilön käsittelyä käsitellään artikkelissa “The Windows Certificate Store in Practice”.
Käyttäjän todentaminen
Varmenteilla tarkistetaan sovellukset. Sen lisäksi istuntoa avattaessa välitetään käyttäjän tunnistava tunnus (token). Määritys määrittelee neljä lajia: anonyymi, käyttäjänimi ja salasana, X.509-varmenne sekä ulkoisesti myönnetty tunnus18. Tämän artikkelin asiakas yhdisti anonyymisti. Se, mitä tunnuksia palvelin hyväksyy, sisältyy palvelimen päätepisteen tietoihin19.
Missä tiedonkeruu kentällä menee pieleen
Seuraavaksi luettelen ongelmia, joita laitteiden tietoja keräävissä järjestelmissä usein syntyy, tämän kokeen ja määrityksen perusteella.
Palvelimen pysähdyksen aikaiset arvot eivät saavu
Tilauksen aikana pysäytin palvelimen ja käynnistin sen uudelleen noin 15 sekunnin kuluttua. Tämän kirjaston ManagedSession yhdistää automaattisesti uudelleen, kun yhteys katkeaa20. Palvelimen ollessa pysähdyksissä asiakas yritti toistuvasti yhdistää uudelleen.
warn: Opc.Ua.ChannelManager[6]
Reconnect failed. Endpoint=opc.tcp://localhost:4840/demo/, Attempt=3, Outcome=transient-failure, Status=BadNotConnected, ErrorMessage=Could not connect to the remote endpoint.
Kun palvelin palasi, myös ilmoitukset palasivat. Tässä osa tilauksen tulosteesta.
13:41:13.364 Line1.Temperature 25.61 Good [0x00000000]
13:41:13.865 Line1.Temperature 25.12 Good [0x00000000]
13:41:34.285 Line1.Temperature 26.55 Good [0x00000000]
13:41:33.784 Line1.PartCount 2 Good [0x00000000]
13:41:34.786 Line1.Temperature 26.16 Good [0x00000000]
Ajalta 13.41.13–13.41.34 ei saapunut yhtään arvoa. Tuotemäärä palasi arvosta 78 arvoon 2. Tämä johtuu siitä, että simuloitu palvelin aloitti laskemisen uudelleenkäynnistyksen jälkeen alusta nollasta.
Tässä esimerkissä itse palvelin oli pysähdyksissä, joten sen ajan arvoja ei ole tallessa missään. Uudelleenyhdistämisen mekanismi palauttaa yhteyden, mutta se ei täydennä jälkikäteen arvoja ajalta, jolloin palvelin oli poissa käytöstä.
Tilanne on eri, kun vain tietoliikenne katkeaa ja palvelin jatkaa toimintaansa. Määrityksessä on Republish-palvelu, jolla palvelin lähettää perille saapumattomat ilmoitusviestit uudelleen uudelleenlähetysjonostaan21. Ilmoituksia kertyy myös MonitoredItemin jonoon, mutta jonon koon ylittävä osa hylätään13. En kokeillut tätä tapausta tässä kokeessa. Kummassakin tapauksessa yhteyden katkeamisen ja uudelleenyhdistämisen ajat kannattaa tallentaa, jotta tiedetään, minä aikana arvoja ei saapunut. Sarjaliikennelaitteiden uudelleenyhdistämistä ja lokien suunnittelua käsitellään myös artikkelissa “Serial Communication App Pitfalls”.
flowchart TB
accTitle: Tallentaminen, kun palvelin pysähtyy
accDescr: Kaavio, joka näyttää, että kun palvelin pysähtyy tilauksen aikana, asiakas yrittää toistuvasti yhdistää uudelleen ja ilmoitukset palaavat palvelimen palatessa, mutta pysähdyksen aikaiset arvot eivät saavu, joten katkeamisen ja uudelleenyhdistämisen ajat tallennetaan.
A["Tilaus voimassa"] --> B["Palvelin pysähtyy"]
B --> C["Asiakas yrittää toistuvasti yhdistää uudelleen"]
C --> D["Palvelin palaa ja ilmoitukset jatkuvat"]
B -.-> E["Pysähdyksen aikaiset arvot eivät saavu"]
E -.-> F["Katkeamisen ja uudelleenyhdistämisen ajat tallennetaan"]
Kuva 9: Uudelleenyhdistäminen palauttaa yhteyden, mutta palvelimen pysähdyksen aikaiset arvot eivät saavu.
Kumpi aikaleima tallennetaan
Määrityksen mukaan SourceTimestamp on aika, jonka tiedon lähde liitti arvoon, ja sen pitäisi ilmaista, milloin arvo muuttui. ServerTimestamp on aika, jolloin palvelin vastaanotti arvon tai sai tietää sen olevan oikea9. Tämän artikkelin simuloitu palvelin tuottaa arvot itse, joten molemmat ajat olivat samat.
Jos haluat tietää, milloin arvo muuttui laitteessa, käytä SourceTimestampia. Aika merkitään kuitenkin lähteen kellon mukaan, joten jos laitteen tai palvelimen kello on väärässä, myös tallenne on väärässä. Jos aiot verrata kerättyjä tietoja muihin tallenteisiin, tallenna niiden rinnalle myös vastaanottavan tietokoneen aika, jotta poikkeama voidaan tarkistaa myöhemmin. Windows-puolen ajan synkronointia käsitellään artikkelissa “Windows Time Synchronization (w32time) and Business Systems”.
Älä käsittele arvoja, joiden tila ei ole Good, pelkkinä lukuina
Kun tilakoodi on Bad, arvo on jätettävä huomiotta9. Kun se on Uncertain, arvo ei välttämättä kelpaa joihinkin käyttötarkoituksiin10. Ennen kuin arvot viedään kaavioihin tai koosteisiin, lajittele ne tilakoodin mukaan ja päätä, miten muut kuin Good-arvot käsitellään. Täyttyneen jonon Overflow-bitti asetetaan myös tilakoodiin13. Laitteen tilan näyttämistä näytöllä käsitellään artikkelissa “Best Practices for Checking and Displaying External Device State”.
Avaa portti palomuurissa
IANA:n rekisterissä oleva OPC UA:n portti on 4840/TCP3. Kaikki palvelimet eivät kuitenkaan käytä tätä numeroa. OPC Foundationin .NET-esimerkit käyttävät muun muassa porttia 625414. Tarkista porttinumero laitteen päätepisteen URL-osoitteesta ja salli yhteydet kyseiseen porttiin. Jos palvelin toimii Windowsissa, salli yhteys sen Windowsin palomuurissa, ja jos välissä on verkkolaitteita, salli se niissä. Saapuvan liikenteen sääntöjen luomista käsitellään artikkelissa “The Windows Firewall and Business Applications”.
flowchart TB
accTitle: Missä tiedonkeruu menee pieleen
accDescr: Kaavio, joka näyttää kohdat, joissa laitetietojen keruu menee pieleen, jaettuna tallenteiden sisältöön (palvelimen pysähdyksen aikaiset arvot eivät saavu, kumpi aikaleima tallennetaan, muiden kuin Good-arvojen käsittely) ja yhteyden valmisteluun (palomuurin portit, varmenteiden vanheneminen).
A["Missä tiedonkeruu menee pieleen"] --> R["Tallenteiden sisältö"]
A --> N["Yhteyden valmistelu"]
R --> B["Pysähdyksen aikaiset arvot eivät saavu"]
B ~~~ C["Kumpi aikaleima"]
C ~~~ D["Muiden kuin Good-arvojen käsittely"]
N --> E["Palomuurin portit"]
E ~~~ F["Varmenteiden vanheneminen"]
Kuva 10: Vaikka yhteys toimisi, tarkista tallenteiden aukot, ajat, tilat, portit ja varmenteet.
OPC UA:n, Modbus/TCP:n ja valmistajakohtaisten protokollien valinta
PLC:iden ja laitteiden kanssa viestimiseen on OPC UA:n lisäksi Modbus/TCP sekä PLC-valmistajien tarjoamia protokollia.
Modbus-määritys käsittelee tietoja neljänä taulukkona: Discrete Input (vain luettava yksittäinen bitti), Coil (luettava ja kirjoitettava yksittäinen bitti), Input Register (vain luettava 16-bittinen sana) ja Holding Register (luettava ja kirjoitettava 16-bittinen sana)22. IANA:n rekisterissä 502/TCP on rekisteröity Modbusin sovellusprotokollaksi (mbap)3.
Näihin taulukoihin tallennetaan bittejä ja 16-bittisiä sanoja, joten se, mikä arvo on missäkin osoitteessa ja missä muodossa, on tarkistettava laitteen dokumentaatiosta ja kirjoitettava asiakkaan puolelle. OPC UA:ssa, kuten edellä nähtiin, palvelin julkaisee nimettyjä muuttujia osoiteavaruudessaan, ja asiakas voi löytää ne Browse-palvelulla. Arvojen mukana tulee tilakoodi ja aikaleimat, ja yhteydet sallitaan varmenteilla.
Käytettävä tapa määräytyy usein sen mukaan, mitä laite tarjoaa. Jos laitteessa on OPC UA -palvelin, käytä sitä. Jos siinä on vain Modbus/TCP, laadi osoitekartta ja lue sen mukaan. Jos tarjolla on vain valmistajan protokolla tai SDK, noudata sen dokumentaatiota. USB-laitteiden tiedonsiirtotavan valintaa käsitellään artikkelissa “How to Work with USB Devices from a Windows App”.
flowchart TB
accTitle: Laitteen kanssa viestimisen tavan valinta
accDescr: Kaavio, joka näyttää, että jos laitteessa on OPC UA -palvelin, muuttujat selataan ja kerätään OPC UA:lla, jos siinä on vain Modbus/TCP, osoitteet ja muodot tarkistetaan dokumentaatiosta ja rekisterit luetaan, ja jos siinä on vain valmistajan protokolla, noudatetaan sen dokumentaatiota.
A["Laitteen tarjoama tiedonsiirto"] --> B{"Mitä on saatavilla?"}
B -->|"OPC UA -palvelin"| C["Muuttujat selataan ja kerätään"]
B -->|"Vain Modbus/TCP"| D["Osoitteet ja muodot tarkistetaan dokumentaatiosta"]
B -->|"Vain valmistajan protokolla"| E["Noudatetaan valmistajan dokumentaatiota ja SDK:ta"]
D --> F["Rekisterit luetaan ja muunnetaan arvoiksi"]
Kuva 11: Keruutapa määräytyy usein sen mukaan, mitä laite tarjoaa.
Aiheeseen liittyviä artikkeleita
- Dropped Frames with GigE Vision and USB3 Vision Cameras
- Serial Communication App Pitfalls
- Best Practices for Checking and Displaying External Device State
- How to Work with USB Devices from a Windows App
- The Windows Firewall and Business Applications
- The Windows Certificate Store in Practice
- Windows Time Synchronization (w32time) and Business Systems
Lähteet
-
OPC Foundation, Classic. OPC Classicin perustuminen COM/DCOMiin, DA-, A&E- ja HDA-määritykset, OPC UA:n julkaisu vuonna 2008 ja uudelleensuunnittelun syyt. ↩ ↩2
-
IEC, IEC TR 62541-1:2020 OPC Unified Architecture - Part 1: Overview and concepts. IEC 62541 -sarjan osa 1, joka käsittelee OPC UA:n käsitteitä ja yleiskuvaa (korvattu sittemmin uudemmalla painoksella). ↩
-
IANA, Service Name and Transport Protocol Port Number Registry.
opcua-tcp-rekisteröinti porttiin 4840/TCP jambap-rekisteröinti porttiin 502/TCP. ↩ ↩2 ↩3 -
OPC Foundation, UA-.NETStandard 2.0.1: Getting started. 2.0-sarjan asiakkaan kirjoittaminen,
ReadValueAsyncheittää poikkeuksen Bad-tilassa, rejected- ja trusted-säilöt, palvelimet eivät oletuksena tarjoaNone-käytäntöä ja esimerkeissä käytetyt porttinumerot. ↩ ↩2 ↩3 ↩4 ↩5 -
FreeOpcUa, asyncua (PyPI). Simuloidussa laitepalvelimessa käytetty Pythonin OPC UA -kirjasto. ↩
-
OPC Foundation, OPC 10000-4 v1.05, 5.9.2 Browse. Palvelu, joka seuraa solmun viittauksia. ↩
-
OPC Foundation, OPC 10000-3 v1.05, 8.2.2 NamespaceIndex. Nimiavaruuksien URI:t esitetään palveluissa numeroina, ja numero vastaa sijaintia NamespaceArray-taulukossa. ↩
-
OPC Foundation, OPC 10000-4 v1.05, 5.11 Attribute Service Set. Read- ja Write-palvelut. ↩
-
OPC Foundation, OPC 10000-4 v1.05, 7.11 DataValue. Arvon, tilakoodin, SourceTimestampin ja ServerTimestampin määritelmät. ↩ ↩2 ↩3
-
OPC Foundation, OPC 10000-4 v1.05, 7.38.1 StatusCode General. Kahden ylimmän bitin ilmaisemat tilat Good, Uncertain ja Bad. ↩ ↩2
-
OPC Foundation, OPC 10000-4 v1.05, 5.13.1.2 Sampling interval. Näytteenottoväli on parhaan yrityksen jakso. ↩ ↩2
-
OPC Foundation, OPC 10000-4 v1.05, 7.22.2 DataChangeFilter. Ilman suodatinta ilmoitus lähetetään arvon tai tilan muuttuessa. ↩
-
OPC Foundation, OPC 10000-4 v1.05, 5.13.1.5 Queue parameters. Jonon koko, hylkäämiskäytäntö ja Overflow-bitti. ↩ ↩2 ↩3
-
OPC Foundation, OPC 10000-4 v1.05, 5.14.1.1 Subscription model. Julkaisuväli ja keep-alive-viestit. ↩
-
OPC Foundation, UA-.NETStandard 2.0.1: Subscriptions and Monitored Items Service Set.
SubscribeDataChangesAsyncsekäMonitoredItemOptions-asetusten näytteenottoväli ja jonon koko. ↩ -
OPC Foundation, OPC 10000-4 v1.05, 7.20 MessageSecurityMode. Arvojen None, Sign ja SignAndEncrypt merkitykset. ↩
-
OPC Foundation, UA-.NETStandard 2.0.1: Certificates. Käytäntö siirtää varmenteet rejected-säilöstä trusted-säilöön sekä se, ettei
AutoAcceptUntrustedCertificates-asetusta käytetä tuotannossa. ↩ ↩2 -
OPC Foundation, OPC 10000-4 v1.05, 7.40 UserIdentityToken parameters. Neljä lajia: anonyymi, käyttäjänimi, X.509 ja myönnetty tunnus. ↩
-
OPC Foundation, OPC 10000-4 v1.05, 7.14 EndpointDescription. Luettelo käyttäjätunnuksista, jotka päätepiste hyväksyy (userIdentityTokens). ↩
-
OPC Foundation, UA-.NETStandard 2.0.1: Sessions, Reconnection, and Subscription Engines.
ManagedSession-luokassa on sisäänrakennettu uudelleenyhdistämisen mekanismi. ↩ -
OPC Foundation, OPC 10000-4 v1.05, 5.14.6.1 Republish. Palvelu, jolla tilauksen uudelleenlähetysjono lähettää ilmoitusviestit uudelleen. ↩
-
Modbus-IDA, MODBUS Application Protocol Specification V1.1b (Chicagon yliopiston palvelimella oleva kopio). Luvun 4.3 tietomalli (Discrete Input, Coil, Input Register, Holding Register). ↩
Aiheeseen liittyvät artikkelit
Uusimmat artikkelit, joilla on samoja tunnisteita. Niiden avulla aihetta voi syventää läheisten teemojen kautta.
Mitä pysähtyy, kun ”käytön mukaan laskutettava yhteys” otetaan käyttöön? ── Vaikutus Windows Updateen, OneDriveen ja Store-sovelluksiin
Kun Windowsin käytön mukaan laskutettava yhteys on käytössä, Windows Update lataa vain tärkeät päivitykset ja OneDrive keskeyttää synkron...
Voiko Windows.old-kansion ja ”väliaikaiset tiedostot” poistaa? – Milloin käyttää tallennusseurantaa ja milloin Levyn uudelleenjärjestämistä
Windows.old-kansion ja väliaikaisten tiedostojen poistamisesta päätetään sen mukaan, katoaako jotain, mitä ei saa takaisin. Artikkeli käy...
Mikä muuttuu Windowsin virtatilassa? ── Paras suorituskyky, Tasapainotettu ja Paras energiatehokkuus vertailussa ja näin valitset
Mitä Windows 11:n virtatilat Paras suorituskyky, Tasapainotettu ja Paras energiatehokkuus muuttavat: taustalla vaihtuvat suoritinasetukse...
Mikä on Windowsin pelitila? ── Mikä muuttuu, kun otat sen käyttöön, ja vaikuttaako se muuhunkin kuin peleihin
Windowsin pelitila estää Windows Updatea asentamasta ohjaimia ja lähettämästä uudelleenkäynnistysilmoituksia pelin ollessa käynnissä ja p...
Mitä Tehtävienhallinnan ”Erillinen GPU-muisti” ja ”Jaettu GPU-muisti” tarkoittavat? ── Miksi luvut eroavat integroidulla GPU:lla niin paljon ja mitä tapahtuu, kun muisti ei riitä
Mitä Tehtävienhallinnan erillinen ja jaettu GPU-muisti tarkoittavat, miksi integroidulla GPU:lla erillistä muistia on vähän ja jaettua pa...
Aiheeseen liittyvät aihesivut
Tähän teemaan läheisesti liittyviä aihesivuja. Artikkelista voi siirtyä aiheeseen liittyviin palveluihin ja muihin artikkeleihin.
Windowsin tekniset aiheet
Aloitussivu, jolle on koottu Windows-kehitykseen, vianetsintään ja olemassa olevien ratkaisujen hyödyntämiseen liittyvät tekniset aiheet.
Palvelut, joihin tämä aihe liittyy
Tämä artikkeli liittyy seuraaviin palvelusivuihin. Voitte tutustua lähimpään niistä.
Windows-sovelluskehitys
Laitteista tietoja keräävän Windows-sovelluksen rakentaminen tilausasetuksineen, uudelleenyhdistämisineen sekä aikaleimojen ja tilojen tallennuksineen voidaan hoitaa Windows-sovelluskehityksenä.
Tekninen konsultointi ja suunnittelukatselmointi
Jos haluat päättää, kerätäänkö tiedot OPC UA:lla vai käytetäänkö Modbus/TCP:tä tai valmistajan omaa protokollaa, ja miten varmenteita hallitaan, asia voidaan käsitellä teknisenä konsultointina ja suunnittelun katselmointina.
Usein kysytyt kysymykset
Tämän artikkelin aiheesta konsultoinnin yhteydessä usein esitettyjä kysymyksiä.
- Mitä eroa on OPC UA:lla ja OPC Classicilla (OPC DA)?
- OPC Classic on joukko määrityksiä, jotka välittävät tietoja Windowsin COM/DCOM-tekniikalla. Vuonna 2008 julkaistu OPC UA ei ole sidottu tiettyyn käyttöjärjestelmään, ja se kokoaa Classicin toiminnot yhteen. OPC UA -asiakkaat toimivat myös muualla kuin Windowsissa, eikä DCOM-asetuksia tarvita.
- Riittääkö, että arvot luetaan OPC UA:lla tasaisin väliajoin?
- Jos arvoja on vähän ja väli on pitkä, lukeminen riittää. Jos haluat seurata arvojen muutoksia, voit käyttää tilausta: palvelin hoitaa näytteenoton ja ilmoittaa muutoksista. Kummassakin tapauksessa tallenna arvon mukana palaava tilakoodi ja aikaleimat.
- Miksi yhdistäminen päättyy virheeseen BadCertificateUntrusted?
- Koska asiakas ei vielä luota palvelimen varmenteeseen. OPC Foundationin .NET-kirjasto tallentaa hylätyt varmenteet rejected-säilöön. Tarkista varmenteen tunnistearvo (thumbprint) palvelimen ylläpitäjän kanssa ja siirrä varmenne sitten trusted-säilöön. Käytä varmenteet automaattisesti hyväksyviä asetuksia vain kehitysympäristöissä.
- Mitä porttinumeroa OPC UA käyttää?
- IANA:n rekisterissä 4840/TCP on rekisteröity nimellä opcua-tcp. Todelliset palvelimet käyttävät kuitenkin joskus muuta porttia, joten tarkista se laitteen asetuksista. Jos palvelin toimii Windowsissa, liikenne kyseiseen porttiin on sallittava Windowsin palomuurissa, ja jos välissä on verkkolaitteita, myös niissä.
Kirjoittajan profiili
Artikkelin kirjoittajan profiilisivu.
Go Komura
KomuraSoft LLC:n edustaja
Keskittyy Windows-ohjelmistokehitykseen, tekniseen konsultointiin ja vianetsintään. Erityisosaamista ovat hankkeet, joissa on olemassa olevia ratkaisuja, sekä vikojen tutkiminen silloin, kun syy ei ole helposti havaittavissa.