Projekt

Smart eHZ LAN – RS232 Interface

 

  

 

EHZ001 BKE-Datenschnittstelle,  Leitungslänge 450mm                 Image result for hager ehz

 

GLAB Logo

 

 

 

 

Version 1.1


 

Dokument Version:

 

Version:                     1.1

Datum:                       2018.09.11

Autor:                         GINTHER, Andreas

Sprache:                    Deutsch

 

 

GLAB:

 

GLAB Logo GLAB steht für Ginther Laboratories.

Es handelt sich hier weder um eine Firma noch ein gemeldetes Gewerbe.

Es werden damit lediglich Konstruktionen, Architekturen und Erfindungen bezeichnet welche im privaten eigennützigen Gebrauch entstehen.

 

Nur mit Zustimmung von Ginther Andreas dürfen mit GLAB gekennzeichnete Software, Hardware und Konzepte verwendet werden.

Es wir keinerlei Haftung oder Gewährleistung für dessen übernommen.

 


Inhaltsverzeichnis

 

 

 

1        Projekt 3

1.1         eHZ Zähler 3

1.2         eHZ optische Schnittstelle. 4

1.3         RS232 – LAN Modul 7

1.4         UART – RS232 Treiber 8

1.5         PoE – LAN Modul 9

1.6         PoE – LAN Transformer 10

1.7         TTL – LED Treiber 11

1.8         12 / 5V Versorgungsspannung. 12

1.9         GLAB eHZ LAN - RS232 Interface. 13

1.10      Schaltung Hauptplatine. 15

1.11      Platine. 16

1.12      Frontplatte. 18

1.13      Komplett Modul 20

1.14      Einbau im Hager Zählerschrank. 22

1.15      RS232 – LAN Modul Konfiguration. 24

1.16      SML Protokoll 25

1.17      SML Frame. 29

1.18      CRC16 Prüfsummenberechnung. 30

1.19      PowerShell Programm.. 30

1.20      Registry Datenbank. 34

1.21      PRTG Sensoren.. 35

1.22      PRTG Grafen.. 36

1.23      PRTG Map. 37

1.24      PRTG E-Mail-Benachrichtigung. 38

 


 

1     Projekt

 

·         Auslesen des Hager eHZ EHZ363 (elektronischer Haushalt Zähler) mit der optischen Schnittstelle

·         Übertragen der Daten von der seriellen RS232 Schnittstelle über Ethernet LAN TCP

·         Parsen vom SML Frame over TCP und CRC16 Prüfsumme mit Windows PowerShell

·         Stromversorgen des Modules mit PoE, keine extra Stromversorgungen für Sensorik

·         Langzeitaufzeichnung und Map mit PRTG

·         Kein aufbringen eines Optokopfes auf der Vorderseite des Zählers

·         Hutschienenkomponenten geeignet für Zählerschrank Einbau

 

1.1    eHZ Zähler

 

Ein elektronischer Haushaltszähler ist unverzichtbarer Baustein eines intelligenten Stromnetzes (Smart Grid). Durch die Möglichkeit einer elektronischen Auslesung kann der Zähler in ein Smart Metering integriert werden. Hierzu ist ein Standardprotokoll definiert worden SML mit dem die Zählerdaten per RS232 ausgelesen werden können.

Smart Message Language (SML) ist ein Kommunikationsprotokoll für Stromzähler, das unter anderem für Messdatenaustausch, aber auch für Firmware Upgrades entwickelt wurde.

 

·         Hager eHZ Zähler EHZ363WA Einrichtung Wirkenergie Drehstromzähler

·         Genauigkeitsklasse: Klasse A oder Klasse B (MID, DIN EN 50470)

·         Nennspannung Un: 4-Leiter: 3 x 230 / 400V

·         Anlaufstrom Ist: 0,02A

·         Mindeststrom Imin: 0,1A

·         Impuls-LED 10.000 Imp./ kWh

·         Leistungsaufnahme: je Spannungspfad: 4-Leiter: < 0,4 VA, < 0,2 W

·         Datenschnittstelle: frontseitige und rückseitige optische Datenschnittstelle nach DIN EN 62056-21

 


1.2    eHZ optische Schnittstelle

 

Zur Erfassung der Zähler Daten wird die Hager EHZ001K BKE-Datenschnittstelle an der Rückseite des installierten Energiezählers verwendet. DIN EN 62056-21

 

EHZ001 BKE-Datenschnittstelle,  Leitungslänge 450mm

 

EDL-Schnittstelle:

·         Gateway oder andere Geräte über RS232.

·         Übertragungsrate elektrisch und optisch

·         9600 Bit/s, 8 Databits, 1 Stopbits, Parity no, Flowcontrol no

·         Übertragungsart halbduplex.

·         Wellenlänge 850 nm.

 

Der RJ12 Stecker ist wie folgt belegt:

 

 

Es sind 12V Versorgungsspannung notwendig welche vom PoE Modul bereitgestellt werden.

IDC <= 8 mA

I peak <= 10 mA

 


 

An der Rückseite des Zählers sind 2 Löcher für die optische Übertragung der Zählerdaten.

Die Schnittstelle ist galvanisch getrennt und greift nicht ins Messsystem ein.

 

 


 

Ist die Schnittstelle im Zählerplatz eingeclipst und der Zähler eingerastet stimmt die Position und die Daten können optisch übertragen werden.

 

 


 

1.3    RS232 – LAN Modul

 

Es wird ein Modul eingesetzt (USR-TCP232-ED2) von www.usriot.com welches 2 UART Ports über eine Ethernet LAN Schnittstelle übertragen kann. Über die Web Oberfläche können die Ports konfiguriert werden.

Danach können über TCP die Daten der RS232 empfangen werden.

Auf dem Modul arbeitet ein Cortex-M4 Prozessor mit 512Kb Speicher.

 

 


 

1.4    UART – RS232 Treiber

 

Das USR-TCP232-ED2 Modul stellt allerdings nur UART Ports bereit. Diese müssen an einen RS232 Treiber angeschlossen werden damit diese dann mit der Hager EHZ001K BKE-Datenschnittstelle kommunizieren können. Dabei wird RxD und TxD vom RS232 Treiber und der EHZ001K Schnittstelle gekreuzt.

 

Es wird ein ADM3202ANZ PDIP-16 eingesetzt:

 

     Image result for adm3202anz

 

 

