strubartacus
Goto Top

Bashscript in Pythonscript umwandeln

Hallo zusammen

Ich habe mir ein Bash-Script erstellt (absolut quick and dirty) um diverse Stromwerte aus meinem smappee auszulesen. Die Werte werden anschliessend in eine InfluxDB geladen und auf einem Grafana-Dashboard dargestellt. Das Ganze läuft soweit einwandfrei. Trotzdem würde ich gerne das Script nach Python migrieren und das am besten in einer professionelleren Form.

Mein Bash-Script:
#!/bin/bash

ipsmappe="10.11.3.35"  
ipdb="10.11.1.104"  

while true; do
        sleep 5
        login="`curl -s -H "Content-Type: application/json" -X POST -d "admin" http://"$ipsmappe"/gateway/apipublic/logon`"  
        smappeepoll="`curl -s http://"$ipsmappe"/gateway/apipublic/reportInstantaneousValues`"  
        apowerl1="`echo $smappeepoll | html2text | grep apparentPower | cut -d " " -f1 | cut -c 15- | head -n1`"  
        apowerl2="`echo $smappeepoll | html2text | grep apparentPower | cut -d " " -f1 | cut -c 15- | head -n2 | tail -1l`"  
        apowerl3="`echo $smappeepoll | html2text | grep apparentPower | cut -d " " -f1 | cut -c 15- | tail -1l`"  
        powerl1="`echo $smappeepoll | html2text | grep activePower | cut -d " " -f3 | cut -c 13- | head -n1`"  
        powerl2="`echo $smappeepoll | html2text | grep activePower | cut -d " " -f3 | cut -c 13- | head -n2 | tail -1l`"  
        powerl3="`echo $smappeepoll | html2text | grep activePower | cut -d " " -f3 | cut -c 13- | tail -1l`"  
        rpowerl1="`echo $smappeepoll | html2text | grep reactivePower | cut -d " " -f5 | cut -c 15- | head -n1`"  
        rpowerl2="`echo $smappeepoll | html2text | grep reactivePower | cut -d " " -f5 | cut -c 15- | head -n2 | tail -1l`"  
        rpowerl3="`echo $smappeepoll | html2text | grep reactivePower | cut -d " " -f5 | cut -c 15- | tail -1l`"  
        powertotal="`echo $powerl1"+"$powerl2"+"$powerl3 | bc`"  
        cosfil1="`echo $smappeepoll | html2text | grep cosfi | cut -d " " -f3 | cut -c 7- | head -n1 | cut -d, -f1`"  
        cosfil2="`echo $smappeepoll | html2text | grep cosfi | cut -d " " -f3 | cut -c 7- | head -n2 | tail -1l | cut -d, -f1`"  
        cosfil3="`echo $smappeepoll | html2text | grep cosfi | cut -d " " -f3 | cut -c 7- | tail -1l | cut -d, -f1`"  
        voltage="`echo $smappeepoll | html2text | grep voltage | cut -d " " -f1 | cut -c 9-`"  
        currentl1="`echo $smappeepoll | html2text | grep tcurrent | cut -d " " -f1 | cut -c 11- | head -n1`"  
        currentl2="`echo $smappeepoll | html2text | grep tcurrent | cut -d " " -f1 | cut -c 11- | head -n2 | tail -1l`"  
        currentl3="`echo $smappeepoll | html2text | grep tcurrent | cut -d " " -f1 | cut -c 11- | tail -1l`"  

        curl -i -XPOST 'http://'$ipdb':8086/write?db=struband' --data-binary '  
        apparentpower-l1.smappee,host=smappee,location=keller,phase=1 value='$apowerl1'  
        apparentpower-l2.smappee,host=smappee,location=keller,phase=2 value='$apowerl2'  
        apparentpower-l3.smappee,host=smappee,location=keller,phase=3 value='$apowerl3'  
        activepower-l1.smappee,host=smappee,location=keller,phase=1 value='$powerl1'  
        activepower-l2.smappee,host=smappee,location=keller,phase=2 value='$powerl2'  
        activepower-l3.smappee,host=smappee,location=keller,phase=3 value='$powerl3'  
        reactivepower-l1.smappee,host=smappee,location=keller,phase=1 value='$rpowerl1'  
        reactivepower-l2.smappee,host=smappee,location=keller,phase=2 value='$rpowerl2'  
        reactivepower-l3.smappee,host=smappee,location=keller,phase=3 value='$rpowerl3'  
        powertotal.smappee,host=smappee,location=keller,phase=123 value='$powertotal'  
        cosfi-l1.smappee,host=smappee,location=keller,phase=1 value='$cosfil1'  
        cosfi-l2.smappee,host=smappee,location=keller,phase=2 value='$cosfil2'  
        cosfi-l3.smappee,host=smappee,location=keller,phase=3 value='$cosfil3'  
        voltage.smappee,host=smappee,location=keller,phase=123 value='$voltage'  
        current-l1.smappee,host=smappee,location=keller,phase=1 value='$currentl1'  
        current-l2.smappee,host=smappee,location=keller,phase=2 value='$currentl2'  
        current-l3.smappee,host=smappee,location=keller,phase=3 value='$currentl3''  
