Hallo zusammen,
ich wollte gerne eine json - Datei auslesen, die direkt auf dem System liegt, wo auch FHEM drauf läuft.
Hier mal ein List des Moduls:
Internals:
API_LAST_MSG 200
API_LAST_RES 1672949813.85706
CFGFN
DEF file://home/pi/BTCInfo.json
FUUID 63b5f00e-f33f-de75-143a-a00245a638994b8e
NAME BTCInfoTest
NEXT 2023-01-05 22:00:00
NR 513
SOURCE /home/pi/BTCInfo.json (339)
STATE ???
SVN 24783 2021-07-21 22:37:12 UTC
TYPE JsonMod
eventCount 109
CONFIG:
IN_REQUEST 0
SOURCE file://home/pi/BTCInfo.json
SECRET:
OLDREADINGS:
READINGS:
Attributes:
readingList complete();
room BETA
Die JSON - Datei hat folgenden Inhalt:
getPositions: b'{"code":0,"msg":"","ttl":1,"data":{"positions":[{"positionId":"16106910628XXXXXXXXX","symbol":"BTC-USDT","currency":"","volume":0.000X,"availableVolume":0.000X,"positionSide":"Long","marginMode":"Isolated","avgPrice":16906,"liquidatedPrice":XX.X,"margin":X.4454,"leverage":1,"pnlRate":-0.08,"unrealisedPNL":-0.0075,"realisedPNL":-0.0034}]}}'
Nur irgendwie will es noch nicht so ganz. Eine andere Datei als JSON läuft ohne Probleme und ich erhalte Readings.
Bei der Datei, die ich zum testen habe, erscheint am Ende der Zeile SOURCE in Klammern eine 78. Hier ist es eine 339 zu sehen.
Ist das die Anzahl der Zeichen oder ist das noch ein interner Code ?
Oder kann es an der Kodierung der JSON ansich liegen ? Da habe ich allerdings keinen Einfluss drauf :o.
Viele Grüße und Besten Dank
Warum in Anfängerfragen und nicht im passenden Unterforum:
Zitat von: help jsonmod
Module: 98_JsonMod.pm Maintainer: herrmannj Forum: Automatisierung
Du kannst auch verschieben...
...dann bekommen es auch Leute mit, die das Modul genau(er) kennen.
Wenn es mit einer Datei geht und mit einer anderen nicht:
Wo ist die Datei/Inhalt, die geht?
Liegen sie an unterschiedlichen Orten?
Weil die, die nicht geht liegt ja in /home/pi/ da dürfen andere User u.U. nicht viel/alles, weil "gehört" ja dem User pi und fhem läuft (norm.) unter dem User fhem...
Ansonsten: steht etwas im fhem Log? verbose höher setzen und noch mal schauen...
Gruß, Joachim
Deine Datei enthält schlicht keinen gültigen JSON Input.
Das kannst Du mit jedem beliebigen JSON pretty printer, den Du online findest, nachprüfen.
Hast Du eigentlich die ganzen "X" und das "b'" in den Beispielcode eingebaut? Problem dabei ist, dass rein numerische Werte nicht in "" stehen, aber wenn Du da ein X reinschreibst, dann ist das halt kein numerischer Wert mehr, sondern ein alphanumerischer. Und der muss dann doch wieder in "" eingefasst werden.
Was das "b'" soll, erschließt sich mir allerdings nicht.
Und um den gesamten Inhalt gehört nochmal eine geschweifte Klammer.
Dann käme am Ende sowas raus:
{
"getPositions": {
"code": 0,
"msg": "",
"ttl": 1,
"data": {
"positions": [
{
"positionId": "16106910628XXXXXXXXX",
"symbol": "BTC-USDT",
"currency": "",
"volume": 0.0,
"availableVolume": 0.0,
"positionSide": "Long",
"marginMode": "Isolated",
"avgPrice": 16906,
"liquidatedPrice": "XX.X",
"margin": "X.4454",
"leverage": 1,
"pnlRate": -0.08,
"unrealisedPNL": -0.0075,
"realisedPNL": -0.0034
}
]
}
}
}
Hallo zusammen,
Danke für eure Antworten. Ich hatte das mit dem Dateiinhalt schon so grob in Verdacht. Bin aber bei der Auswertung von JSON - Inhalten noch blutiger Anfänger.
Es gibt hier im Forum das Beispiel mit einer Zisterne. Da hatte ich folgendes als "Testobjekt" als JSON Datei hinterlegt:
{"Sensor":"Zisterne","IP":"192.168.18.90","Fuellstand":"156","Abstand":"0"}
Nachzulesen hier: https://forum.fhem.de/index.php?topic=109412.0 (https://forum.fhem.de/index.php?topic=109412.0)
Da liefert das Modul dann natürlich 4 ordentliche Readings.
Die Datei, wie sie mir per Python-Skript geschrieben wird, kann ich nicht ändern. Sprich, es in einen konformen JSON - Inhalt zu bringen.
Die "XXXX"se war ich. Da stehen normalerweise Zahlen.
Ich hatte ebenfalls kurz einmal das FileRead angefangen zu nutzen. Bis ich über JsonMod gestolpert bin.
Wie kann ich denn wohl aus dem "nicht konformen Zeichensalat" meine Readings generieren ?
Habt ihr noch einen Tipp zum Anstoß ?
Vielen Dank an euch für eure Hilfe !
Warum kannst Du das python Skript nicht ändern?
Woher stammt das skript und was tut das eigentlich?
Guten Morgen,
da hole ich kurz einmal etwas weiter aus. Die Funktionsweise sieht so aus, dass ich eine Anfrage per Python–Skript an einen Server sende. Dieser soll mir dann ein Ergebnis einiger Bitcoin–Kursdaten zurück geben. Wenn ich das Abfrageskript starte, ,,baut" er die Anfrage mit verschieden Variablen in dem Pythonskript zusammen und sendet diese zu dem besagten Server. Und dieser sendet dann die obige Rückantwort. Diese wird dann 1:1 in eine Datei gespeichert, die FHEM als Datengrundlage nutzen soll. Die Serverantwort kann ich dann halt nur manuell ändern. Aber das würde für mich dann nur wenig Sinn machen. Viel einfacher wäre es natürlich, wenn ich eine direkte Abfrage per HTTPMOD oder JsonMod per Webadresse starten könnte.
Viele Grüße
André
Zeig doch mal das Skript wenn es möglich ist. Das geht sicherlich auch mit HTTPMOD oder man erweitert das Skript so das es gleich an FHEM sendet und nicht das FHEM da "abholen" muss.
Hi CoolTux,
Hier mal das Skript was eigentlich drei Funktionen kann. Ich nutze aber nur die 'getPositions'.
#coding: utf-8
import urllib.request
import json
import base64
import hmac
import time
APIURL = "https://api-swap-rest.bingbon.pro"
APIKEY = "Set your api key here !!"
SECRETKEY = "Set your secret key here!!"
def genSignature(path, method, paramsMap):
sortedKeys = sorted(paramsMap)
paramsStr = "&".join(["%s=%s" % (x, paramsMap[x]) for x in sortedKeys])
paramsStr = method + path + paramsStr
return hmac.new(SECRETKEY.encode("utf-8"), paramsStr.encode("utf-8"), digestmod="sha256").digest()
def post(url, body):
req = urllib.request.Request(url, data=body.encode("utf-8"), headers={'User-Agent': 'Mozilla/5.0'})
return urllib.request.urlopen(req).read()
def getBalance():
paramsMap = {
"apiKey": APIKEY,
"timestamp": int(time.time()*1000),
"currency": "USDT",
}
sortedKeys = sorted(paramsMap)
paramsStr = "&".join(["%s=%s" % (x, paramsMap[x]) for x in sortedKeys])
paramsStr += "&sign=" + urllib.parse.quote(base64.b64encode(genSignature("/api/v1/user/getBalance", "POST", paramsMap)))
url = "%s/api/v1/user/getBalance" % APIURL
return post(url, paramsStr)
def getPositions(symbol):
paramsMap = {
"symbol": symbol,
"apiKey": APIKEY,
"timestamp": int(time.time()*1000),
}
sortedKeys = sorted(paramsMap)
paramsStr = "&".join(["%s=%s" % (x, paramsMap[x]) for x in sortedKeys])
paramsStr += "&sign=" + urllib.parse.quote(base64.b64encode(genSignature("/api/v1/user/getPositions", "POST", paramsMap)))
url = "%s/api/v1/user/getPositions" % APIURL
return post(url, paramsStr)
def placeOrder(symbol, side, price, volume, tradeType, action):
paramsMap = {
"symbol": symbol,
"apiKey": APIKEY,
"side": side,
"entrustPrice": price,
"entrustVolume": volume,
"tradeType": tradeType,
"action": action,
"timestamp": int(time.time()*1000),
}
sortedKeys = sorted(paramsMap)
paramsStr = "&".join(["%s=%s" % (x, paramsMap[x]) for x in sortedKeys])
paramsStr += "&sign=" + urllib.parse.quote(base64.b64encode(genSignature("/api/v1/user/trade", "POST", paramsMap)))
url = "%s/api/v1/user/trade" % APIURL
return post(url, paramsStr)
def main():
print("getBalance:", getBalance())
print("placeOpenOrder:", placeOrder("BTC-USDT", "Bid", 0, 0.0004, "Market", "Open"))
print("getPositions:", getPositions("BTC-USDT"))
print("placeCloseOrder:", placeOrder("BTC-USDT", "Ask", 0, 0.0004, "Market", "Close"))
if __name__ == "__main__":
main()
Weiß nicht, ob man da was umbauen kann ?
VG
Da ist nix geheimnisvolles dabei, und das ist so simpel, dass man nichtmal HTTPMOD oder JsonMod dazu braucht.
Das geht problemlos als Funktion in der 99_myUtils.pm.
Die URL zusammenbasteln und mit FHEM Bordmitteln aufrufen,
das Ergebnis mit json2nameValue() oder json2reading() verarbeiten, dann kommt sowas raus:
$VAR1 = {
'getPositions_data_positions_1_leverage' => '1',
'getPositions_data_positions_1_symbol' => 'BTC-USDT',
'getPositions_data_positions_1_volume' => '0.0',
'getPositions_data_positions_1_marginMode' => 'Isolated',
'getPositions_data_positions_1_margin' => 'X.4454',
'getPositions_data_positions_1_pnlRate' => '-0.08',
'getPositions_data_positions_1_positionId' => '16106910628XXXXXXXXX',
'getPositions_ttl' => '1',
'getPositions_code' => '0',
'getPositions_data_positions_1_positionSide' => 'Long',
'getPositions_data_positions_1_liquidatedPrice' => 'XX.X',
'getPositions_data_positions_1_unrealisedPNL' => '-0.0075',
'getPositions_msg' => '',
'getPositions_data_positions_1_realisedPNL' => '-0.0034',
'getPositions_data_positions_1_avgPrice' => '16906',
'getPositions_data_positions_1_currency' => '',
'getPositions_data_positions_1_availableVolume' => '0.0'
};
Was ich immer noch nicht weiß: Was kommt als Ergebnis wirklich aus dem Skript?
Der json-input im ersten Beitrag wurde derartig verhunzt, dass ich einfach nicht glaube, dass sowas aus einem API-Abruf als Ergebnis kommt.
Hallo zusammen,
ZitatDer json-input im ersten Beitrag wurde derartig verhunzt, dass ich einfach nicht glaube, dass sowas aus einem API-Abruf als Ergebnis kommt.
Doch. Ist leider so. Sonst hätte ich ihn auch leichter dekodiert bekommen. Habe es nochmal gegen gecheckt, indem ich den Aufruf nochmals von Hand in die Konsole getippert habe und die Antwort, die ich dann vom Server bekomme ist absolut identisch mit der, die ich oben gepostet habe. Nur habe ich die private Keys "verstümmelt". Mehr aber nicht.
Mit deinem Ergebnis ist ja schon genial. Da muss ich mich dann wohl noch weiter einarbeiten...
Bis hierhin schonmal ein herzliches Dankeschön für die Hilfestellung !
Ok, nehmen wir mal an, der Teil am Anfang "getPositions: b'" gehört gar nicht zum JSON selbst, sondern ist einfach für die Identifikation des Datensatzes notwendig. Dann müssen wir das inklusive des einfachen Anführungszeichen wegregexen.
$json =~ s/^getPositions.*{/{/;
Dann vernichten wir noch das einfache Anführungszeichen ganz am Ende, damit passen dann auch die geschweiften Klammern.
$json =~ s/'$//;
Und schon bleibt ein korrekter JSON Inhalt übrig.
Probier mal folgendes in der 99_myUtils.pm:
use Data::Dumper;
sub test {
my ($err,@input) = FileRead({FileName=>'/tmp/test.input', ForceType=>'file'});
return $err if $err;
my $json = join ("",@input);
$json =~ s/^getPositions.*{/{/;
$json =~ s/'$//;
return Dumper json2nameValue($json);
}
Den FileName musst Du natürlich auf Deinen Dateinamen ändern.
Bei mir kommt dann das als Ergebnis:
$VAR1 = {
'currency' => '',
'unrealisedPNL' => '-0.0075',
'positionId' => '16106910628XXXXXXXXX',
'symbol' => 'BTC-USDT',
'leverage' => '1',
'avgPrice' => '16906',
'pnlRate' => '-0.08',
'marginMode' => 'Isolated',
'availableVolume' => '0.0003',
'volume' => '0.0002',
'realisedPNL' => '-0.0034',
'liquidatedPrice' => '23.4',
'positionSide' => 'Long',
'margin' => '0.4454'
};
Hallo betateilchen,
jau ! Das geht schon genau so, wie du geschrieben hast. Habe das gleiche Ergebnis ! :D.
Jetzt bleibt halt nur die Frage, wie ich die Readings in einen dummy oder so bekomme ?
Ich habe vor Ur-Zeiten mal einmal ein paar Antworten für einen Telegram-Bot in der 99_myUtils abgelegt. Mehr habe ich damit (leider)
noch nicht machen müssen. Aber ich glaube, ich habe es mir dadurch in der Vergangenheit schwerer gemacht, als ich hätte müssen... ???
VG
Zitat von: Stargazer am 06 Januar 2023, 19:24:22
Jetzt bleibt halt nur die Frage, wie ich die Readings in einen dummy oder so bekomme ?
Dazu musst Du nur die Zeile mit dem return austauschen:
return json2reading('testDummy',$json);
'testDummy' ist der Name eines device, in dem die readings gesetzt werden sollen.
Das kann natürlich auch eine Variable sein, in der ein Name steckt.
Hallo betateilchen,
vielen Dank an dich. Es läuft absolut perfekt.
da werde ich mich wohl noch des öfteren mit der 99_myUtils beschäftigen müssen ;) :D.
Viele Grüße und einen schönen Abend...
Hallo zusammen,
ich grabe diesen Thread noch einmal aus, da ich aktuell noch einmal euren Rat/Tipp brauche.
Ich würde gerne eine json-Datei parsen. Ebenfalls wieder über die 99_myUtils. Diesesmal jedoch scheint mir JSON - Datei nicht so komplex zu sein,
wie der Vorgänger.
Hier einmal der Inhalt der JSON-Datei:
{'ret_code': 0, 'ret_msg': 'OK', 'result': [{'user_id': 51101317, 'symbol': 'BTCUSDT', 'side': 'None', 'size': 0, 'position_value': 0, 'entry_price': 0, 'liq_price': 0, 'bust_price': 0, 'leverage': 1, 'auto_add_margin': 0, 'is_isolated': True, 'position_margin': 0, 'occ_closing_fee': 0, 'realised_pnl': -0.1473463, 'cum_realised_pnl': -0.2546504, 'free_qty': 0, 'tp_sl_mode': 'Full', 'unrealised_pnl': 0, 'deleverage_indicator': 0, 'risk_id': 1, 'stop_loss': 0, 'take_profit': 0, 'trailing_stop': 0, 'position_idx': 0, 'mode': 'MergedSingle'}], 'ext_code': '', 'ext_info': '', 'time_now': '1674316840.217231', 'rate_limit_status': 119, 'rate_limit': 120, 'rate_limit_reset_ms': 1674316840212}
Dazu hatte ich folgenden Eintrag zum testen in die Utils geschrieben:
use Data::Dumper;
sub test {
my ($err,@input) = FileRead({FileName=>'/home/pi/BTCOrderInfoByBit.txt', ForceType=>'file'});
return $err if $err;
my $json = join ("",@input);
##$json =~ s/^getPositions.*{/{/;
$json =~ s/'$//;
return Dumper json2nameValue($json);
}
Und die Antwort seitens FHEM:
$VAR1 = {
'json2nameValueInput' => '{\'ret_code\': 0, \'ret_msg\': \'OK\', \'result\': [{\'user_id\': 51101317, \'symbol\': \'BTCUSDT\', \'side\': \'None\', \'size\': 0, \'position_value\': 0, \'entry_price\': 0, \'liq_price\': 0, \'bust_price\': 0, \'leverage\': 1, \'auto_add_margin\': 0, \'is_isolated\': True, \'position_margin\': 0, \'occ_closing_fee\': 0, \'realised_pnl\': -0.1473463, \'cum_realised_pnl\': -0.2546504, \'free_qty\': 0, \'tp_sl_mode\': \'Full\', \'unrealised_pnl\': 0, \'deleverage_indicator\': 0, \'risk_id\': 1, \'stop_loss\': 0, \'take_profit\': 0, \'trailing_stop\': 0, \'position_idx\': 0, \'mode\': \'MergedSingle\'}], \'ext_code\': \'\', \'ext_info\': \'\', \'time_now\': \'1674316840.217231\', \'rate_limit_status\': 119, \'rate_limit\': 120, \'rate_limit_reset_ms\': 1674316840212}',
'json2nameValueErrorText' => 'error parsing (#1) \'\'ret_code\': 0, \'ret_msg\': \'OK\', \'result\': [{\'user_id\': 51101317, \'symbol\': \'BTCUSDT\', \'side\': \'None\', \'size\': 0, \'position_value\': 0, \'entry_price\': 0, \'liq_price\': 0, \'bust_price\': 0, \'leverage\': 1, \'auto_add_margin\': 0, \'is_isolated\': True, \'position_margin\': 0, \'occ_closing_fee\': 0, \'realised_pnl\': -0.1473463, \'cum_realised_pnl\': -0.2546504, \'free_qty\': 0, \'tp_sl_mode\': \'Full\', \'unrealised_pnl\': 0, \'deleverage_indicator\': 0, \'risk_id\': 1, \'stop_loss\': 0, \'take_profit\': 0, \'trailing_stop\': 0, \'position_idx\': 0, \'mode\': \'MergedSingle\'}], \'ext_code\': \'\', \'ext_info\': \'\', \'time_now\': \'1674316840.217231\', \'rate_limit_status\': 119, \'rate_limit\': 120, \'rate_limit_reset_ms\': 1674316840212\''
};
Ich denke, es ist wieder nur so eine kleine Sache... :o
Viele Grüße und besten Dank für einen kleinen Tipp
André
Wie man den von Dir zitierten Fehlermeldungen entnehmen kann, lieferst Du wieder keinen für json2nameValue() gültigen Input.
Problem 1: einfache Anführungszeichen anstatt doppelte
Problem 2: der logische Wert True steht nicht in Anführungszeichen.
Insbesondere zu 2 sei angemerkt, dass das zwar syntaktisch für JSON so korrekt ist, aber die Funktion json2nameValue() damit nicht zurecht kommt.
Beide Probleme lassen sich durch geeignete regex lösen, dann käme am Ende sowas raus:
$VAR1 = {
'ext_info' => '',
'result_1_size' => '0',
'result_1_position_margin' => '0',
'result_1_position_value' => '0',
'result_1_take_profit' => '0',
'result_1_bust_price' => '0',
'result_1_mode' => 'MergedSingle',
'result_1_is_isolated' => 'True',
'result_1_user_id' => '51101317',
'result_1_position_idx' => '0',
'result_1_leverage' => '1',
'rate_limit' => '120',
'result_1_occ_closing_fee' => '0',
'result_1_tp_sl_mode' => 'Full',
'rate_limit_reset_ms' => '1674316840212',
'ret_code' => '0',
'time_now' => '1674316840.217231',
'result_1_unrealised_pnl' => '0',
'result_1_trailing_stop' => '0',
'result_1_realised_pnl' => '-0.1473463',
'result_1_side' => 'None',
'result_1_auto_add_margin' => '0',
'ext_code' => '',
'result_1_stop_loss' => '0',
'result_1_liq_price' => '0',
'rate_limit_status' => '119',
'result_1_symbol' => 'BTCUSDT',
'result_1_free_qty' => '0',
'result_1_entry_price' => '0',
'ret_msg' => 'OK',
'result_1_risk_id' => '1',
'result_1_deleverage_indicator' => '0',
'result_1_cum_realised_pnl' => '-0.2546504'
};
Hallo betateilchen,
vielen Dank für deine Antwort. So wie du mir das geschrieben hast, würde ich aus der Zeile:
my $json = join ("",@input); -> my $json = join ('',@input); machen.
Wäre das zu Punkt 1 schonmal der richtige Weg ?
Bei Punkt zwei muss ich mich echt rein Knien. Habe da schon Ansätze mit der Ausgabe auf https://www.regextester.com/ (https://www.regextester.com/) gemacht.
Habe bis jetzt jedoch immer so eingermaßen mit den HTTPMOD - Regex arbeiten können, also immer normales HTTP Format.
Aber JSON scheint irgendwie anders zu sein.. ::)
VG
regex ist überall gleich - das hat überhaupt nichts mit perl, FHEM oder irgendeinem FHEM Modul zu tun.
Und nein, mit Deinen Änderungen an join() bist Du komplett auf dem Holzweg.
Die Anführungszeichen sind schon in den Quelldaten (Dein json input). Egal, ob man die zeilenweise hat oder per join() zu einer Zeile zusammenbaut.
sub test{
my $text = "{'ret_code': 0, 'ret_msg': 'OK', 'result': [{'user_id': 51101317, 'symbol': 'BTCUSDT', 'side': 'None', 'size': 0, 'position_value': 0, 'entry_price': 0, 'liq_price': 0, 'bust_price': 0, 'leverage': 1, 'auto_add_margin': 0, 'is_isolated': True, 'position_margin': 0, 'occ_closing_fee': 0, 'realised_pnl': -0.1473463, 'cum_realised_pnl': -0.2546504, 'free_qty': 0, 'tp_sl_mode': 'Full', 'unrealised_pnl': 0, 'deleverage_indicator': 0, 'risk_id': 1, 'stop_loss': 0, 'take_profit': 0, 'trailing_stop': 0, 'position_idx': 0, 'mode': 'MergedSingle'}], 'ext_code': '', 'ext_info': '', 'time_now': '1674316840.217231', 'rate_limit_status': 119, 'rate_limit': 120, 'rate_limit_reset_ms': 1674316840212}";
$text =~ s/True/'True'/g;
$text =~ s/False/'False'/g;
$text =~ s/'/"/g;
return Dumper json2nameValue($text);
}
So langsam klickert es.
Ist trotzdem schwer, erstmal die Vorgehensweise heraus zu lesen.
ich habe jetzt folgendes, was dank Dir funktioniert:
sub test{
my ($err,@input) = FileRead({FileName=>'/home/pi/BTCOrderInfoByBit.txt', ForceType=>'file'});
return $err if $err;
my $text = join ("",@input);
$text =~ s/True/'True'/g;
$text =~ s/False/'False'/g;
$text =~ s/'/"/g;
return Dumper json2nameValue($text);
}
Die Sache mit den Regex und dem testen, ist für mich trotzdem schwer. Warum ? Weil ich wahrscheinlich noch durch die $text Zuordnung verwirrt werde.
Ich habe sonst immer nur nach einem Schlüsselwort gesucht. Das hat immer so mit ach und krach funktioniert. Aber hier bin ich noch etwas verwirrt.
Das mit den Zusammenbauen aus dem Quelldaten, das ist mein Hauptproblem :o
Vielen Dank bis hier her...
Zitat von: Stargazer am 21 Januar 2023, 22:29:57
Die Sache mit den Regex und dem testen, ist für mich trotzdem schwer. Warum ? Weil ich wahrscheinlich noch durch die $text Zuordnung verwirrt werde.
Naja, Dein Hauptproblem ist vermutlich eher, dass Du noch nicht so einfach denken kannst, wie es eigentlich in Wirklichkeit ist.
Die Bearbeitung eines Variableninhaltes per regex ist nichts anderes als eine Rechenoperation mit einer Variablen.
my $zahl = 5;
$zahl += 7;
return $zahl;
Dass da 12 als Ergebnis kommt, wird Dich hoffentlich kaum verwundern.
Vergleichen wir das jetzt mit der Anwendung einer regex anstatt einer Addition:
my $text = "{'ret_code': 0, 'is_isolated': True}";
$text =~ s/True/'True'/g;
$text =~ s/False/'False'/g;
$text =~ s/'/"/g;
return $text;
Da kommt als Ergebnis
{"ret_code": 0, "is_isolated": "True"}
raus. Warum?
Der erste Schritt (my $text ...) ist hoffentlich noch klar.
Die nächsten drei Zeilen haben alle die gleiche Aufgabe: Sie sollen
den Inhalt der Variablen $text verändern.
Konkret: Sie sollen im Inhalt der Variablen jeweils etwas anderes ersetzen.
s/<quelle>/<ziel>/g
Eine Standardsyntax einer regex, die man sich mit zwei Eselsbrücken gut merken kann.
- s/ bedeutet suche und ersetze etwas.
- /<quelle>/<ziel>/ bezeichnet WAS (<quelle>) gesucht werden soll und WOMIT (<ziel>) das Gefundene ersetzt werden soll.
- /g bedeutet eigentlich "global", man kann sich das aber auch mit "gierig" merken: das ist der Parameter, der angibt, dass ALLE mit <quelle> gefundenen Stellen im Text ersetzt werden sollen und nicht nur die erste Fundstelle.
Damit solltest Du jetzt verstehen können, was in Deinem Code eigentlich wirklich passiert.
--
Hallo betateilchen,
danke dir für die Erläuterungen. Doch ! Das lichtet schon einmal den dunklen "Regex-Schleier" etwas.
Nun habe ich noch ein kleines anderes Problem, mit den Rechten unter Linux.
Aber dazu mache ich einen anderen Thread auf.
VG
Hallo zusammen,
ich grabe dieses Thema noch einmal aus, da ich ein kleines Problem mit einem anderen JSON - Format habe.
Und zwar hat sich die Quelle der Abfrage geändert. Der Rest ist so geblieben. Es wird immer noch eine Datei ausgelesen, die den JSON - String beinhaltet.
Doch der wird vom Server nicht so ganz so sauber ausgeben. Leider. Es fehlen die Anführungszeichen im String, die der Server zurück gibt. Nur an einer Stelle.
Der String sieht wie folgt aus:
{"code": "00000", "msg": "success", "requestTime": 1728498144036, "data": [{"marginCoin": "USDT", "symbol": "WIFUSDT_UMCBL", "holdSide": "short", "openDelegateCount": "0", "margin": "62.355504233276", "available": "50", "locked": "0", "total": "50", "leverage": 2, "achievedProfits": "-1.251111111201", "averageOpenPrice": "2.478922222222", "marginMode": "fixed", "holdMode": "double_hold", "unrealizedPL": "6.6661111111", "liquidationPrice": "0", "keepMarginRate": "0.0066", "marketPrice": "2.3456", "marginRatio": None, "autoMargin": "off", "cTime": "1728405113909"}]}
Das Problem ist das, dass None am Ende des Strings nicht in Anführungszeichen steht. Darum ergibt die Abfrage auch "json2nameValueErrorText
error parsing (#2) 'None, "autoMargin": "off", "cTime": "1728405113909"'" seitens FHEM. Das ganze wird in dem DOIF - Modul als Readings zurück gegeben, welches auch die Abfrage via Python - Skript startet. Läuft wo anders im meinem System sehr gut. Nur hier macht er Probleme wegen zwei kleinen Anführungszeichen. Füge ich diese Manuell ein, habe ich alle Daten die brauche.
Kann mir jemand einen Tipp geben, wie ich den String richtig geparst bekomme. Theoretisch benötige ich die Daten noch nicht einmal, die ab "marginRatio" ausgegeben werden.
Vielen Dank für eure Mühe...
André
In der Datei das None per regex ersetzen. Im einfachsten Falle durch zwei Anführungszeichen einen leeren String erzeugen.
Hallo betateilchen !
Okay. Das werde ich mal versuchen.
Dankeschön !
https://forum.fhem.de/index.php?topic=139411.0
Vielleicht tut sich was 8)