Skip to content

Commit 63eea2e

Browse files
author
Klas Pihl
committed
Initial code read power meter with P1 port
1 parent d34d196 commit 63eea2e

File tree

5 files changed

+187
-0
lines changed

5 files changed

+187
-0
lines changed

get-P1power/get-P1power.ps1

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<#
2+
.SYNOPSIS
3+
Get power reading from smart power meter using the HAN / H1 / P1 port
4+
.DESCRIPTION
5+
Call from /var/prtg/scriptsxml/get-P1power.sh that just load the powershell script from bash. Uses PRTG 'SSH Script Advanced' sensor
6+
.NOTES
7+
2022-12-04 Version 1 [email protected]
8+
.NET new-Object System.IO.Ports.SerialPort does not get data, use command 'cu' instead.
9+
.LINK
10+
https://hanporten.se/
11+
.EXAMPLE
12+
cu -l /dev/ttyUSB0 -s 115200 -E% > pwr.log
13+
#>
14+
function get-P1data {
15+
param (
16+
$SerialPort = '/dev/ttyUSB0',
17+
$BaudRate=115200,
18+
$Parity=0, #'None'
19+
$StopBits=1, #'One'
20+
$DataBits =8 ,
21+
$ByteSize=8,
22+
$XonXoff=$false,
23+
$TimeOut = 120
24+
)
25+
$Templog = New-TemporaryFile | Select-Object -ExpandProperty FullName
26+
$Starttime = get-date
27+
do {
28+
29+
$CUCommand = [Scriptblock]::Create(("cu -l {0} -s {1} -E% > {2}" -f $SerialPort,$BaudRate,$Templog))
30+
31+
$JobGetData = Start-Job -ScriptBlock $CUCommand
32+
while($JobGetData.State -ne 'Completed') {
33+
Start-Sleep -Milliseconds 100
34+
Write-Verbose "Waiting to complete"
35+
}
36+
$JobGetData | Remove-Job
37+
$ResultJob = Get-Content $Templog
38+
$CurrentTime = Get-Date
39+
if(($CurrentTime-$Starttime).totalseconds -ge $TimeOut) {
40+
throw "Timout, could not get a correct reading in $TimeOut seconds"
41+
}
42+
} while ($ResultJob.length -le 10) #data is written from power meeter every 10 seconds, sometime the data returned is not complete.
43+
Remove-Item -Path $Templog -Force
44+
45+
#Date,0-0:1.0.0
46+
$Map =
47+
"metric,register,value,suffix
48+
Measure,1-0:1.8.0
49+
Effekt,1-0:1.7.0
50+
L1,1-0:21.7.0
51+
L2,1-0:41.7.0
52+
L3,1-0:61.7.0
53+
L1A,1-0:31.7.0
54+
L2A,1-0:51.7.0
55+
L3A,1-0:71.7.0
56+
" | ConvertFrom-Csv
57+
58+
59+
60+
foreach ($Register in $Map) {
61+
$Match = $ResultJob | Where-Object {$PSitem -match $Register.register} | Select-Object -Last 1
62+
if($Match) {
63+
$Value,$Suffix = $Match.Replace($Register.register,'').Split('*').trim('(',')')
64+
$Register.value = $Value
65+
$Register.suffix = $Suffix
66+
}
67+
68+
}
69+
Write-Output $Map
70+
}
71+
72+
#Main code
73+
try {
74+
$Measurements = get-P1data
75+
$Output = [PSCustomObject]@{
76+
prtg = [PSCustomObject]@{
77+
result =
78+
$Measurements | ForEach-Object {
79+
[PSCustomObject]@{
80+
Channel = $PSitem.metric
81+
Float = 1
82+
Value = $PSitem.value
83+
CustomUnit = $PSitem.suffix
84+
85+
}
86+
}
87+
}
88+
}
89+
90+
} Catch {
91+
$error
92+
$Output = [PSCustomObject]@{
93+
prtg = [PSCustomObject]@{
94+
error = 1
95+
text = $error[0].Exception.Message
96+
}
97+
}
98+
}
99+
Write-Output ($Output | ConvertTo-Json -depth 5 | ForEach-Object { [System.Text.RegularExpressions.Regex]::Unescape($PSItem) })

