ow ja klopt moet response staan inplaats van type ik heb wat gestoeid er mee maar als er response staat krijg ik deze foutmelding
ow ja klopt moet response staan inplaats van type ik heb wat gestoeid er mee maar als er response staat krijg ik deze foutmelding
Zonder code kunnen we natuurlijk niet zien wat er mis gaat.
Maar om even bij de code van de eerste pagina te blijven is hier de oplossing om de json weer naar een stringgrid te zetten.
Ditmaal bevat de response dus geen array met de naam switches maar is de response zelf een array.
De testdata2.json:
Json Code:
{ "status": "ok", "version": "3.38", "request": { "route": "/el" }, "response": [{ "type": "electricity", "tariff": 1, "consumed": 5505.239, "produced": 0.001 }, { "type": "electricity", "tariff ": 2, "consumed": 5563.550, "produced": 0.001 }, { "type": "gas", "consumed": 5564.793, "timestamp": 1498086000 }] }
Delphi Code:
uses System.JSON; function LoadFileToStr(const FileName: TFileName): String; var FileStream: TFileStream; Bytes: TBytes; begin Result := ''; FileStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); try if FileStream.Size > 0 then begin SetLength(Bytes, FileStream.Size); FileStream.Read(Bytes[0], FileStream.Size); end; Result := TEncoding.ASCII.GetString(Bytes); finally FileStream.Free; end; end; procedure AutoSizeCol(Grid: TStringGrid; Column: integer); var i, W, WMax: integer; begin WMax := 0; for i := 0 to Grid.RowCount - 1 do begin W := Grid.Canvas.TextWidth(Grid.Cells[Column, i]); if W > WMax then WMax := W; end; Grid.ColWidths[Column] := WMax + 15; end; procedure TForm9.Button1Click(Sender: TObject); var JsonString: String; jsv: TJsonValue; jsResponse: TJsonPair; jsSwitches: TJsonPair; jsArr: TJsonArray; jso: TJsonObject; jsPair: TJsonPair; i, j: integer; begin JsonString := LoadFileToStr('c:\temp\testdata2.json'); jsv := TJsonObject.ParseJSONValue(JsonString); try if jsv = nil then raise Exception.Create('error in json'); jsResponse := (jsv as TJsonObject).Get('response'); if jsResponse = nil then raise Exception.Create('no response in json'); // in dit geval is response de array dus moeten we jsResponse naar een TJsonArray casten jsArr := jsResponse.JsonValue as TJsonArray; StringGrid1.RowCount := jsArr.Count + 1; StringGrid1.ColCount := 1; for i := 0 to jsArr.Count - 1 do begin jso := jsArr.Items[i] as TJsonObject; for jsPair in jso do begin j := StringGrid1.Rows[0].IndexOf(jsPair.JsonString.Value); if j < 0 then begin // kolom toevoegen if StringGrid1.Cells[StringGrid1.ColCount - 1, 0] <> '' then StringGrid1.ColCount := StringGrid1.ColCount + 1; j := StringGrid1.ColCount - 1; StringGrid1.Cells[j, 0] := jsPair.JsonString.Value; end; StringGrid1.Cells[j, i + 1] := jsPair.JsonValue.Value; end; end; for i := 0 to StringGrid1.ColCount - 1 do AutoSizeCol(StringGrid1, i); finally jsv.Free(); end; end;
Resultaat:
Harstikke bedankt ik heb de code van mij bewerkt en het werkt nu maar nu zit ik weer met een ander probleem:
ik wil de energy link uit lezen maar hij pakt niet alles waarom moet dat json zo omslachtig allemaal maar dat zal wel aan mij liggen
json: hij leest dit uit:
het rode gedeelte leest hij maar half uit dus niet de waarde{"status": "ok", "version": "3.38", "request": {"route": "/get-status" }, "response": {"preset":0,"time":"2017-06-23 22:14","switches":[{"id":0,"type":"switch","status":"on"},{"id":1,"ty pe":"switch","status":"off"},{"id":2,"type":"dimme r","status":"off","dimlevel":0},{"id":3,"type":"sw itch","status":"on"},{"id":4,"type":"switch","stat us":"off"},{"id":5,"type":"switch","status":"on"}, {"id":6,"type":"switch","status":"on"},{"id":7,"ty pe":"dimmer","status":"on","dimlevel":100},{"id":8 ,"type":"switch","status":"off"},{"id":9,"type":"s witch","status":"on"},{"id":10,"type":"switch","st atus":"on"},{"id":11,"type":"dimmer","status":"off ","dimlevel":0},{"id":15,"type":"switch","status": "on"},{"id":16,"type":"virtual"},{"id":17,"type":" virtual"},{"id":18,"type":"switch","status":"off"} ,{"id":19,"type":"dimmer","status":"off","dimlevel ":0},{"id":20,"type":"switch","status":"on"},{"id" :21,"type":"switch","status":"off"},{"id":22,"type ":"switch","status":"off"}],"uvmeters":[],"windmeters":[],"rainmeters":[],"thermometers":[{"id":0,"te":25.5,"hu":46,"favorite":"no"}],"weatherdisplays":[], "energymeters": [], "energylinks": [{"id":0,"tariff":1,"s1":{"po":0,"dayTotal":592.00, "po+":14,"po+t":"10:46","po-":0,"po-t":"00:01"},"s2":null,"aggregate":{"po":570,"dayTo tal":11.47,"po+":2560,"po+t":"06:58","po-":200,"po-t":"02:01"},"used":{"po":570,"dayTotal":11.38,"po+ ":2560,"po+t":"06:58","po-":200,"po-t":"02:01"},"gas":{"lastHour":0.00,"dayTotal":0.68 },"kwhindex":0.00}], "heatlinks": [{"id": 0, "pump": "off", "heating": "off", "dhw": "off", "rte": 25.500, "rsp": 5.000, "tte": 5.000, "ttm": null, "wp": 1.597, "wte": 43.000, "ofc": 0, "odc": 0}], "kakusensors": [{"id":0,"status":"no","timestamp":"17:56"},{"id":1 ,"status":"no","timestamp":"21:42"},{"id":2,"statu s":null,"timestamp":"00:00"},{"id":3,"status":"no" ,"timestamp":"16:31"},{"id":4,"status":"no","times tamp":"22:11"},{"id":5,"status":"yes","timestamp": "22:11"},{"id":6,"status":null,"timestamp":"00:00" },{"id":7,"status":null,"timestamp":"00:00"},{"id" :8,"status":null,"timestamp":"00:00"},{"id":9,"sta tus":"yes","timestamp":"05:45"}]}}
energylinks is ook weer een json-array.
Maar zonder code kunnen we natuurlijk niet zeggen wat er bij jou verkeerd gaat.
code:
Delphi Code:
Var JsonString: String; jsv: TJsonValue; jsResponse: TJsonPair; jsSwitches: TJsonPair; jstype: TJsonPair; jste: TJsonPair; jsArr: TJsonArray; jso: TJsonObject; jsPair: TJsonPair; i, j: integer; ms:TMemoryStream; begin Energygrid2.ClearColumns; JsonString := loadfiletostr('status.json'); jsv := TJsonObject.ParseJSONValue(JsonString); try jsResponse := (jsv as TJsonObject).Get('response'); jsSwitches := (jsResponse.JsonValue as TJsonObject).Get('energylinks'); jsArr := jsSwitches.JsonValue as TJsonArray; Energygrid2.RowCount := jsArr.Count; while Energygrid2.ColumnCount > 1 do Energygrid2.Columns[0].DisposeOf; for i := 0 to jsArr.Count - 1 do begin jso := jsArr.Items[i] as TJsonObject; for jsPair in jso do begin j := 0; while (j < Energygrid2.ColumnCount) and (Energygrid2.Columns[j].Header <> jsPair.JsonString.Value) do Inc(j); if (j >= Energygrid2.ColumnCount) then begin Energygrid2.AddObject(TStringColumn.Create(Self)); Energygrid2.Columns[j].Header := jsPair.JsonString.Value; end; Energygrid2.Cells[j, i] := jsPair.JsonValue.Value;
Last edited by GolezTrol; 25-Jun-17 at 01:50.
En wat is dan het probleem. Ik zie in jouw screenshot wel de gegevens staan die jij rood gemarkeerd had.
Ik zie id=0, tariff=1, s1=leeg omdat het multiple values heeft, s2=null
Dus wat is het probleem?
Als jij de waardes in s1 wilt weergeven dan zul je die ook weer "af moeten lopen". s1 is geen enkele key met een waarde maar bevat ook weer meerdere waardes. Idem met aggregate, used en gas.
Dus je moet iets in gaan bouwen van:
Delphi Code:
if jsPair.JsonString.Value = 's1' then begin // en hier weer een loop maken die de jsPair als TJsonObject cast naar jsPair_s1 // en met "for jsPair_s1 in jso_s1 do" alle waardes doorloopt. end;
Hieronder weer even de json mooi neergezet zodat het wat duidelijker is:
JSON Code:
{ "status": "ok", "version": "3.38", "request": { "route": "/get-status" }, "response": { "preset": 0, "time": "2017-06-23 22:14", "switches": [ { "id": 0, "type": "switch", "status": "on" }, { "id": 1, "ty pe": "switch", "status": "off" }, { "id": 2, "type": "dimme r", "status": "off", "dimlevel": 0 }, { "id": 3, "type": "sw itch", "status": "on" }, { "id": 4, "type": "switch", "stat us": "off" }, { "id": 5, "type": "switch", "status": "on" }, { "id": 6, "type": "switch", "status": "on" }, { "id": 7, "ty pe": "dimmer", "status": "on", "dimlevel": 100 }, { "id": 8, "type": "switch", "status": "off" }, { "id": 9, "type": "s witch", "status": "on" }, { "id": 10, "type": "switch", "st atus": "on" }, { "id": 11, "type": "dimmer", "status": "off ", "dimlevel": 0 }, { "id": 15, "type": "switch", "status": "on" }, { "id": 16, "type": "virtual" }, { "id": 17, "type": " virtual" }, { "id": 18, "type": "switch", "status": "off" }, { "id": 19, "type": "dimmer", "status": "off", "dimlevel ": 0 }, { "id": 20, "type": "switch", "status": "on" }, { "id": 21, "type": "switch", "status": "off" }, { "id": 22, "type ": "switch", "status": "off" } ], "uvmeters": [], "windmeters": [], "rainmeters": [], "thermometers": [ { "id": 0, "te": 25.5, "hu": 46, "favorite": "no" } ], "weatherdisplays": [], "energymeters": [], "energylinks": [ { "id": 0, "tariff": 1, "s1": { "po": 0, "dayTotal": 592, "po+": 14, "po+t": "10:46", "po-": 0, "po-t": "00:01" }, "s2": null, "aggregate": { "po": 570, "dayTo tal": 11.47, "po+": 2560, "po+t": "06:58", "po-": 200, "po-t": "02:01" }, "used": { "po": 570, "dayTotal": 11.38, "po+ ": 2560, "po+t": "06:58", "po-": 200, "po-t": "02:01" }, "gas": { "lastHour": 0, "dayTotal": 0.68 }, "kwhindex": 0 } ], "heatlinks": [ { "id": 0, "pump": "off", "heating": "off", "dhw": "off", "rte": 25.5, "rsp": 5, "tte": 5, "ttm": null, "wp": 1.597, "wte": 43, "ofc": 0, "odc": 0 } ], "kakusensors": [ { "id": 0, "status": "no", "timestamp": "17:56" }, { "id": 1, "status": "no", "timestamp": "21:42" }, { "id": 2, "statu s": null, "timestamp": "00:00" }, { "id": 3, "status": "no", "timestamp": "16:31" }, { "id": 4, "status": "no", "times tamp": "22:11" }, { "id": 5, "status": "yes", "timestamp": "22:11" }, { "id": 6, "status": null, "timestamp": "00:00" }, { "id": 7, "status": null, "timestamp": "00:00" }, { "id": 8, "status": null, "timestamp": "00:00" }, { "id": 9, "sta tus": "yes", "timestamp": "05:45" } ] } }
oké,
en hebt u daar een voorbeeld van?
Last edited by GolezTrol; 25-Jun-17 at 01:51.
Bedoel je of ik de complete code daarvoor wil schrijven?
Ik gaf al aan hoe het ongeveer moet.
delphi Code:
if jsPair.JsonString.Value = 's1' then begin // en hier weer een loop maken die de jsPair als TJsonObject cast naar jsPair_s1 // en met "for jsPair_s1 in jso_s1 do" alle waardes doorloopt. end;
Verder zou dan ook de vraag zijn welke waarde uit s1 en e.v. s2 je zou willen hebben (of allemaal). Maar met alle waarde hem je weer kans dat het niet in de breedte van je stringgrid/beeldscherm past.
Ik zat weer even achter de computer en zal je laten zien hoe je subkeys uit zou moeten lezen.
Je ziet dat s1, aggregate e.d. ook weer subkeys heeft. Dus je moet controleren binnen je loop of je te maken hebt met één enkele waarde of met een key met multiple waarden. Dit doe je door te controleren of jsPair.JsonValue een TJSONObject is.
Hier heb ik code die een memo vult.
(zie de code "hier wordt het dus interessant" wat ik bedoel)
Delphi Code:
procedure TForm1.Button1Click(Sender: TObject); var JsonString: String; jsv: TJsonValue; jsResponse: TJsonPair; jsEnergyLinks: TJsonPair; jsArr: TJsonArray; jso: TJsonObject; jsPair: TJsonPair; jso2: TJsonObject; jsPair2: TJsonPair; i: integer; begin JsonString := LoadFileToStr('c:\temp\testdata3.json'); jsv := TJsonObject.ParseJSONValue(JsonString); try if jsv = nil then raise Exception.Create('error in json'); jsResponse := (jsv as TJsonObject).Get('response'); if jsResponse = nil then raise Exception.Create('no response in json'); jsEnergyLinks := (jsResponse.JsonValue as TJsonObject).Get('energylinks'); if jsEnergyLinks = nil then raise Exception.Create('no energylinks in json'); // in dit geval is response de array dus moeten we jsResponse naar een TJsonArray casten jsArr := jsEnergyLinks.JsonValue as TJsonArray; for i := 0 to jsArr.Count - 1 do // in geval van energylinks is dit er maar 1 begin jso := jsArr.Items[i] as TJsonObject; for jsPair in jso do begin Memo1.Lines.Add(jsPair.JsonString.Value + ' = ' + jsPair.JsonValue.Value); // =================== // hier wordt het dus interessant // =================== if jsPair.JsonValue is TJSONObject then // is het een object met meerdere keys ? begin jso2 := jsPair.JsonValue as TJsonObject; // loop dan ook al die keys weer door for jsPair2 in jso2 do begin Memo1.Lines.Add(jsPair.JsonString.Value + '.' + jsPair2.JsonString.Value + ' = ' + jsPair2.JsonValue.Value); end; end; // =================== end; end; finally jsv.Free(); end; end;
Geeft dit als resultaat.
Ik neem aan dat je dit zelf wel weer in een stringgrid of andere vorm kunt gieten.Code:id = 0 tariff = 1 s1 = s1.po = 0 s1.dayTotal = 592 s1.po+ = 14 s1.po+t = 10:46 s1.po- = 0 s1.po-t = 00:01 s2 = null aggregate = aggregate.po = 570 aggregate.dayTo tal = 11,47 aggregate.po+ = 2560 aggregate.po+t = 06:58 aggregate.po- = 200 aggregate.po-t = 02:01 used = used.po = 570 used.dayTotal = 11,38 used.po+ = 2560 used.po+t = 06:58 used.po- = 200 used.po-t = 02:01 gas = gas.lastHour = 0 gas.dayTotal = 0,68 kwhindex = 0
Harstikke bedankt ik ga eens klooien met de code als ik er wat van kan maken. heb het de vorige keer ook gedaan toen is het mij gelukt
nogmaals harstikke bedankt.
Last edited by GolezTrol; 25-Jun-17 at 01:51.
Je hoeft niet het hele bericht te citeren als je antwoord geeft, zeker niet met die lappen code van rvk.
1+1=b
There are currently 1 users browsing this thread. (0 members and 1 guests)
Bookmarks