done
EDIT: Script angepasst

Der zu verarbeitende Output:
root@monitoring:~# curl -s http:{{comment_single_line_double_slash:0}}
{"report":"Instantaneous values:  
voltage=228.9 Vrms
FFTComponents:
Phase 1:
\tcurrent=0.692 A, activePower=118.598 W, reactivePower=105.148 var,
apparentPower=158.498 VA, cosfi=74, quadrant=0, phaseshift=0.0, phaseDiff=0.0
\tFFTComponents:
Phase 2:
\tcurrent=0.133 A, activePower=19.844 W, reactivePower=23.285 var,
apparentPower=30.594 VA, cosfi=62, quadrant=0, phaseshift=0.0, phaseDiff=0.0
\tFFTComponents:
Phase 3:
\tcurrent=1.299 A, activePower=204.569 W, reactivePower=216.077 var,
apparentPower=297.553 VA, cosfi=68, quadrant=0, phaseshift=0.0, phaseDiff=0.0
\tFFTComponents:


Phase 1, peak active power 3668.322 W at 27/12/2016 18:47:55
Phase 2, peak active power 2180.333 W at 03/01/2017 06:10:50
Phase 3, peak active power 4695.78 W at 18/12/2016 13:41:35
active energy RMS per phase mapping combination
phase mapping 210=256.88 kWh [ 1/0]
phase mapping 12=87.606 kWh [ 1/2]
phase mapping 21=82.206 kWh [ -1/2]
phase mapping 102=316.667 kWh [* 1/3]
phase mapping 120=195.204 kWh [ 1/1]
phase mapping 201=127.587 kWh [ 1/2]

active energy RMS (solar) per phase mapping combination
phase mapping 210=0.0 kWh [ 1/0]
phase mapping 12=0.0 kWh [ 1/2]
phase mapping 21=0.0 kWh [ -1/2]
phase mapping 102=0.0 kWh [* 1/3]
phase mapping 120=0.0 kWh [ 1/1]
phase mapping 201=0.0 kWh [ 1/2]

"}  

Das Dashboard:
dashboard

Nun meine Frage: Wie stelle ich das am besten an? Den Output in einer for-Schleife mittels einer vordefinierten Stichwort-Liste parsen und die Werte dann in ein Dictionary schreiben, welches wiederum in einer weiteren for-Schleife ausgelesen wird, um die Werte in die DB zu schreiben? Ginge das? Hätte jemand evtl. Lust, mir eine Vorlage zu erstellen? face-wink

Content-Key: 325670

Url: https://administrator.de/contentid/325670

Printed on: April 19, 2024 at 17:04 o'clock

Mitglied: 131381
131381 Jan 06, 2017 updated at 10:20:10 (UTC)
Goto Top
Moin,
du könntest die Werte z.B. einfach per Regex aus dem gesamten String auslesen. Für jeden Wert die Seite extra abzurufen ist ja sehr ineffektiv face-wink.

Hier ein kleines Beispiel um die Name:Wert Paare auszulesen:
import re
import urllib.request
link = "http://deineurl.com"  
f = urllib.request.urlopen(link)
data = f.read().decode('utf-8')  

for match in re.findall("([^=,\r\n]+)=([^\r\n,]+)",data):  
    print(match.strip(),"=",match[1].strip())  

Wenn das Ergebnis der Website wirklich plain JSON ist was ich hier leider nicht sehen kann da du das Ergebnis durch html2text jagst, kann man das natürlich auch direkt mit der JSON-Bibliothek in ein Objekt umwandeln und dann durchlaufen.
import json
parsed_json = json.loads(data)
http://docs.python-guide.org/en/latest/scenarios/json/

Gruß mik
Member: STRUBartacus
STRUBartacus Jan 06, 2017 at 10:28:42 (UTC)
Goto Top
Zitat von @131381:

Moin,
du könntest die Werte z.B. einfach per Regex aus dem gesamten String auslesen.

Genau so etwas habe ich mir vorgestellt. :thumbsup:

Für jeden Wert die Seite extra abzurufen ist ja sehr ineffektiv face-wink.

Die Seite wird pro Durchlauf aber nur einmal aufgerufen. face-wink


Hier ein kleines Beispiel um die Name:Wert Paare auszulesen:

Vielen Dank, das hilft mir schon weiter.

Wenn das Ergebnis der Website wirklich plain JSON ist was ich hier leider nicht sehen kann da du das Ergebnis durch html2text jagst

Hier noch der unformatierte Output:

{"report":"Instantaneous values:<BR>voltage=230.6 Vrms<BR>FFTComponents:<BR>Phase 1:<BR>\tcurrent=0.689 A, activePower=118.65 W, reactivePower=105.963 var, apparentPower=159.079 VA, cosfi=74, quadrant=0, phaseshift=0.0, phaseDiff=0.0<BR>\tFFTComponents:<BR>Phase 2:<BR>\tcurrent=0.259 A, activePower=46.126 W, reactivePower=38.147 var, apparentPower=59.857 VA, cosfi=76, quadrant=0, phaseshift=0.0, phaseDiff=0.0<BR>\tFFTComponents:<BR>Phase 3:<BR>\tcurrent=1.315 A, activePower=210.417 W, reactivePower=218.681 var, apparentPower=303.475 VA, cosfi=69, quadrant=0, phaseshift=0.0, phaseDiff=0.0<BR>\tFFTComponents:<BR><BR><BR>Phase 1, peak active power 3668.322 W at 27/12/2016 18:47:55<BR>Phase 2, peak active power 2180.333 W at 03/01/2017 06:10:50<BR>Phase 3, peak active power 4695.78 W at 18/12/2016 13:41:35<BR>active energy RMS per phase mapping combination<BR>phase mapping 210=258.295 kWh [ -1/0]<BR>phase mapping 12=88.429 kWh [ 1/1]<BR>phase mapping 21=82.64 kWh [ -1/1]<BR>phase mapping 102=318.387 kWh [* 1/3]<BR>phase mapping 120=196.227 kWh [ 1/1]<BR>phase mapping 201=128.293 kWh [ 1/2]<BR><BR>active energy RMS (solar) per phase mapping combination<BR>phase mapping 210=0.0 kWh [ -1/0]<BR>phase mapping 12=0.0 kWh [ 1/1]<BR>phase mapping 21=0.0 kWh [ -1/1]<BR>phase mapping 102=0.0 kWh [* 1/3]<BR>phase mapping 120=0.0 kWh [ 1/1]<BR>phase mapping 201=0.0 kWh [ 1/2]<BR><BR>"}  

html2text verwende ich nur damit die Zeilenumbrüche interpretiert werden.
Mitglied: 131381
Solution 131381 Jan 06, 2017 updated at 10:37:36 (UTC)
Goto Top
Das ist leider kein valides JSON.

ie Seite wird pro Durchlauf aber nur einmal aufgerufen.
Und die tausend curl Aufrufe face-wink. Naja egal mit dem Input sollest du dir zumindest schon mal selbst was bauen können.
Member: STRUBartacus
STRUBartacus Jan 06, 2017 updated at 10:47:43 (UTC)
Goto Top
Zitat von @131381:

Das ist leider kein valides JSON.

ie Seite wird pro Durchlauf aber nur einmal aufgerufen.
Und die tausend curl Aufrufe face-wink. Naja egal mit dem Input sollest du dir zumindest schon mal selbst was bauen können.

Damit werden die Werte in die DB übertragen. Ok, lässt sich sicher irgendwie auch gesammelt übertragen face-wink
EDIT: Na klar geht das! face-wink


Vielen Dank schon mal!