Bei einem RS232 Signal wird ein logisches 1 mit einer negativen Spannung und ein logisches 0 mit einer positiven Spannung signalisiert. Die Spannungen können von -3V bis -25V und +3V bis +25V liegen.

Hingegen ein TTL Signal ist von 0V bis +5V definiert. Dies wird vom ADM3202 mit den Pump Kondensatoren umgesetzt.

 

http://www.sparkfun.com/tutorial/RS232vsTTL-BiteSize/ttl-timing.PNG


 

1.5    PoE – LAN Modul

 

Das gesamte Modul mit all seinen Komponenten soll per PoE mit Strom versorgt werden.

Hierzu wird ein PoE Modul eingesetzt.

 

 

Das PoE Modul kann per Daten und Storm Modus A oder per Separate Strom Modus B versorgt werden.

Es wird der Modus A gewählt, weil die meisten PoE Switche über die Daten Leitungen die 48V Versorgungsspannung lagern.

 


 

1.6    PoE – LAN Transformer

 

Damit der PoE Modus A verwendet werden kann müssen von den Datenleitungen die Versorgungsspannung abgegriffen werden dazu ist ein LAN Transformer notwendig.

 

Es wird ein MagJack 10/100Base-TX PoE Übertrager SI-52008-F eingesetzt.

Diese platzsparende Variante hat den Übertrager mit CT Abgriffen im RJ45 Buchsen Gehäuse integriert.

Image result for si-52008-f

 

Das PoE Modul wird somit an P8 und P9 angeschlossen.

Das PoE Modul liefert dann 12VDC mit einer Leistung von max. 12.95W.


 

1.7    TTL – LED Treiber

 

Für LAN und RS232 werden LEDs in der Frontplatte angebracht um Link, Daten, Sende und Empfangsstatus zu signalisieren. Dazu ist ein TTL LED Treiber notwendig.

 

Es wird ein SN74LS07N PDIP-14 eingesetzt:

 

    Main Product

 

 

2 Paar wird für die LAN LEDs verwendet, Link und Data

2 Paar wird für die RS232 Port1 LEDs verwendet, RxD und TxD

2 Paar wird für die RS232 Port2 LEDs verwendet, RxD und TxD

 


 

1.8    12 / 5V Versorgungsspannung

 

Das PoE Modul liefert 12VDC welche für die Versorgung der Hager EHZ001K BKE-Datenschnittstelle benötigt werden.

Ein DC/DC Wandler transformiert dann auf 5VDC herunter als Versorgungspannung für das RS232 – LAN Modul sowie die restlichen TTL Bausteine und Signalisierung LEDs.

 

Es wird ein TracoPower TSR 1-2450 DC/DC-Wandler eingesetzt:

·         Eingangsspannung 6,5 – 36VDC

·         Ausgangsspannung 5VDC

·         Strombelastbarkeit 1A

·         96% Effektiv, keine Wärmeentwicklung

·         Schaltfrequenz 400-500 kHz PWM

 

Main Product

 

Das ganze Modul mit einer optischen Schnittstelle verbraucht im Betrieb 1,2W.

 

 


 

1.9    GLAB eHZ LAN - RS232 Interface

 

Es werden 2 Platinen gefertigt. Auf der Haupt Platine sind die Komponenten:

·         RS232 – LAN Modul

·         UART – RS232 Treiber

·         PoE – LAN Modul

·         PoE – LAN Transformer

·         LED Treiber

·         12 / 5 V Versorgungsspannung

welche dann mit einem Flachbandkabel mit der Frontplatten Platine verbunden werden.

 

 

Die Einzelkomponenten GLAB eHZ LAN – RS232 Interface for Hager EHZ001K:

 

 

Die ungefähren Kosten der Einzelkomponenten wie folgt:

 

Gehäuse                                   11 €

Platine                                      41 €

Frontplatte                                18 €

PoE Modul                                27 €

RS232 LAN Modul                    48 €

RJ45 Transformer                      5,2 €

RJ12 Stecker                            1,5 €

Kondensatoren                          5 €

Widerstände                              1 €

ICs                                           5 €

Taster                                       1,2 €

Stiftleisten                                5 €

LEDs                                        1,4 €

DC/DC Wandler                         5,7 €

Flachbandkabel                         4 €

Schrauben                                0,5

 

Summe                                    180.- Euro

 


 

1.10 Schaltung Hauptplatine

 


 

1.11 Platine

 

Auf der Hauptplatine befinden sich alle Komponenten.

Auf der Tochterplatine nur die LED Anzeige.

Es wird doppelseitig bestückt auch mit SMD Bauteilen.

 

 


 

Das PoE Modul wird zwecks Wärmeableitung verlötet.

Das RS232 – LAN Modul wird aufgesteckt.

Dabei werden die Pins der UART3 welche nicht benutzt wird abgeschnitten um Platz für das PoE Modul zu bekommen.

 

 


 

1.12 Frontplatte

 

Die Frontplatte ist aus Aluminium natureloxiert 2mm stark und in Farbe bedruckt.

 

 


 

Die Frontplatte wird auf die Tochterplatine verschraubt (Senkkopfschraube M2,5) und klemmt sich an den Gehäusenoppen fest. Die Frontplatte ist über die Messing Distanzhalter auf Masse gelegt.

 

Da die optische Schnittstelle für galvanische Trennung sorgt ist das ganze Modul auf Ethernet Schirm Masse gelegt.

 

 


 

1.13 Komplett Modul

 

Oben ist der Ethernet RJ45 Anschluss.

Link und Data vom RJ45 Transformer Stecker sind zusätzlich mit weitern LEDs auf die Frontplatte geführt.

Angesteuert werden sie vom LED Treiber um das UART Modul nicht zu belasten.

Unten sind die 2 RJ12 Anschlüsse mit der 12V Versorgung zum direkten Anschluss des EHZ001K.

 


 

Die Frontplatte wird auf die Tochterplatine verschraubt und hält sich an den Gehäusenoppen.

Links und rechts die 2 RS232 RJ12 Anschlüsse.

 

Es werden low power LEDs verwendet und mit nur ca. 3mA betrieben.

 

 


 

1.14 Einbau im Hager Zählerschrank

 

Im Nachzähler Feld ist der ideale Platz für das Modul.

Das Kabel von der EHZ001K BKE-Datenschnittstelle ist lange genug um es direkt einzustecken.

Ein Ethernet Kabel mit Winkelstecker wird mit einem Netzwerkswitch verbunden.

 

 


 

Es können bis zu 2 Zähler angeschlossen werden.

 

