Moin,
ich möchte diesen String
-94,-11,-62,47130,416,18096129,6200,0,0,0,0,0,0,0
auflösen und die Werte in Readings bunkern.
Es gibt - wo auch immer - Beispiele, wie das geht, ich kann sie nur nicht wiederfinden.
Bitteschön: weiß wer wo ?
wie sollen denn die ReadingNamen aussehen?
sub test{
my $count=0;
foreach(split(/,/,"-94,-11,-62,47130,416,18096129,6200,0,0,0,0,0,0,0")){
fhem("setreading testdummy reading$count $_");
$count++;
}
}
Danke schön, wird probiert.
Habe leider noch kein mir verständliches "Lehrbuch" gefunden, wie Doofe etwas mittels RegEx wo herausfieseln.
man muss ja auch nicht alles per regex lösen, manchmal kann man auch einfach eine existierende perl Funktion wie z.B. split() verwenden 8)
Ja, da hast Du wohl recht.
Deine sub funktioniert wunderbar.
Um auf deine Frage zurückzukommen:
die Readings sollen heißen: RSRP , RSRQ , RSSI TAC , PCI , CELL-ID , EARFCN. Die Nuller werden nicht gebraucht.
Um die Neugierfrage zu beantworten:
ich bin genötigt und aufgefordet der BNetzA nachzuweisen, dass die Schlechte meiner Mobilfunkanbindung wesentlich darauf zurückzuführen ist, dass ich dauernd aus (m)einer (Stamm-)Zelle ausgebucht und in einer anderen Zelle, deren Öffnungswinkel woandershin zeigt, eingebucht werde.
Habe fast 1 Jahr gebraucht, bis ich das so geschnallt habe.
Nun wollen die eine Tabelle, wann das wie oft passiert.
Mein Plan ist mit einem Watchdog zyklisch die CGI des Routers aufzurufen, die Werte zu bunkern und zu prüfen, ob sich die CELL-ID geändert hat.
Idealstenfalls sollen auch die Speedtest-Downloadwerte in die Tabelle gehängt werden. Da habe ich aber noch keinen Plan dafür.
Hast Du bitte einen Rat, wie ich die Readings benenne und die Werte einfülle ?
Hallo Ralph,
z.B. so (Beispielcode zum Testen):
sub value2readings {
my $value_string = q(-94,-11,-62,47130,416,18096129,6200,0,0,0,0,0,0,0,123,456);
my @reading_names = qw(RSRP RSRQ RSSI TAC PCI CELL-ID EARFCN);
my $device = q(test_device);
for my $value (split q{,}, $value_string) {
next if $value == 0;
my $name = shift @reading_names;
fhem(qq{setreading $device $name $value}) if $name;
}
}
sub fhem {
say @_;
}
value2readings();
Die Werte (Namen der künftigen Readings) in @reading_names müssen in der gleichen Reihenfolge angeben sein wie die Werte in $value_string. 0-Werte werden ignoriert, ebenso wenn es keinen Namen mehr in @reading_names gibt.
Hallo Ralph,
Idee:
Test in der Kommandozeile sonst nur ein semikolon ;)
{my $count=0;;
my @val=split(/,/,"-94,-11,-62,47130,416,18096129,6200,0,0,0,0,0,0,0");;
foreach('RSRP' , 'RSRQ' , 'RSSI', 'TAC' , 'PCI' , 'CELL-ID' , 'EARFCN'){
fhem("setreading testdummy $_ $val[$count]");;
$count++;;
}
}
Edit: Zu langsam :)
Gruß Otto
Zitat von: betateilchen am 02 Dezember 2020, 15:18:10
man muss ja auch nicht alles per regex lösen, manchmal kann man auch einfach eine existierende perl Funktion wie z.B. split() verwenden 8)
nitpick:
PATTERN in
split ist auch eine regular expression ;-)
ja, das ist aber nicht das, was Ralph meint, wenn er davon schreibt, dass ihm regex suspekt sind :)
So würde es e.g. als Version ohne split aussehen:
sub value2readings_re {
my $value_string = q(-94,-11,-62,47130,416,18096129,6200,0,0,0,0,0,0,0,);
my @reading_names = qw(RSRP RSRQ RSSI TAC PCI CELL-ID EARFCN FOO BAR);
my $device = q(test_device);
for my $value ($value_string =~ /([^,]+)/g) {
next if $value == 0;
my $name = shift @reading_names;
fhem(qq{setreading $device $name $value}) if $name;
}
}
Der /g-Modifier macht global matching, d.h. er springt von match zu match und liefert alle Ergebnisse als Liste zurück.
Ich bin platt !
Danke schön. Ihr überbietet Euch ja geradezu. Bitte entfacht keinen Methodenstreit, ich brauche euch noch. :-)
Bitte gebt mir etwas Zeit das alles auszu probieren. Ob ich es je verstehe, das mag ich nicht garantieren.
Danke Euch allen.
Zitat von: Ralph am 02 Dezember 2020, 22:02:47
Danke schön. Ihr überbietet Euch ja geradezu. Bitte entfacht keinen Methodenstreit, ich brauche euch noch. :-)
Ach iwo, TIMTOWTDI (https://de.wikipedia.org/wiki/Perl_(Programmiersprache)#Mehrere_Wege).
Also ich danke Euch nochmals
und habe mir was zusammengefriemelt, das für mich funktioniert:
Internals:
NAME o2spot
STATE 18096129
TYPE dummy
READINGS:
2020-12-04 17:05:00 CELL-ID 18096129
2020-12-04 17:05:00 EARFCN 6200
2020-12-04 17:05:00 PCI 416
2020-12-04 17:05:00 RSRP -93
2020-12-04 17:05:00 RSRQ -10
2020-12-04 17:05:00 RSSI -65
2020-12-04 17:05:00 TAC 47130
2020-12-04 13:25:51 state 18096153
Attributes:
room Internet
stateFormat CELL-ID
.
DEF ([+:05]) { my $count=0;;
my @val=split(/,/,(GetHttpFile("o2.spot", "/cgi-bin/mycgi?ACT=GetLTECellinfo")));;
foreach('RSRP' , 'RSRQ' , 'RSSI', 'TAC' , 'PCI' , 'CELL-ID' , 'EARFCN'){
fhem("setreading o2spot $_ $val[$count]");;
$count++;;
}
my $zeit = ReadingsTimestamp("o2spot","CELL-ID","0");;
my $rsrp = ReadingsVal("o2spot","RSRP","0");;
my $rsrq = ReadingsVal("o2spot","RSRQ","0");;
my $rssi = ReadingsVal("o2spot","RSSI","0");;
my $tac = ReadingsVal("o2spot","TAC","0");;
my $pci = ReadingsVal("o2spot","PCI","0");;
my $cellid = ReadingsVal("o2spot","CELL-ID", 0);;
my $earfcn = ReadingsVal("o2spot","EARFCN","0");;
open (DATEI, ">>/opt/fhem/log/o2spot.txt") or die $!;;
print DATEI "$zeit $rsrp $rsrq $rssi $tac $pci $cellid $earfcn\n";;
close (DATEI);;
if ( Value("o2spot") ne 18096129) {
fhem "set o2spot_Rel off" ;;
fhem "set Y_LED blink 60" ;;
}
}
MODEL FHEM
NAME di_o2spot
NOTIFYDEV global
NTFY_ORDER 50-di_o2spot
STATE cmd_1
TYPE DOIF
Attributes:
do always
room Internet
Wenn mir wieder eine schlechtere Zelle untergeschoben wird, dann wird der Pott neu gestartet.
Eine Möglichkeit, den LTE-Speed mit Methoden wie GetHttpFile oder ähnlich habe ich noch nicht gefunden.
Ich scheitere daran, dass man immer händisch irgendwelche Buttons drücken und auf das Ergebnis warten muss.
Zitat von: Ralph am 04 Dezember 2020, 17:13:37
Wenn mir wieder eine schlechtere Zelle untergeschoben wird, dann wird der Pott neu gestartet.
Wie kommt denn die CELL-ID in den
state des o2spot-Dummies?
Zitat von: Ralph am 04 Dezember 2020, 17:13:37
Eine Möglichkeit, den LTE-Speed mit Methoden wie GetHttpFile oder ähnlich habe ich noch nicht gefunden.
Ich scheitere daran, dass man immer händisch irgendwelche Buttons drücken und auf das Ergebnis warten muss.
Was genau hast du denn für ein Setup? Reines LTE? Wenn ja, kannst du das speedtest-Modul nehmen, das periodisch einen Speedtest macht - und die Daten dann zu deinem Device loggen. Ich habe hier im Forum schon mehrfach gelesen, dass Leute so z.B. Vodafone an die Kandare nehmen und ihr Sonderkündigungsrecht nutzen konnten.
Zitat von: Christoph Morrison am 04 Dezember 2020, 17:36:38
Wie kommt denn die CELL-ID in den state des o2spot-Dummies?
Mit
Attributes:
stateFormat CELL-ID
Das habe ich irgendwo abgeschrieben.
Oups, es gibt ein Speedtest-Modul? Das ist mir durchgegangen. Muss ich gucken. Danke für den Tip.
Zitat von: Ralph am 04 Dezember 2020, 17:57:11
MitAttributes:
stateFormat CELL-ID
Das habe ich irgendwo abgeschrieben.
Damit kommt
CELL-ID in den
STATE, nicht in den
state. Das sind zwei unterschiedliche paar Schuhe.
state und
CELL-ID sind bei dir auch unterschiedlich. In deinem Fall ist das aber nicht tragisch, weil du eh Value() benutzt. Insgesamt ist das aber nicht mehr state of the art, wie man so schön sagt.
Willst du wirklich alle 5 Minuten einen Logeintrag haben? Oder reicht es, wenn du einen Logeintrag bekommst, wenn sich die Cell-ID ändert? Du kannst das Logging auch FHEM machen lassen. Insgesamt machst du es dir ganz schön schwer ist mein Eindruck.
Wahrscheinlich ist das so. Ich weiß und ich kann es aber nicht besser. Und ich kämpfe jeden Tag darum, dass ich nicht verblöde.
Es mag geschicktere Lösungen und Wege geben, aber ich kenne sie eben nicht.
Nun weiß ich, was Du meintest. dein kleine state hatte ich selber beschrieben, um mir die Abweichung zu merken.
Was die Protokollierung betrifft, da experimentiere ich noch.