HarrySteff
Anmeldungsdatum: 4. August 2017
Beiträge: Zähle...
|
Hallo zusammen, ich habe folgendes Problem: | for i in `seq 1001 1 1001` #Counting Senseboxes - Syntax: seq "startwert" "schrittweite" "endwert"
do
#Get GEO-Coordinates of Senseboxes
eval sensebox${i}_lng=$(sudo cat sensebox${i}.tmp | jq -r '.loc[0].geometry.coordinates[0]')
eval sensebox${i}_lat=$(sudo cat sensebox${i}.tmp | jq -r '.loc[0].geometry.coordinates[1]')
echo 1 echo $sensebox${i}_lng
echo 2 echo $sensebox1001_lng
done
|
Die Ausgabe ist so:
| 1 echo 1001_lng
2 echo 9.675063
|
Die Variablenzuweisung scheint problemlos zu funktionieren.
Die "2. Ausgabe" ist auch richtig!
Allerdings möchte ich die Ausgabe gerne auch mit dem "$i" Zähler bewerkstelligen.
Kann mir vielleicht jemand einen Tipp geben? DANKE!
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Welchen Sinn hat denn die merkwürdige for-Schleife? Wieso nicht
? Die Variable $sensebox${i}_lng ist ja im Prinzip äquivalent zu $a$b_c. Wenn
| a=foo # ist und
b=12 # und
foo12=9 # dann würde
a12=baz
echo $a${b}_c # zu
foo12_c # expandieren - ganz logisch: a=foo, b=12, _c = _c
# Wenn $a wie bei Dir null ist, leer, undefiniert, expandiert es zu 12_c
# Du willst erst $b expandieren, dann $a12. Dazu müsste man sowas schreiben:
echo ${a${b}}_c # aber leider:
bash: ${a${b}}_c: Falsche Variablenersetzung.
|
Variablenexpansion geschieht in einem Durchgang und nicht rekursiv. Jetzt weiß ich aber nicht wo sensebox herkommt, ob Du Einfluss auf die Variablennamen und die 1001 hast. Arrays erlauben geschachelte Auflösung: | sensebox=(foo bar)
echo ${sensebox[0]}
foo
echo ${sensebox[1]}
bar
|
Allerdings haben Basharrays nur bedingt was mit Arrays, die man sonst so kennt, zu tun - man kann Indexe festlegen, die jenseits der deklarierten Bereichs liegen und Lücken lassen: | sensebox[204]=49
echo ${sensebox[204]}
49
echo ${sensebox[@]}
foo bar 49
|
Es ist mehr wie ein assoziatives Dings, eine Map mit ausschließlich numerischen Keys. | sensebox[107]=ffoo
echo ${sensebox[@]}
a9 bar ffoo 49
test=107
echo ${sensebox[test]}
ffoo
|
Vielleicht bringt Dich das weiter.
|
HarrySteff
(Themenstarter)
Anmeldungsdatum: 4. August 2017
Beiträge: 6
|
Vielen Dank für deine Antwort!
Leider hilft es mir so noch nicht so wirklich...
also die for-schleife ist momentan nur ein Test.
Deshalb ist der "bis-Wert" auch nur 1001! Hier soll irgendwann, wenn alles klappt, 1100 oder so stehen. Der Begriff Sensebox ist feststehend, nur die Nummerierung soll von 1001 aufwärts gehen...
Ich parse einen json Inhalt in eine Textdatei, und lese mit jq dann bestimmte Teile daraus aus.
Da ich den block nicht für jede "Sensebox" wiederholen möchte, will ich mit der for-schleife den Zähler jeweils hochsetzen...
Hoffe ich habe mich einigermaßen verständlich ausgedrückt... DANKE
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12821
|
Die Generierung von Variablennamen mit eingebetteten Zahlen ist Quark, da benutzt Du besser ein Array. Und für die Schleife reicht eine Brace Expansion. Also, wenn überhaupt: 1
2
3
4
5
6
7
8
9
10
11
12
13 | #!/bin/bash
# fülle sensebox Array...
for i in {1001..1100}; do
# Get GEO-Coordinates of Senseboxes
sensebox_lng[$i]=$(jq -r '.loc[0].geometry.coordinates[0]' "${sensebox[$i]}")
sensebox_lat[$i]=$(jq -r '.loc[0].geometry.coordinates[1]' "${sensebox[$i]}")
echo "1 echo ${sensebox_lng[$i]}"
echo "2 echo ${sensebox_lat[$i]}"
done
|
Die Chancen stehen aber gut, dass man das noch eleganter lösen kann. Dafür müssten wir aber den größeren Zusammenhang verstehen. Möglicherweise muss man auch gar nicht alle Koordinatenpaare in einem Array speichern, sondern kann sie auch direkt weiter verarbeiten. Ich würde das vermutlich sowieso mit einer Skriptsprache wie Ruby und einem JSON-Parser machen, damit ich die Dateien nicht doppelt lese.
|
HarrySteff
(Themenstarter)
Anmeldungsdatum: 4. August 2017
Beiträge: 6
|
Danke @rklm dafür reicht es bei mir wohl noch nicht ☹ Wenn du mir helfen kannst, ich poste später mal mein gesamtes Script, und was genau ich vorhabe...
Würde mich freuen, wenn du mir helfen würdest! Gruß HarrySteff
|
HarrySteff
(Themenstarter)
Anmeldungsdatum: 4. August 2017
Beiträge: 6
|
Also hier mal eine ausführlichere Erklärung.
Die Sensebox ist ein Messinstrument für Umweltsensoren. (Z.B. Temperatur, Luftfeuchtigkeit, Feinstaub, UV usw.) http://www.sensebox.de
Es gibt eine super API-Schnittstelle (https://docs.opensensemap.org) die ich nutzen möchte, um die Messwerte meiner Box(en) an zwei weitere "Webdienste" (pimatic http://www.pimatic.org und das [ui!]Cockpit https://badhersfeld.urbanpulse.de) zu übermitteln.
Ich habe im moment eine Box zum Testen, das sollen aber zukünftig mehr werden.
Ich habe einfach mal angefangen ein Script zu schreiben mit mehr oder weniger Erfolg: Dies sind die Quelldaten welche ich bei Abfrage mit diesem Link:https://api.opensensemap.org/boxes/596e0dd38ecc8900101c2936 meiner Box zurückbekomme:
| {"_id":"596e0dd38ecc8900101c2936","createdAt":"2017-07-18T13:32:03.732Z","updatedAt":"2017-08-01T14:23:23.668Z","name":"Test2","boxType":"fixed","grouptag":"Bad_Hersfeld","exposure":"outdoor","model":"homeWifiFeinstaub","sensors":[{"title":"Temperatur","unit":"°C","sensorType":"HDC1008","icon":"osem-thermometer","_id":"596e0dd38ecc8900101c2937","lastMeasurement":{"value":"27.67","createdAt":"2017-08-01T14:23:23.664Z"}},{"title":"rel. Luftfeuchte","unit":"%","sensorType":"HDC1008","icon":"osem-humidity","_id":"596e0dd38ecc8900101c2938","lastMeasurement":{"value":"53.16","createdAt":"2017-08-01T14:23:23.664Z"}},{"title":"Luftdruck","unit":"hPa","sensorType":"BMP280","icon":"osem-barometer","_id":"596e0dd38ecc8900101c2939","lastMeasurement":{"value":"987.86","createdAt":"2017-08-01T14:23:23.664Z"}},{"title":"Beleuchtungsstärke","unit":"lx","sensorType":"TSL45315","icon":"osem-brightness","_id":"596e0dd38ecc8900101c293a","lastMeasurement":{"value":"740.00","createdAt":"2017-08-01T14:23:23.664Z"}},{"title":"UV-Intensität","unit":"μW/cm²","sensorType":"VEML6070","icon":"osem-brightness","_id":"596e0dd38ecc8900101c293b","lastMeasurement":{"value":"11.25","createdAt":"2017-08-01T14:23:23.664Z"}},{"title":"PM10","unit":"µg/m³","sensorType":"SDS 011","icon":"osem-cloud","_id":"596e0dd38ecc8900101c293c","lastMeasurement":{"value":"6.00","createdAt":"2017-08-01T14:23:23.664Z"}},{"title":"PM2.5","unit":"µg/m³","sensorType":"SDS 011","icon":"osem-cloud","_id":"596e0dd38ecc8900101c293d","lastMeasurement":{"value":"3.10","createdAt":"2017-08-01T14:23:23.664Z"}},{"_id":"597083342e9396000fd09586","icon":"osem-volume-up","sensorType":"mic","unit":"db","title":"Umgebungslautstärke"}],"loc":[{"geometry":{"coordinates":[9.675063,50.870084],"type":"Point"},"type":"feature"}],"description":"TestSenseBOX"}
|
Jetzt möchte ich all die Infos in Variablen speichern, um dann über eine Schleife die Übermittlungen für jede Box zu bewerkstelligen.
- So war zumindest mein Gedanke Anschließend geht es darum, die Messergebnisse zuerst in pimatic zu übermitteln, dies funktioniert so:
| #Send last Temp-Measurement from Senseboxes to Pimatic
curl \
-X PATCH \
--header "Content-Type:application/json" \
--data '{"type": "value", "valueOrExpression":"'"$sensebox$i_temp"'"}' \
--user "admin:xxx" \
http://test.de:8090/api/variables/sensebox$i_temp
|
In pimatic wurden Variablen angelegt, die der Namenskonvension sensebox1001_temp, sensebox1001_hum usw. entsprechen. Anschließend sollen wie gesagt diese Werte auch an das [ui!]Cockpit übermittelt werden:
So ungefähr:
| ui_url=https://badhersfeld.urbanpulse.de:5350
#send senseboxes_temp to cockpit
#curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' "'"$ui_url"'" -d '{ "sensorId": "$i", "timestamp": "'"$sensebox$i_temp_ts"'", "measurement": "'"$sensebox$i_temp"'", "type": "temperature", "lat": "'"$sensebox$i_lat"'", "lng": "'"$sensebox$i_lng"'"}' -f -s
|
Hierbei soll die "SenseboxID" nicht mehr das Wort Sensebox enthalten (also nur noch 1001, 1002, ...) Hier mein Script, wie es momentan ausschaut: (Ist noch natürlich noch nicht funktionsfähig geschweige denn vollständig)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 | #!/bin/bash
# Testscript Sensebox2Pimatic
#
#####################################################################################################
# #
# Write every SenseBox Details in tmp file #
# #
#####################################################################################################
sudo rm *.tmp #remove last tmp files
sleep 2
sudo curl -s https://api.opensensemap.org/boxes/596e0dd38ecc8900101c2936 >> sensebox1001.tmp
#sudo curl -s https://api.opensensemap.org/boxes/SENSEBOX_ID >> sensebox1002.tmp
#sudo curl -s https://api.opensensemap.org/boxes/SENSEBOX_ID >> sensebox1003.tmp
#sudo curl -s https://api.opensensemap.org/boxes/SENSEBOX_ID >> sensebox1004.tmp
#sudo curl -s https://api.opensensemap.org/boxes/SENSEBOX_ID >> sensebox1005.tmp
#sudo curl -s https://api.opensensemap.org/boxes/SENSEBOX_ID >> sensebox1006.tmp
#sudo curl -s https://api.opensensemap.org/boxes/SENSEBOX_ID >> sensebox1007.tmp
#sudo curl -s https://api.opensensemap.org/boxes/SENSEBOX_ID >> sensebox1008.tmp
#sudo curl -s https://api.opensensemap.org/boxes/SENSEBOX_ID >> sensebox1009.tmp
#sudo curl -s https://api.opensensemap.org/boxes/SENSEBOX_ID >> sensebox1010.tmp
#####################################################################################################
# #
# Fill Variables for bash-script #
# #
#####################################################################################################
for i in `seq 1001 1 1001` #Counting Senseboxes - Syntax: seq "startwert" "schrittweite" "endwert"
do
#Get GEO-Coordinates of Senseboxes
sensebox'$i'_lng=$(sudo cat sensebox$i.tmp | jq -r '.loc[0].geometry.coordinates[0]')
sensebox$i_lat=$(sudo cat sensebox$i.tmp | jq -r '.loc[0].geometry.coordinates[1]')
#Get last Temp-Measurement from Senseboxes
sensebox$i_temp=$(sudo cat sensebox$i.tmp | jq -r '.sensors[0].lastMeasurement.value')
sensebox$i_temp_ts=$(sudo cat sensebox$i.tmp | jq -r '.sensors[0].lastMeasurement.createdAt')
#Get last Humidity-Measurement from Senseboxes
sensebox$i_hum=$(sudo cat sensebox$i.tmp | jq -r '.sensors[1].lastMeasurement.value')
sensebox$i_hum_ts=$(sudo cat sensebox$i.tmp | jq -r '.sensors[1].lastMeasurement.createdAt')
#Get last Pressure-Measurement from Senseboxes
sensebox$i_press=$(sudo cat sensebox$i.tmp | jq -r '.sensors[2].lastMeasurement.value')
sensebox1$i_press_ts=$(sudo cat sensebox$i.tmp | jq -r '.sensors[2].lastMeasurement.createdAt')
#####################################################################################################
# #
# Send Variables to Pimatic #
# #
#####################################################################################################
#Send last Temp-Measurement from Senseboxes to Pimatic
curl \
-X PATCH \
--header "Content-Type:application/json" \
--data '{"type": "value", "valueOrExpression":"'"$sensebox$i_temp"'"}' \
--user "admin:xxx" \
http://test.de:8090/api/variables/sensebox$i_temp
sleep 2
#Send last Humidity-Measurement from Senseboxes to Pimatic
curl \
-X PATCH \
--header "Content-Type:application/json" \
--data '{"type": "value", "valueOrExpression":"'"$sensebox$i_hum"'"}' \
--user "admin:xxx" \
http://test.de:8090/api/variables/sensebox$i_hum
sleep 2
#Send last Pressure-Measurement from Senseboxes to Pimatic
curl \
-X PATCH \
--header "Content-Type:application/json" \
--data '{"type": "value", "valueOrExpression":"'"$sensebox$i_press"'"}' \
--user "admin:xxx" \
http://test.de:8090/api/variables/sensebox$i_press
sleep 2
#####################################################################################################
# #
# Send Measurements to [ui]Cockpit #
# #
#####################################################################################################
ui_url=https://badhersfeld.urbanpulse.de:5350
#senseboxes_temp
#curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' "'"$ui_url"'" -d '{ "sensorId": "$i", "timestamp": "'"$sensebox$i_temp_ts"'", "measurement": "'"$sensebox$i_temp"'", "type": "temperature", "lat": "'"$sensebox$i_lat"'", "lng": "'"$sensebox$i_lng"'"}' -f -s
sleep 2
done #Ende for-schleife für jede SenseBox
|
Wie gesagt, das Script ist nur ein mehr oder weniger erster Gehversuch, und ich bin für andere Vorschläge / Ideen gern zu haben, und hoffe es gibt da eine gute (einfache) ☺ Möglichkeit Vielen Dank schonmal und ein schönes Wochenende!
Ps.: ach ja, und ich habe das mit dem jq auf "aus einer Datei lesen" umgestellt, weil ich dachte, ich muss ja ständig online-aufrufe machen, wenn ich es direkt über den Link hole... 😮
HarrySteff
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12821
|
Aber dann gibt es doch keine Notwendigkeit, das in Arrays zu speichern. Du brauchst doch nur (Pseudocode) | for i in {1001..1100}; do
data=$(hole daten von $i)
lng=$(extrahiere wert 0 von $data)
lat=$(extrahiere wert 1 von $data)
sende an piematic $i $lng $lat
sende an ui cockpit $i $lng $lat
done
|
Das Versenden könnte man in eine Funktion auslagern, aber ich glaube, das sind ja eher Einzeiler.
|
HarrySteff
(Themenstarter)
Anmeldungsdatum: 4. August 2017
Beiträge: 6
|
Mhhh okay, aber ich habe trotzdem noch nicht ganz verstanden wie ich folgendes lösen kann: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | sensebox1001_data=$(sudo curl -s https://api.opensensemap.org/boxes/596e0dd38ecc8900101c2936)
echo $sensebox1001_data #Ausgabe klappt einwandfrei!
sensebox1001_lng=$(echo "$sensebox1001_data" | jq -r '.loc[0].geometry.coordinates[0]') #Dies funktioniert auch super!
echo "Ausgabe:" echo $sensebox1001_lng # Auch Hier kommt genau das Ergebnis welches ich hier erwarte!
# Wie kann ich das in der "FOR-Schleife" mit den Zählern lösen?
for ((i=1001; i<1010; i++)); do
"sensebox"$i"_lng"=$($"sensebox"$i"_data" | jq -r '.loc[0].geometry.coordinates[0]')
#Testausgaben (keine funktioniert)
echo 1 echo "$sensebox""$i""_data"
echo 2 echo $sensebox$i_lng
echo 3 echo $"sensebox"$i"_lng"
done
|
Gibt es eine Möglichkeit die Variable sensebox$zähler_lng irgendwie nach meinem Schema zu "füllen"?
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12821
|
HarrySteff schrieb: Mhhh okay, aber ich habe trotzdem noch nicht ganz verstanden wie ich folgendes lösen kann:
Gibt es eine Möglichkeit die Variable sensebox$zähler_lng irgendwie nach meinem Schema zu "füllen"?
Das ist ja gerade mein Punkt: das brauchst Du nicht. Du machst es Dir unnötig kompliziert.
|