Video: GLAB LAN - RS232 Interface for Hager EHZ001K in Betrieb

 

 


 

1.15 RS232 – LAN Modul Konfiguration

 

Mit einer Weboberfläche kann das Modul konfiguriert werden.

IP Adresse und TTL Port Konfiguration.

 

Gemäß dem Hager EHZ001 sind diese RS232 Parameter einzustellen:

9600 Bit/s, 8 Databits, 1 Stopbits, Parity no, Flowcontrol no

 

Das PowerShell Programm welches dann die Daten abfragt verbindet sich an Port 231 TCP.

Es wird zum empfangen der Seriellen Daten kein virtueller COMP Port installiert was auch möglich wäre, sondern direkt auf TCP IP Ebene die Daten empfangen und weiterverarbeitet.

 

 

 

Mit dem Reset Taster in der Gehäuse Frontpatte kann das Modul neu gestartet werden.

Mit dem Defaults Taster kann das Modul auf Werkseinstellungen zurückgesetzt werden.

 


 

1.16 SML Protokoll

 

Die Datenschnittstellen des Zählers sind Infrarot-Kommunikationsschnittstellen nach DIN EN62056-21.

Alle Telegramme sind mit SML-Transportprotokoll (Version 1) kodiert.

Der Zähler sendet alle 1s - 4s einen Datensatz, welcher neben den Inhalten des/der Energieregister(s) weitere Informationen enthält.

 

Datentelegramm nach FNN Lastenheft EDL:

 

OBIS-Kennzahl Inhalt:

81 81 C7 82 03 FF  Hersteller-Identifikation

01 00 00 00 09 FF  Geräteeinzelidentifikation

01 00 01 08 00 FF  Zählerstand Totalregister

01 00 01 08 01 FF  Zählerstand Tarif 1

01 00 01 08 02 FF  Zählerstand Tarif 2

01 00 10 07 00 FF  aktuelle Wirkleistung

01 00 01 11 00 FF  (nur rückseitige Schnittstelle) letzter signierter Total-Zählerstand

81 81 C7 82 05 FF  öffentlicher Schlüssel

 

Zusatztelegramm (optional):

OBIS-Kennzahl Inhalt:

01 00 24 07 00 FF:  Wirkleistung L1

01 00 38 07 00 FF:  Wirkleistung L2

01 00 4C 07 00 FF:  Wirkleistung L3

01 00 60 32 00 02:  Aktuelle Chiptemperatur

01 00 60 32 00 03:  Minimale Chiptemperatur

01 00 60 32 00 04:  Maximale Chiptemperatur

01 00 60 32 00 05:  Gemittelte Chiptemperatur

01 00 60 32 03 03:  Spannungsminimum

01 00 60 32 03 04:  Spannungsmaximum

01 00 1F 07 00 FF:  Strom L1

01 00 20 07 00 FF:  Spannung L1

01 00 33 07 00 FF:  Strom L2

01 00 34 07 00 FF:  Spannung L2

01 00 47 07 00 FF:  Strom L3

01 00 48 07 00 FF:  Spannung L3

 


 

OSI Modell:

 

Das SML Protokoll ist eine Folge von Bytes in der alle Zählerdaten, Kennzeichnungen und Prüfsummen enthalten sind.

 

Im OSI Modell ist SML auf Layer 6 und 7 und kann somit über alle möglichen Medien wie Seriell, LAN, HTTP, E-Mail übertragen werden.

 

 

    Quelle

   

 


 

Protokoll Beschreibung:

 

Diese Daten werden in jeder SML Message vom SMART METER gesendet

 

 

 

Wirkenergie Total Bezug OBIS Kennzahl = 1-0:1.8.0*255 -> OBIS Kennzahl in HEX: 01 00 01 08 00 FF

 

 

    Quelle

   

 


 

SML Telegramm:

 

 

 


1.17 SML Frame

 

Ein SML Frame ist ca. 1456 Zeichen lang also 728 Hex Zahlen. Es hat eine dynamische Länge.

 

1B1B1B1B01010101760900000000002443F762016200726301017601010900000000000C16AA0B090

1484147100005D5CB010163571E00760900000000002443F8620162007263070177010B0901484147

100005D5CB070100620AFFFF726201642497CBF17E77078181C78203FF01010101044841470177070

100000009FF010101010B0901484147100005D5CB0177070100010800FF628001621E52FF540190AC

0177070100010801FF0101621E52FF5401699C0177070100010802FF0101621E52FF5327100177070

100100700FF0101621B52005300060177070100240700FF0101621B52FF5300280177070100170700

FF0101621D52FF53FF0A01770701001F0700FF0101622152FE53000A0177070100200700FF0101622

352FE535BCC0177070100510704FF0101620852005301170177070100380700FF0101621B52FF5300

1B01770701002B0700FF0101621D52FF5300000177070100330700FF0101622152FE5300020177070

100340700FF0101622352FE535BBB017707010051070FFF01016208520053000001770701004C0700

FF0101621B52FF53000001770701003F0700FF0101621D52FF5300000177070100470700FF0101622

152FE5300010177070100480700FF0101622352FE535BCB017707010051071AFF01016208520053FF

FF0177070100510701FF0101620852005300770177070100510702FF0101620852005300F10177070

100603200020101620952FF5301680177078181C78205FF010101018302B27B87BD5340E19BD1F473

2999EE198BBD036E51158767713E5D38831E9D43BD9C07763E6F683F05A2033AA6C14C5DF70177070

1006032030301016223520062D701770701006032030401016223520062EE01770701006032000301

0162095200520E017707010060320004010162095200522A017707010060320005010162095200522

6010101638A7600760900000000002443F96201620072630201710163775C001B1B1B1B1A0068FA

 

·         Start eines Frames

·         Ende eines Frames

·         Liefer Wirkenergie

·         Aktuelle Leistung

·         Aktuelle Chip Temperatur

·         CRC16 Prüfsumme

 

 

Dynamische Länge:

 

Dadurch dass das SML Frame eine dynamische Länge hat ist das Parsen doch etwas aufwendiger.

 

Wenn z.B.: eine Leistung von L3 über ca. 3200W gemessen wird dann werden die Nutzdaten Bytes um 2 Hex Zeichen länger. Darauf muss der Parser dynamisch reagieren.

 

737F = 29567 /10 = 2956,7 Watt

7849 = 30793 /10 = 3079,3 Watt

0082CB = 33483 /10 = 3348,3 Watt

 

 


 