get-P1power/get-P1power.sh

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/bash
2+
pwsh -file /var/prtg/scriptsxml/get-P1power.ps1

get-P1power/get-PRTGhistoricdiff.ps1

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<#
2+
.SYNOPSIS
3+
Get differense from sensor since last n minutes
4+
.DESCRIPTION
5+
If historic data is less then argument minutes an correcting scale is calculated.
6+
Historic data API can not select datachannel so only a sensor with one channel should be used. If sensor is multichannel create a 'sensor factory'
7+
sensor with only desired channel.
8+
.NOTES
9+
2022-12-06 Version 1 [email protected]
10+
Used to get the daily power consumption from API historicdata.
11+
No error handling
12+
13+
.EXAMPLE
14+
.\get-PRTGhistoricdiff.ps1 -User %windowsuser -Password %windowspassword -SensorID %sensorid -BaseURL https://prtg.pihl.local
15+
#>
16+
17+
18+
19+
[CmdletBinding()]
20+
param (
21+
$BaseURL='https://prtg.pihl.local',
22+
$SensorID=9950,
23+
$Minutes=1440,
24+
$User,
25+
$Password
26+
)
27+
$EndDate = Get-Date -format "yyyy-MM-dd-HH-mm-ss"
28+
$StartDate ='{0:yyyy-MM-dd-HH-mm-ss}' -f ((get-date).AddMinutes(-$Minutes))
29+
30+
$url = '{0}/api/historicdata.json?id={1}&avg=0&sdate={2}&edate={3}&username={4}&password={5}' -f $BaseURL,$SensorID,$StartDate,$EndDate,$User,$Password
31+
$data = Invoke-WebRequest $url -UseBasicParsing
32+
$result = $data.Content | ConvertFrom-Json | Select-Object -ExpandProperty histdata | Where-Object coverage_raw -gt 0
33+
$ResultValue = $result[-1].value_raw-$result[0].value_raw
34+
35+
[datetime]$TimeAdjustStart = $result[0].datetime
36+
[datetime]$TimeAdjustEnd = $result[-1].datetime
37+
$TimeDiff = $TimeAdjustEnd - $TimeAdjustStart
38+
if($TimeDiff.TotalMinutes -lt $Minutes) {
39+
Write-Verbose "Date is from smaller interval then scope, adjusting"
40+
$Factor = $Minutes / $TimeDiff.TotalMinutes
41+
$ResultValue = $ResultValue* $Factor
42+
}
43+
44+
Write-Output ("{0}:{0}" -f (([string]([math]::Round($ResultValue,1))).Replace(',',',')))
45+

get-P1power/img/overview.png

49.5 KB
Loading

get-P1power/readme.MD

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# PRTG sensor for power grid meeter
2+
3+
## Swedish implementation
4+
P1 port from [DSMR P1 Companion Standard](https://www.netbeheernederland.nl/_upload/Files/Slimme_meter_15_a727fce1f1.pdf)
5+
6+
### Protocol
7+
SerialPort = '/dev/ttyUSB0'
8+
BaudRate=115200
9+
Parity=None
10+
StopBits=One
11+
DataBits = 8
12+
ByteSize = 8
13+
XonXoff = Off
14+
15+
## My soloution
16+
17+
Raspberry and arms length from whe power meeter.
18+
[USB - P1](https://www.sossolutions.nl/slimme-meter-kabel-p1-kabel-3-meter)
19+
Energy meeter Landis + Gyr E350
20+
21+
### PRTG
22+
Trigger data collection, db and visualisation
23+
24+
### Shell script to start data collection by powershell
25+
26+
27+
### Powershell code
28+
29+
Could not get .NET new-Object System.IO.Ports.SerialPort to get data so instead I used linux command CU
30+
```bash
31+
sudo apt-get install cu
32+
cu -l /dev/ttyUSB0 -s 115200 -E%
33+
```
34+
Dumped output to a temporary file and parse the output and create json output readable in PRTG
35+
36+
![overview](img/overview.png)
37+
38+
39+
### Bonus sensor
40+
I like to have an easy metric to compare the total energy consumption day to day.
41+
Wrote an 'XML Custom EXE/Script' sensor using PRTG API to collect historical data and use a factor to interpolate 24h consumption.

0 commit comments

Comments
 (0)