1.18 CRC16 Prüfsummenberechnung

 

Am Ende des SML Frames befinden sich mit 4 Hex Zeichen eine CCCIT-CRC16 Prüfsumme.

Diese kommt nach den 2 Füllbytes.

1B1B1B1B1A0068FA

 

Die Berechnung erfolgt mit diesen Parametern:

Profil CRC16 X 25

Polynomial 0x1021

Initial Value: 0xFFFF

Final Xor Value: 0xFFFF

Input reflected yes

Result reflected yes

 

Eine PowerShell Funktion Get-CRC16 führt dies direkt im Skript durch

 

1.19 PowerShell Programm

 

Auf dem Hausautomation Server läuft ein PowerShell Programm welches den TCP Datenstrom liest und dann die SML Frame auswertet und die Daten in die Windows Registry schreibt.

Von dort können dann andere Programme die Daten wieder abgreifen und weiterverwenden.

Wo wird PRTG eingesetzt mit mehreren PowerShell Sensoren zum Zeichnen von Grafen und darstellen in der PRTG Map.

 

Das PowerShell Programm:

 

# Hager eHZ RS232 Reader and SML 1.0 Frame Parser DIN EN 62056-21 (Windows PowerShell)

# written by Ginther Andreas (GLAB) 2018 http://www.the-ginthers.net/

# Version 1.1.2 (2018.09.08)

 

# 3rd party code

# -----------------------------------

# Function Convert-ByteArrayToHexString (https://cyber-defense.sans.org/blog/2010/02/11/powershell-byte-array-hex-convert)

# Function calculate CRC16 checksum (https://gist.github.com/gravejester/ef27e6d82f3d051ac57e995b784512d8#file-crc16-ps1)

# -----------------------------------

 

# Database Instance = ElectricityMeter1

# TCP Port          = 231

# BKE-Datenschnittstelle (OKK) EHZ001K

 

# -----------------------------------

 

 

# Var

$SMLLog = "C:\ProgramData\GLAB\SMLFrame.log"

If(!(Test-Path "C:\ProgramData\GLAB")) {New-Item -ItemType Directory -Force -Path "C:\ProgramData\GLAB"}

 

# Function Convert-ByteArrayToHexString (https://cyber-defense.sans.org/blog/2010/02/11/powershell-byte-array-hex-convert)

Function Convert-ByteArrayToHexString {

    [CmdletBinding()] Param (

    [Parameter(Mandatory = $True, ValueFromPipeline = $True)] [System.Byte[]] $ByteArray,

    [Parameter()] [Int] $Width = 10,

    [Parameter()] [String] $Delimiter = ",0x",

    [Parameter()] [String] $Prepend = "",

    [Parameter()] [Switch] $AddQuotes )

    if ($Width -lt 1) { $Width = 1 }

    if ($ByteArray.Length -eq 0) { Return }

    $FirstDelimiter = $Delimiter -Replace "^[\,\:\t]",""

    $From = 0

    $To = $Width - 1

    Do {

        $String = [System.BitConverter]::ToString($ByteArray[$From..$To])

        $String = $FirstDelimiter + ($String -replace "\-",$Delimiter)

        if ($AddQuotes) { $String = '"' + $String + '"' }

        if ($Prepend -ne "") { $String = $Prepend + $String }

        $String

        $From += $Width

        $To += $Width

    } While ($From -lt $ByteArray.Length)

}

 

# Function Convert-HexStringToByteArray (https://cyber-defense.sans.org/blog/2010/02/11/powershell-byte-array-hex-convert)

function Convert-HexStringToByteArray {

    [CmdletBinding()]

    Param ( [Parameter(Mandatory = $True, ValueFromPipeline = $True)] [String] $String )

    $String = $String.ToLower() -replace '[^a-f0-9\\,x\-\:]',"

    $String = $String -replace '0x|\x|\-|,',':'

    $String = $String -replace '^:+|:+$|x|\',"

    if ($String.Length -eq 0) { ,@() ; return }

    if ($String.Length -eq 1)

        { ,@([System.Convert]::ToByte($String,16)) }

    elseif (($String.Length % 2 -eq 0) -and ($String.IndexOf(":") -eq -1))

        { ,@($String -split '([a-f0-9]{2})' | foreach-object { if ($_) {[System.Convert]::ToByte($_,16)}}) }

    elseif ($String.IndexOf(":") -ne -1)

        { ,@($String -split ':+' | foreach-object {[System.Convert]::ToByte($_,16)}) }

    else

        { ,@() }

}

 

# Function calculate CRC16 checksum (https://gist.github.com/gravejester/ef27e6d82f3d051ac57e995b784512d8#file-crc16-ps1)

function Invoke-Reflection16 {

    param (

        [uint16]$val

    )

    [uint16]$resVal = 0

    for ($i = 0; $i -lt 16; $i++) {

        if (($val -band (1 -shl $i)) -ne 0) {

            $resVal = $resVal -bor ([uint16](1 -shl (15 - $i)))

        }

    }

    Write-Output $resVal

}

function Invoke-Reflection8 {

    param (

        [byte]$val

    )

    [byte]$resByte = 0

    for ($i = 0; $i -lt 8; $i++) {

        if (($val -band (1 -shl $i)) -ne 0) {

            $resByte = $resByte -bor ([byte](1 -shl (7 - $i)))

        }

    }

    Write-Output $resByte

}

function New-CRC16Table {

    [uint16]$polynomial = 0x1021

    $crcTable = New-Object 'System.Uint16[]' 256

    for ($divident = 0; $divident -lt 256; $divident++) {

        [uint16]$currentByte = ([uint16]$divident -shl 8)

        for ([byte]$bit = 0; $bit -lt 8; $bit++) {

            if (($currentByte -band 0x8000) -ne 0) {

                $currentByte = $currentByte -shl 1

                $currentByte = $currentByte -bxor $polynomial

            }

            else {

                $currentByte = $currentByte -shl 1

            }

        }

        $crcTable[$divident] = $currentByte

    }

    Write-Output $crcTable

}

function Get-CRC16 {

    [CmdletBinding()]

    param (

        [Parameter(Position = 0, ValueFromPipeline = $true)]

        [ValidateNotNullOrEmpty()]

        [byte[]]$InputObject

    )

    [uint16]$crc = 0xFFFF

    Write-Verbose "Initial Value: $crc"

    $crc16Table = New-CRC16Table

    foreach ($b in $InputObject) {

        $currentByte = Invoke-Reflection8 -val $b

        Write-Verbose "Byte: $($b) - Reflected byte: $($currentByte)"

        [byte]$position = [byte](($crc -shr 8) -bxor $currentByte)

        $crc = [uint16](($crc -shl 8) -bxor ([uint16]$crc16Table[$position]))

        Write-Verbose "CRC: $crc"

    }

    $reflectedOutput = Invoke-Reflection16 -val $crc

    Write-Verbose "Final CRC: $($crc) - Reflected CRC: $($reflectedOutput)"

    Write-Output ($reflectedOutput -bxor 0xFFFF)

}

#$CRC16InputData = [System.Text.Encoding]::ASCII.GetBytes("PowerShell")

#Get-CRC16 $CRC16InputData

 

# Get 1500 bytes from the eHZ interface for max 3 times in case of corrupt data

$getdataloop = 1

Do {

    # Record 1500 single ASCII bytes from the port (more then 2 SML Frames)

        Write-Output ('Run ' + $getdataloop)

    $getdataloop++

   

    # Create an empty array

    #$TCPDataByteArray = @()

    $TCPDataByteArray = $null

    $TCPDataByteArray = New-Object System.Collections.ArrayList # high performance array

    # TCP Socket           

    $TCPPort = '231'

    $TCPHost = '192.168.33.151'

    $TCPBuffer = New-Object System.Byte[] 16384

    $TCPEncoding = New-object -TypeName System.Text.AsciiEncoding

    $TCPConnection = New-Object System.Net.Sockets.TcpClient($TCPHost, $TCPPort)

    $TCPStream = $TCPConnection.GetStream()

        Write-Output 'TCP opened'

    $TCPloop = 0

    Do {

        $TCPDataRAW = $TCPStream.ReadByte()    # get ASCII codes

        #$TCPDataByteArray += $PortDataRAW

        $TCPDataByteArray.Add($TCPDataRAW) > $null

        #    $TCPDataByteArray.count

        #    Write-Output $TCPDataRAW

        $TCPloop++

    }

    Until ($TCPloop -gt 1500)

    $TCPConnection.Close()

        Write-Output 'TCP closed'

   

    # Convert the byte array to a hex array

    $PortDataHex = Convert-ByteArrayToHexString -ByteArray $TCPDataByteArray -Width '' -Delimiter ' '

        #Write-Output $PortDataHex

 

    # Convert the hex array to a hex string and cutout the SML Frame and the CRC16

    [string]$PortDataHexLine = ''

    $PortDataHexLineString = ''

    $PortDataHexLineStringNS = ''

    $SMLFrameStartIndex = ''

    $SMLFrameEndIndex = ''

    $SMLFrameRAW = ''

    $SMLFrame = ''

    $SMLFrameWoCRC = ''

    $SMLFrameCRCB1 = ''

    $SMLFrameCRCB2 = ''

    $SMLFrameCRCB12 = ''

    $SMLFrameEnd = ''

    $SMLFrameChars = ''

    [string]$PortDataHexLine = $PortDataHex -join ''

    $PortDataHexLineString = [string]$PortDataHexLine

    $PortDataHexLineStringNS = $PortDataHexLineString.Replace(' ','')

    $SMLFrameStartIndex = $PortDataHexLineStringNS.IndexOf('1B1B1B1B01010101')

    $SMLFrameRAW = $PortDataHexLineStringNS.Substring($SMLFrameStartIndex,1470)

    $SMLFrameEndIndex = $SMLFrameRAW.IndexOf('1B1B1B1B1A00')

    $SMLFrame = $SMLFrameRAW.Substring(0,$SMLFrameEndIndex+16)

    $SMLFrameWoCRC = $SMLFrame.Substring(0,$SMLFrame.Length - 4)

    $SMLFrameCRCB12 = $SMLFrame.Substring($SMLFrame.Length - 4)

    $SMLFrameCRCB1 = $SMLFrameCRCB12.Substring(0,$SMLFrameCRCB12.Length - 2)

    $SMLFrameCRCB2 = $SMLFrame.Substring($SMLFrame.Length - 2)

    $SMLFrameChars = $SMLFrame.Length # should be 1456 characters = 728 bytes

    Write-Output $SMLFrame

    Write-Output ('SML RAW Frame chars = '+$PortDataHexLineStringNS.Length)

    Write-Output ('SML Frame chars = '+$SMLFrameChars)

 

    # Verify the char length and the CRC of the SML Frame

    if ($SMLFrameChars -ge '1446'){

        Write-Output ('SML Frame ok !')

        Write-Output ('SML Frame chars = '+$SMLFrameChars)

        #$getdataloop++

        #$getdataloop++

        $SMLFrameGood = $true

        # -----------------------------------------------------------------------

        # Verify the CRC16 sum of the SML Frame

        # Convert Hex to Byte

        $SMLFrameByteArray = Convert-HexStringToByteArray $SMLFrameWoCRC

        # Calculate CRC16

        $SMLCRC16 = Get-CRC16 $SMLFrameByteArray

        $SMLCRC16Hex = [System.Convert]::ToString($SMLCRC16, 16)

        # Add leading zero

        $SMLCRC16HexString = $SMLCRC16Hex.PadLeft(4,'0')

        if ($SMLFrameCRCB2+$SMLFrameCRCB1 -like $SMLCRC16HexString){

            Write-Output ('SML CRC ok !')

            Write-Output ('SML CRC = '+$SMLFrameCRCB2+$SMLFrameCRCB1)

            Write-Output ('CALC CRC = '+$SMLCRC16Hex)

            # Write SML Frame to debug

            New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentSMLFrame" -PropertyType String -Value $SMLFrame -Force

            New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentSMLCalcCRC" -PropertyType String -Value $SMLCRC16HexString -Force

            $SMLCRCGood = $true

            $getdataloop++

            $getdataloop++

        }

        else{

            Write-Output ('SML CRC wrong !')

            Write-Output ('SML CRC chars = '+$SMLFrameCRCB2+$SMLFrameCRCB1)

            Write-Output ('CALC CRC chars = '+$SMLCRC16Hex)

            # Count bad SML CRC

            $BadSMLCRCCounter = Get-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name 'BadSMLCRCCounter'

            New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "BadSMLCRCCounter" -PropertyType QWord -Value ($BadSMLCRCCounter.BadSMLCRCCounter +1) -Force

            New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "BadSMLCRCTime" -PropertyType String -Value (get-date) -Force

            # Write SML Frame to debug

            New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentSMLFrameBadCRC" -PropertyType String -Value $SMLFrame -Force

            New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentSMLCalcBadCRC" -PropertyType String -Value $SMLCRC16HexString -Force

            $SMLCRCGood = $false

        }

        # -----------------------------------------------------------------------

    }

    else{

        Write-Output ('SML Frame corrupt !')

        Write-Output ('SML Frame = '+$SMLFrameChars)

        Write-Output ('get once again data')

        # Count bad SML Frames

        $BadSMLFramesCounter = Get-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name 'BadSMLFramesCounter'

        New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "BadSMLFramesCounter" -PropertyType QWord -Value ($BadSMLFramesCounter.BadSMLFramesCounter +1) -Force

        New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "BadSMLFramesTime" -PropertyType String -Value (get-date) -Force

        $SMLFrameGood = $false

    }

}

Until ($getdataloop -gt 3)

 

# Final verify the char length of the SML Frame

if ($SMLFrameGood -and $SMLCRCGood){

    Write-Output ('Writing to registry data base')

   

    # Extract OBIS data and write values to cache database

    # Voltage L1

    $SMLOBISUL1 = $SMLFrame.IndexOf('0100200700FF')

        $SMLCutStart = $SMLFrame.Substring($SMLOBISUL1,64)

        $SMLCutEnd = $SMLCutStart.IndexOf('017707')

        $SMLUL1HEX = $SMLCutStart.Substring(26,$SMLCutEnd-26)

    $SMLUL1DEC = [Convert]::ToInt64($SMLUL1HEX,16)/100

    Write-Output ('Voltage L1 = '+$SMLUL1HEX)

    Write-Output ('Voltage L1 = '+$SMLUL1DEC)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentVoltageL1" -PropertyType String -Value $SMLUL1DEC -Force

    # Voltage L2

    $SMLOBISUL2 = $SMLFrame.IndexOf('0100340700FF')

        $SMLCutStart = $SMLFrame.Substring($SMLOBISUL2,64)

        $SMLCutEnd = $SMLCutStart.IndexOf('017707')

        $SMLUL2HEX = $SMLCutStart.Substring(26,$SMLCutEnd-26)

    $SMLUL2DEC = [Convert]::ToInt64($SMLUL2HEX,16)/100

    Write-Output ('Voltage L2 = '+$SMLUL2HEX)

    Write-Output ('Voltage L2 = '+$SMLUL2DEC)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentVoltageL2" -PropertyType String -Value $SMLUL2DEC -Force

    # Voltage L3

    $SMLOBISUL3 = $SMLFrame.IndexOf('0100480700FF')

        $SMLCutStart = $SMLFrame.Substring($SMLOBISUL3,64)

        $SMLCutEnd = $SMLCutStart.IndexOf('017707')

        $SMLUL3HEX = $SMLCutStart.Substring(26,$SMLCutEnd-26)

    $SMLUL3DEC = [Convert]::ToInt64($SMLUL3HEX,16)/100

    Write-Output ('Voltage L3 = '+$SMLUL3HEX)

    Write-Output ('Voltage L3 = '+$SMLUL3DEC)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentVoltageL3" -PropertyType String -Value $SMLUL3DEC -Force

    # Current L1

    $SMLOBISCL1 = $SMLFrame.IndexOf('01001F0700FF')

        $SMLCutStart = $SMLFrame.Substring($SMLOBISCL1,64)

        $SMLCutEnd = $SMLCutStart.IndexOf('017707')

        $SMLCL1HEX = $SMLCutStart.Substring(26,$SMLCutEnd-26)

    $SMLCL1DEC = [Convert]::ToInt64($SMLCL1HEX,16)/100

    Write-Output ('Current L1 = '+$SMLCL1HEX)

    Write-Output ('Current L1 = '+$SMLCL1DEC)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentCurrentL1" -PropertyType String -Value $SMLCL1DEC -Force

    # Current L2

    $SMLOBISCL2 = $SMLFrame.IndexOf('0100330700FF')

        $SMLCutStart = $SMLFrame.Substring($SMLOBISCL2,64)

        $SMLCutEnd = $SMLCutStart.IndexOf('017707')

        $SMLCL2HEX = $SMLCutStart.Substring(26,$SMLCutEnd-26)

    $SMLCL2DEC = [Convert]::ToInt64($SMLCL2HEX,16)/100

    Write-Output ('Current L2 = '+$SMLCL2HEX)

    Write-Output ('Current L2 = '+$SMLCL2DEC)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentCurrentL2" -PropertyType String -Value $SMLCL2DEC -Force

    # Current L3

    $SMLOBISCL3 = $SMLFrame.IndexOf('0100470700FF')

        $SMLCutStart = $SMLFrame.Substring($SMLOBISCL3,64)

        $SMLCutEnd = $SMLCutStart.IndexOf('017707')

        $SMLCL3HEX = $SMLCutStart.Substring(26,$SMLCutEnd-26)

    $SMLCL3DEC = [Convert]::ToInt64($SMLCL3HEX,16)/100

    Write-Output ('Current L3 = '+$SMLCL3HEX)

    Write-Output ('Current L3 = '+$SMLCL3DEC)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentCurrentL3" -PropertyType String -Value $SMLCL3DEC -Force

     # Power L1

    $SMLOBISPL1 = $SMLFrame.IndexOf('0100240700FF')

        $SMLCutStart = $SMLFrame.Substring($SMLOBISPL1,64)

        $SMLCutEnd = $SMLCutStart.IndexOf('017707')

        $SMLPL1HEX = $SMLCutStart.Substring(26,$SMLCutEnd-26)

    $SMLPL1DEC = [Convert]::ToInt64($SMLPL1HEX,16)/10

    Write-Output ('Power L1 = '+$SMLPL1HEX)

    Write-Output ('Power L1 = '+$SMLPL1DEC)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentPowerL1" -PropertyType String -Value $SMLPL1DEC -Force

    # Power L2

    $SMLOBISPL2 = $SMLFrame.IndexOf('0100380700FF')

        $SMLCutStart = $SMLFrame.Substring($SMLOBISPL2,64)

        $SMLCutEnd = $SMLCutStart.IndexOf('017707')

        $SMLPL2HEX = $SMLCutStart.Substring(26,$SMLCutEnd-26)

    $SMLPL2HEX = $SMLFrame.Substring($SMLOBISPL2+26,4)

    $SMLPL2DEC = [Convert]::ToInt64($SMLPL2HEX,16)/10

    Write-Output ('Power L2 = '+$SMLPL2HEX)

    Write-Output ('Power L2 = '+$SMLPL2DEC)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentPowerL2" -PropertyType String -Value $SMLPL2DEC -Force

    # Power L3

    $SMLOBISPL3 = $SMLFrame.IndexOf('01004C0700FF')

        $SMLCutStart = $SMLFrame.Substring($SMLOBISPL3,64)

        $SMLCutEnd = $SMLCutStart.IndexOf('017707')

        $SMLPL3HEX = $SMLCutStart.Substring(26,$SMLCutEnd-26)

    $SMLPL3DEC = [Convert]::ToInt64($SMLPL3HEX,16)/10

    Write-Output ('Power L3 = '+$SMLPL3HEX)

    Write-Output ('Power L3 = '+$SMLPL3DEC)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentPowerL3" -PropertyType String -Value $SMLPL3DEC -Force

    # Power

    $SMLOBISP = $SMLFrame.IndexOf('0100100700FF')

        $SMLCutStart = $SMLFrame.Substring($SMLOBISP,64)

        $SMLCutEnd = $SMLCutStart.IndexOf('017707')

        $SMLPHEX = $SMLCutStart.Substring(26,$SMLCutEnd-26)

    $SMLPDEC = [Convert]::ToInt64($SMLPHEX,16)

    Write-Output ('Power = '+$SMLPHEX)

    Write-Output ('Power = '+$SMLPDEC)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentPower" -PropertyType String -Value $SMLPDEC -Force

    # Energy

    $SMLOBISEA = $SMLFrame.IndexOf('0100010800FF')

        $SMLCutStart = $SMLFrame.Substring($SMLOBISEA,64)

        $SMLCutEnd = $SMLCutStart.IndexOf('017707')

        $SMLEAHEX = $SMLCutStart.Substring(28,$SMLCutEnd-28)

    $SMLEADEC = [Convert]::ToInt64($SMLEAHEX,16)/10000

    Write-Output ('Energy = '+$SMLEAHEX)

    Write-Output ('Energy = '+$SMLEADEC)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentEnergyAll" -PropertyType String -Value $SMLEADEC -Force

    # Energy Tarif 1

    $SMLOBISE1 = $SMLFrame.IndexOf('0100010801FF')

        $SMLCutStart = $SMLFrame.Substring($SMLOBISE1,64)

        $SMLCutEnd = $SMLCutStart.IndexOf('017707')

        $SMLE1HEX = $SMLCutStart.Substring(26,$SMLCutEnd-26)

    $SMLE1DEC = [Convert]::ToInt64($SMLE1HEX,16)/10000

    Write-Output ('Energy = '+$SMLE1HEX)

    Write-Output ('Energy = '+$SMLE1DEC)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentEnergy1" -PropertyType String -Value $SMLE1DEC -Force

    # Power Reactive L1

    $SMLOBISPRL1 = $SMLFrame.IndexOf('0100170700FF')

        $SMLCutStart = $SMLFrame.Substring($SMLOBISPRL1,64)

        $SMLCutEnd = $SMLCutStart.IndexOf('017707')

        $SMLPRL1HEX = $SMLCutStart.Substring(26,$SMLCutEnd-26)

    $SMLPRL1DEC = [Convert]::ToInt64($SMLPRL1HEX,16)/10000

    Write-Output ('Power L1 = '+$SMLPRL1HEX)

    Write-Output ('Power L1 = '+$SMLPRL1DEC)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentPowerReactiveL1" -PropertyType String -Value $SMLPRL1DEC -Force

    # Power ReactiveL2

    $SMLOBISPRL2 = $SMLFrame.IndexOf('01002B0700FF')

        $SMLCutStart = $SMLFrame.Substring($SMLOBISPRL2,64)

        $SMLCutEnd = $SMLCutStart.IndexOf('017707')

        $SMLPRL2HEX = $SMLCutStart.Substring(26,$SMLCutEnd-26)

    $SMLPRL2DEC = [Convert]::ToInt64($SMLPRL2HEX,16)/10000

    Write-Output ('Power L2 = '+$SMLPRL2HEX)

    Write-Output ('Power L2 = '+$SMLPRL2DEC)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentPowerReactiveL2" -PropertyType String -Value $SMLPRL2DEC -Force

    # Power ReactiveL3

    $SMLOBISPRL3 = $SMLFrame.IndexOf('01003F0700FF')

        $SMLCutStart = $SMLFrame.Substring($SMLOBISPRL3,64)

        $SMLCutEnd = $SMLCutStart.IndexOf('017707')

        $SMLPRL3HEX = $SMLCutStart.Substring(26,$SMLCutEnd-26)

    $SMLPRL3DEC = [Convert]::ToInt64($SMLPRL3HEX,16)/10000

    Write-Output ('Power L3 = '+$SMLPRL3HEX)

    Write-Output ('Power L3 = '+$SMLPRL3DEC)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentPowerReactiveL3" -PropertyType String -Value $SMLPRL3DEC -Force

    # Temperature Current

    $SMLOBISE = $SMLFrame.IndexOf('010060320002')

        $SMLCutStart = $SMLFrame.Substring($SMLOBISE,64)

        $SMLCutEnd = $SMLCutStart.IndexOf('017707')

        $SMLTCHEX = $SMLCutStart.Substring(26,$SMLCutEnd-26)

    $SMLTCDEC = [Convert]::ToInt64($SMLTCHEX,16)/10

    Write-Output ('Temperature Current = '+$SMLTCHEX)

    Write-Output ('Temperature Current = '+$SMLTCDEC)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentTemperature" -PropertyType String -Value $SMLTCDEC -Force

 

    # Calculate values

    # Power Apparent L1

    $CALCSL1 = $SMLUL1DEC * $SMLCL1DEC

    Write-Output ('Power apparent L1 = '+$CALCSL1)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentPowerApparentL1" -PropertyType String -Value $CALCSL1 -Force

    # Power Apparent L2

    $CALCSL2 = $SMLUL2DEC * $SMLCL2DEC

    Write-Output ('Power apparent L2 = '+$CALCSL2)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentPowerApparentL2" -PropertyType String -Value $CALCSL2 -Force

    # Power Apparent L3

    $CALCSL3 = $SMLUL3DEC * $SMLCL3DEC

    Write-Output ('Power apparent L3 = '+$CALCSL3)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentPowerApparentL3" -PropertyType String -Value $CALCSL3 -Force

    # Power Apparent

    $CALCS = $CALCSL1 + $CALCSL2 + $CALCSL3

    # Cos Pi

    $CALCCOSPI = $SMLPDEC / $CALCS

    Write-Output ('Cosinus Pi = '+$CALCCOSPI)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentPowerFactor" -PropertyType String -Value $CALCCOSPI -Force

 

    # Count good SML Frames

    $GoodSMLFramesCounter = Get-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name 'GoodSMLFramesCounter'

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "GoodSMLFramesCounter" -PropertyType QWord -Value ($GoodSMLFramesCounter.GoodSMLFramesCounter +1) -Force

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "GoodSMLFramesTime" -PropertyType String -Value (get-date) -Force

}

else{

    Write-Output ('SML Frame corrupt !')

    Write-Output ('SML Frame chars = '+$SMLFrameChars)

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "BadSMLFramesLoop" -PropertyType QWord -Value ($getdataloop -2) -Force

    $date = Get-Date

    $date, $PortDataByteArray.count, $PortDataHexLineStringNS, $SMLFrameStartIndex, $SMLFrameRAW, $SMLFrameEndIndex, $SMLFrame, $SMLFrameChars, ($SMLFrameCRCB2+$SMLFrameCRCB1), $SMLCRC16Hex, $getdataloop | Add-Content -Path $SMLLog

    # Write zero values to cache database

    #New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentVoltageL1" -PropertyType String -Value '0' -Force

    #New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentVoltageL2" -PropertyType String -Value '0' -Force

    #New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentVoltageL3" -PropertyType String -Value '0' -Force

    #New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentCurrentL1" -PropertyType String -Value '0' -Force

    #New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentCurrentL2" -PropertyType String -Value '0' -Force

    #New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentCurrentL3" -PropertyType String -Value '0' -Force

    #New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentPowerL1" -PropertyType String -Value '0' -Force

    #New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentPowerL2" -PropertyType String -Value '0' -Force

    #New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentPowerL3" -PropertyType String -Value '0' -Force

    #New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentPower" -PropertyType String -Value '0' -Force

    #New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentEnergy" -PropertyType String -Value '0' -Force

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentTemperature" -PropertyType String -Value '0' -Force

   

    # Write SML Frame data to debug

    New-ItemProperty -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name "CurrentSMLFrame" -PropertyType String -Value $SMLFrame -Force

}

 

# Write SML Counters

$GoodSMLFramesCounterNew = Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name 'GoodSMLFramesCounter'

$BadSMLFramesCounterNew = Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name 'BadSMLFramesCounter'

$BadSMLCRCCounterNew = Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\GLAB\ElectricityMeter1' -Name 'BadSMLCRCCounter'

 

 

# Write XML for PRTG

[string]$prtgresult=""

$prtgresult+="<?xml version=""1.0"" encoding=""Windows-1252"" ?>`r`n"

$prtgresult+="<prtg>`r`n"

$prtgresult+="    <result>`r`n"

$prtgresult+="        <channel>SMLGood</channel>`r`n"

$prtgresult+="        <mode>Absolute</mode>`r`n"

$prtgresult+="        <customunit>Frames</customunit>`r`n"

$prtgresult+="        <value>$GoodSMLFramesCounterNew</value>`r`n"

$prtgresult+="        <float>1</float>`r`n"

$prtgresult+="    </result>`r`n"

$prtgresult+="    <result>`r`n"

$prtgresult+="        <channel>SMLBad</channel>`r`n"

$prtgresult+="        <mode>Absolute</mode>`r`n"

$prtgresult+="        <customunit>Frames</customunit>`r`n"

$prtgresult+="        <value>$BadSMLFramesCounterNew</value>`r`n"

$prtgresult+="        <float>1</float>`r`n"

$prtgresult+="    </result>`r`n"

$prtgresult+="    <result>`r`n"

$prtgresult+="        <channel>SMLBadCRC</channel>`r`n"

$prtgresult+="        <mode>Absolute</mode>`r`n"

$prtgresult+="        <customunit>Frames</customunit>`r`n"

$prtgresult+="        <value>$BadSMLCRCCounterNew</value>`r`n"

$prtgresult+="        <float>1</float>`r`n"

$prtgresult+="    </result>`r`n"

$prtgresult+="</prtg>"

 

if ($errorfound) {

            write-host "Error Found. Ending with EXIT Code" ([xml]$prtgresult).prtg.error

}

write-host "Sending PRTGRESULT to STDOUT"

$prtgresult

 

if ($errorfound) {

            exit ([xml]$prtgresult).prtg.error

}

 

 


 

1.20 Registry Datenbank

 

Als einfachste Datenbank wird die Windows Registry hergenommen.

 

Hier sind dann schon in aufbereiteter Form die einzelnen Werte vom SML Frame herausgelöst.

Das SML Frame selbst wird auch zu Debugging Zwecken immer aktuell mit abgelegt.

Markant zu erkennen am Framebeginn 1B1B1B1B.

Auch wie viele SML Frames empfangen wurden und wie viele fehlerhaft waren wird mit aufgezeichnet.

 

 


 

1.21 PRTG Sensoren

 

Weitere einzelne PowerShell Sensoren werden von PRTG verwendet um die Grafen zu zeichnen.

Es wird alle 15 Sekunden aufgezeichnet.

 

 

Der Zähler liefert folgende Daten:

 

3Phasen

·         Strom

·         Spannung

·         Leistung

·         Blindleistung

·         Leistungsfaktor

·         Energie

·         Temperatur

 

 


 

1.22 PRTG Grafen

 

So lassen sich dann im 15sec. Intervall Grafen des Stromzählers aufzeichnen.

 

 

Und auch das RS232 – LAN Modul selbst mit überwachen.

 


1.23 PRTG Map

 

Mit einer PRTG Map werden die Daten dann grafisch aufbereitet und könnten an einem 10,1“ Hochformat Display angezeigt werden. (Siehe Projekt GLAB Smart Display 10)

 


 

1.24 PRTG E-Mail-Benachrichtigung

 

Da der Hausautomation Server sowie der PoE Netzwerkswitch an eine USV angeschlossen sind können auch bei Stromausfall PRTG Grenzwerte erkannt werden und Mail Benachrichtigungen noch versendet werden.

 

 

Die wird mit der Notifikation an der Spannung realisiert:

 

 

 

Eine weitere Notifikation signalisiert ob das RS232 – LAN Modul richtig arbeitet und valide SML Datenpakete kommen:

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

GLAB Logo