Android Question Read data from URL into variables

DKHDKH

Member
Licensed User
I get the following data from my energy meter via http://190.160.1.12/restAPI?get=Actual
The data:

{
"Timestamp": "190924184540S"
, "Energy_Delivered": "16021.018"
, "Energy_Returned": "0.000"
, "Gas_Delivered": "2393.86"
, "Energy_Delivered_Tariff1": "9646.286"
, "Energy_Delivered_Tariff2": "6374.731"
, "Energy_Returned_Tariff1": "0.000"
, "Energy_Returned_Tariff2": "0.000"
, "Power_Delivered": "2.892"
, "Power_Returned": "0.000"
, "Voltage_l1": "0.0"
, "Current_l1": "12"
, "Voltage_l2": "0.0"
, "Current_l2": "0"
, "Voltage_l3": "0.0"
, "Current_l3": "0"
, "Power_Delivered_l1": "2892"
, "Power_Returned_l1": "0"
, "Power_Delivered_l2": "0"
, "Power_Returned_l2": "0"
, "Power_Delivered_l3": "0"
, "Power_Returned_l3": "0"
}

I would like to display this data differently. I am unable to write this data in variables.
Many demos and posts viewed and tried. For example:
https://www.b4x.com/android/forum/t...-json-response-from-an-api-web-request.45822/
https://www.b4x.com/android/forum/t...-services-are-now-even-simpler.18992/#content

So now the question to you if someone can help me on my way. Thanks in advance.
Dirk
 

DonManfred

Expert
Licensed User
put the result into the initialize.... replace <text> with you data

B4X:
Dim parser As JSONParser
parser.Initialize(<text>)
Dim root As Map = parser.NextObject
Dim Current_l1 As String = root.Get("Current_l1")
Dim Voltage_l3 As String = root.Get("Voltage_l3")
Dim Power_Returned_l1 As String = root.Get("Power_Returned_l1")
Dim Power_Delivered_l3 As String = root.Get("Power_Delivered_l3")
Dim Energy_Delivered_Tariff1 As String = root.Get("Energy_Delivered_Tariff1")
Dim Energy_Delivered_Tariff2 As String = root.Get("Energy_Delivered_Tariff2")
Dim Current_l3 As String = root.Get("Current_l3")
Dim Power_Delivered_l1 As String = root.Get("Power_Delivered_l1")
Dim Power_Returned_l3 As String = root.Get("Power_Returned_l3")
Dim Current_l2 As String = root.Get("Current_l2")
Dim Power_Delivered_l2 As String = root.Get("Power_Delivered_l2")
Dim Power_Returned_l2 As String = root.Get("Power_Returned_l2")
Dim Energy_Delivered As String = root.Get("Energy_Delivered")
Dim Voltage_l1 As String = root.Get("Voltage_l1")
Dim Timestamp As String = root.Get("Timestamp")
Dim Energy_Returned As String = root.Get("Energy_Returned")
Dim Voltage_l2 As String = root.Get("Voltage_l2")
Dim Energy_Returned_Tariff2 As String = root.Get("Energy_Returned_Tariff2")
Dim Energy_Returned_Tariff1 As String = root.Get("Energy_Returned_Tariff1")
Dim Power_Delivered As String = root.Get("Power_Delivered")
Dim Gas_Delivered As String = root.Get("Gas_Delivered")
Dim Power_Returned As String = root.Get("Power_Returned")
Check http://basic4ppc.com:51042/json/index.html
 

DonManfred

Expert
Licensed User
Use okhttputils2. Search the forum; there are hundrets of similar questions.

Something like

B4X:
    Dim job As HttpJob
    job.Initialize("", Me)
    job.download2("http://190.160.1.12/restAPI", Array As String("get", "Actual"))
    wait for (job) JobDone(job As HttpJob)
    If job.Success Then
        'Log("initkv2 Job.Success = true")
        Dim result As String = job.GetString
        Dim parser As JSONParser
        parser.Initialize(result)
        Dim root As Map = parser.NextObject
        Dim Current_l1 As String = root.Get("Current_l1")
        Dim Voltage_l3 As String = root.Get("Voltage_l3")
        Dim Power_Returned_l1 As String = root.Get("Power_Returned_l1")
        Dim Power_Delivered_l3 As String = root.Get("Power_Delivered_l3")
        Dim Energy_Delivered_Tariff1 As String = root.Get("Energy_Delivered_Tariff1")
        Dim Energy_Delivered_Tariff2 As String = root.Get("Energy_Delivered_Tariff2")
        Dim Current_l3 As String = root.Get("Current_l3")
        Dim Power_Delivered_l1 As String = root.Get("Power_Delivered_l1")
        Dim Power_Returned_l3 As String = root.Get("Power_Returned_l3")
        Dim Current_l2 As String = root.Get("Current_l2")
        Dim Power_Delivered_l2 As String = root.Get("Power_Delivered_l2")
        Dim Power_Returned_l2 As String = root.Get("Power_Returned_l2")
        Dim Energy_Delivered As String = root.Get("Energy_Delivered")
        Dim Voltage_l1 As String = root.Get("Voltage_l1")
        Dim Timestamp As String = root.Get("Timestamp")
        Dim Energy_Returned As String = root.Get("Energy_Returned")
        Dim Voltage_l2 As String = root.Get("Voltage_l2")
        Dim Energy_Returned_Tariff2 As String = root.Get("Energy_Returned_Tariff2")
        Dim Energy_Returned_Tariff1 As String = root.Get("Energy_Returned_Tariff1")
        Dim Power_Delivered As String = root.Get("Power_Delivered")
        Dim Gas_Delivered As String = root.Get("Gas_Delivered")
        Dim Power_Returned As String = root.Get("Power_Returned")
    Else
        Log("Error: "&job.ErrorMessage)
    End If
    job.Release
 
Last edited:

DKHDKH

Member
Licensed User
Thank you. I have seen what I am doing wrong in the line job.download2("http://190.160.1.12/restAPI?get=Actual", Array As String("get", "Actual"))

That array setting was false with me.

I now only get the error message:

ResponseError. Reason: java.io.IOException: unexpected end of stream on okhttp3.Address@ec19b5f6, Response:

I will see the explanation about okhttputils2 from Erel tomorrow. Maybe I see the error there.
 

DKHDKH

Member
Licensed User
Thanks. I now get the data in the variables. I do get an error message during the command:
wait for (job) JobDone (job As HttpJob)
The program simply continues. See the error message only through the log.
Also, the Sub JobDone is never visited. I have now placed the parsing immediately after wait for (job) JobDone (job As HttpJob) and everything works perfectly.
My incoming data may not be fully compatible.
 

DKHDKH

Member
Licensed User
I get the following error:

ResponseError. Reason: java.net.SocketException: failed to connect to /190.160.1.12 (port 80) after 30000ms: isConnected failed: EHOSTUNREACH (No route to host), Response:

I use B4a version 9.50
 

DonManfred

Expert
Licensed User
ResponseError. Reason: java.net.SocketException: failed to connect to /190.160.1.12 (port 80) after 30000ms: isConnected failed: EHOSTUNREACH (No route to host), Response:
make sure that your device is connected via wifi with the same network.
Also make sure your firewall/router is accepting connecting to this host. Looks like a network issue.

failed to connect to /190.160.1.12
are you using a http url? http:\\190.160.1.12 ??

Post your updated code you are using.

Can you get the result when you call the url in your pc browser?
 

DKHDKH

Member
Licensed User
But why do I get the data neatly in the variables?
I use your program above.

From the browser I become:

{
"Timestamp":"190925142748S"
,"Energy_Delivered":"16034.248"
,"Energy_Returned":"0.000"
,"Gas_Delivered":"2393.86"
,"Energy_Delivered_Tariff1":"9652.238"
,"Energy_Delivered_Tariff2":"6382.010"
,"Energy_Returned_Tariff1":"0.000"
,"Energy_Returned_Tariff2":"0.000"
,"Power_Delivered":"0.471"
,"Power_Returned":"0.000"
,"Voltage_l1":"0.0"
,"Current_l1":"2"
,"Voltage_l2":"0.0"
,"Current_l2":"0"
,"Voltage_l3":"0.0"
,"Current_l3":"0"
,"Power_Delivered_l1":"489"
,"Power_Returned_l1":"0"
,"Power_Delivered_l2":"0"
,"Power_Returned_l2":"0"
,"Power_Delivered_l3":"0"
,"Power_Returned_l3":"0"
}
 

DKHDKH

Member
Licensed User
B4X:
#Region Project Attributes
#ApplicationLabel: Voorbeeld4
#VersionCode: 1
#VersionName:
'SupportedOrientations possible values: unspecified, landscape or portrait.
#SupportedOrientations: unspecified
#CanInstallToExternalStorage: False
#BridgeLogger: True
#End Region

#Region Activity Attributes
#FullScreen: False
#IncludeTitle: True
#End Region

Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.

End Sub

Sub Globals
'These global variables will be redeclared each time the activity is created.
'These variables can only be accessed from this module.

Private lblGas_Delivered As Label
Private lblEnergy_Delivered_Tariff1 As Label
Private lblEnergy_Delivered_Tariff2 As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
'Do not forget to load the layout file created with the visual designer. For example:
Activity.LoadLayout("Main")

Dim job As HttpJob
job.Initialize("",Me)

job.download2("http://190.160.1.12/restAPI?get=Actual", Array As String("get", "Actual"))

wait for (job) JobDone(job As HttpJob)
Log("VOOR job.GetString")
Log(job.GetString)
Log("NA job.GetString. Nu de parser in.")

Dim result As String = job.GetString
Dim parser As JSONParser
parser.Initialize(result)
Dim root As Map = parser.NextObject
Dim Current_l1 As String = root.Get("Current_l1")
Dim Voltage_l3 As String = root.Get("Voltage_l3")
Dim Power_Returned_l1 As String = root.Get("Power_Returned_l1")
Dim Power_Delivered_l3 As String = root.Get("Power_Delivered_l3")
Dim Energy_Delivered_Tariff1 As String = root.Get("Energy_Delivered_Tariff1")
Dim Energy_Delivered_Tariff2 As String = root.Get("Energy_Delivered_Tariff2")
Dim Current_l3 As String = root.Get("Current_l3")
Dim Power_Delivered_l1 As String = root.Get("Power_Delivered_l1")
Dim Power_Returned_l3 As String = root.Get("Power_Returned_l3")
Dim Current_l2 As String = root.Get("Current_l2")
Dim Power_Delivered_l2 As String = root.Get("Power_Delivered_l2")
Dim Power_Returned_l2 As String = root.Get("Power_Returned_l2")
Dim Energy_Delivered As String = root.Get("Energy_Delivered")
Dim Voltage_l1 As String = root.Get("Voltage_l1")
Dim Timestamp As String = root.Get("Timestamp")
Dim Energy_Returned As String = root.Get("Energy_Returned")
Dim Voltage_l2 As String = root.Get("Voltage_l2")
Dim Energy_Returned_Tariff2 As String = root.Get("Energy_Returned_Tariff2")
Dim Energy_Returned_Tariff1 As String = root.Get("Energy_Returned_Tariff1")
Dim Power_Delivered As String = root.Get("Power_Delivered")
Dim Gas_Delivered As String = root.Get("Gas_Delivered")
Dim Power_Returned As String = root.Get("Power_Returned")

lblGas_Delivered.Text = Gas_Delivered
lblEnergy_Delivered_Tariff1.Text = Energy_Delivered_Tariff1
lblEnergy_Delivered_Tariff2.Text = Energy_Delivered_Tariff2

Log(Gas_Delivered)


End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub JobDone (Job As HttpJob)
Log("JobName = " & Job.JobName & ", Success = " & Job.Success)
If Job.Success Then
Log("Het is een groot SUCCES")
' 'Log("initkv2 Job.Success = true")
' Dim result As String = Job.GetString
' Dim parser As JSONParser
' parser.Initialize(result)
' Dim root As Map = parser.NextObject
' Dim Current_l1 As String = root.Get("Current_l1")
' Dim Voltage_l3 As String = root.Get("Voltage_l3")
' Dim Power_Returned_l1 As String = root.Get("Power_Returned_l1")
' Dim Power_Delivered_l3 As String = root.Get("Power_Delivered_l3")
' Dim Energy_Delivered_Tariff1 As String = root.Get("Energy_Delivered_Tariff1")
' Dim Energy_Delivered_Tariff2 As String = root.Get("Energy_Delivered_Tariff2")
' Dim Current_l3 As String = root.Get("Current_l3")
' Dim Power_Delivered_l1 As String = root.Get("Power_Delivered_l1")
' Dim Power_Returned_l3 As String = root.Get("Power_Returned_l3")
' Dim Current_l2 As String = root.Get("Current_l2")
' Dim Power_Delivered_l2 As String = root.Get("Power_Delivered_l2")
' Dim Power_Returned_l2 As String = root.Get("Power_Returned_l2")
' Dim Energy_Delivered As String = root.Get("Energy_Delivered")
' Dim Voltage_l1 As String = root.Get("Voltage_l1")
' Dim Timestamp As String = root.Get("Timestamp")
' Dim Energy_Returned As String = root.Get("Energy_Returned")
' Dim Voltage_l2 As String = root.Get("Voltage_l2")
' Dim Energy_Returned_Tariff2 As String = root.Get("Energy_Returned_Tariff2")
' Dim Energy_Returned_Tariff1 As String = root.Get("Energy_Returned_Tariff1")
' Dim Power_Delivered As String = root.Get("Power_Delivered")
' Dim Gas_Delivered As String = root.Get("Gas_Delivered")
' Dim Power_Returned As String = root.Get("Power_Returned")
Else
Log("Error: "&Job.ErrorMessage)
End If
Job.Release
End Sub
 
Last edited:

emexes

Well-Known Member
Licensed User
But why do I get the data neatly in the variables? I use your program above. From the browser I become:

{
"Timestamp":"190925142748S"
,"Energy_Delivered":"16034.248"
,"Energy_Returned":"0.000"
,"Gas_Delivered":"2393.86"
...
Do you get the same JSON data from your program at:
B4X:
Log(job.GetString)
?
 

DKHDKH

Member
Licensed User
This is what I see in the Log:

Logger connected to: samsung GT-P3100
--------- beginning of /dev/log/main
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
ResponseError. Reason: java.net.SocketException: failed to connect to /190.160.1.12 (port 80) after 30000ms: isConnected failed: EHOSTUNREACH (No route to host), Response:
VOOR job.GetString

{
"Timestamp":"190924205642S"
,"Energy_Delivered":"16022.729"
,"Energy_Returned":"0.000"
,"Gas_Delivered":"2393.86"
,"Energy_Delivered_Tariff1":"9646.286"
,"Energy_Delivered_Tariff2":"6376.442"
,"Energy_Returned_Tariff1":"0.000"
,"Energy_Returned_Tariff2":"0.000"
,"Power_Delivered":"0.714"
,"Power_Returned":"0.000"
,"Voltage_l1":"0.0"
,"Current_l1":"3"
,"Voltage_l2":"0.0"
,"Current_l2":"0"
,"Voltage_l3":"0.0"
,"Current_l3":"0"
,"Power_Delivered_l1":"714"
,"Power_Returned_l1":"0"
,"Power_Delivered_l2":"0"
,"Power_Returned_l2":"0"
,"Power_Delivered_l3":"0"
,"Power_Returned_l3":"0"
}
NA job.GetString. Nu de parser in.
2393.86
KLAAR met parser.
** Activity (main) Pause, UserClosed = false **
 

DonManfred

Expert
Licensed User
job.download2("http://190.160.1.12/restAPI?get=Actual", Array As String("get", "Actual"))
The host is not reachable if i try it in my PC browser. As it does not work i expect it does not work in Android too.

Check your firewall/router settings and adapt them so that the host (your server running the restApi) is reachable.
 

DKHDKH

Member
Licensed User
I became now the next log with another error:

** Activity (main) Pause, UserClosed = true **
** Activity (main) Create, isFirst = false **
** Activity (main) Resume **
ResponseError. Reason: java.io.IOException: unexpected end of stream on okhttp3.Address@2cad87de, Response:
job.Success = false
result = [{
"Timestamp":"190924205731S"
,"Energy_Delivered":"16022.737"
,"Energy_Returned":"0.000"
,"Gas_Delivered":"2393.86"
,"Energy_Delivered_Tariff1":"9646.286"
,"Energy_Delivered_Tariff2":"6376.451"
,"Energy_Returned_Tariff1":"0.000"
,"Energy_Returned_Tariff2":"0.000"
,"Power_Delivered":"0.700"
,"Power_Returned":"0.000"
,"Voltage_l1":"0.0"
,"Current_l1":"3"
,"Voltage_l2":"0.0"
,"Current_l2":"0"
,"Voltage_l3":"0.0"
,"Current_l3":"0"
,"Power_Delivered_l1":"699"
,"Power_Returned_l1":"0"
,"Power_Delivered_l2":"0"
,"Power_Returned_l2":"0"
,"Power_Delivered_l3":"0"
,"Power_Returned_l3":"0"
}
]
VOOR job.GetString

{
"Timestamp":"190924205731S"
,"Energy_Delivered":"16022.737"
,"Energy_Returned":"0.000"
,"Gas_Delivered":"2393.86"
,"Energy_Delivered_Tariff1":"9646.286"
,"Energy_Delivered_Tariff2":"6376.451"
,"Energy_Returned_Tariff1":"0.000"
,"Energy_Returned_Tariff2":"0.000"
,"Power_Delivered":"0.700"
,"Power_Returned":"0.000"
,"Voltage_l1":"0.0"
,"Current_l1":"3"
,"Voltage_l2":"0.0"
,"Current_l2":"0"
,"Voltage_l3":"0.0"
,"Current_l3":"0"
,"Power_Delivered_l1":"699"
,"Power_Returned_l1":"0"
,"Power_Delivered_l2":"0"
,"Power_Returned_l2":"0"
,"Power_Delivered_l3":"0"
,"Power_Returned_l3":"0"
}
NA job.GetString. Nu de parser in.
2393.86
KLAAR met parser.
 

emexes

Well-Known Member
Licensed User
This is what I see in the Log:
That looks good. The only difference I can see is that the JSON data shown in the log is preceded by a blank line or two. But I checked in B4J and the JSON parser copes ok with leading blank lines, and the Log(Gas_Delivered) is showing the same value as received in the JSON data, so that all looks good.

The only mystery wrt JSON decoding now is what happened to the "If job.Success" check from Manfred's example:
B4X:
Dim job As HttpJob
job.Initialize("", Me)
job.Download2("http://190.160.1.12/restAPI", Array As String("get", "Actual"))
Wait For (job) JobDone(job As HttpJob)
If job.Success Then
        'Log("initkv2 Job.Success = true")
        Dim result As String = job.GetString
        Dim parser As JSONParser
        parser.Initialize(result)
 

emexes

Well-Known Member
Licensed User
ResponseError. Reason: java.io.IOException: unexpected end of stream on okhttp3.Address@2cad87de, Response:
job.Success = false
result = [{
"Timestamp":"190924205731S"
,"Energy_Delivered":"16022.737"
,"Energy_Returned":"0.000"
...
Righto, now I understand ;-) The JSON decoding issue is resolved, and the question now is:

what is that java.io.IOException error?

although happily you are still getting the JSON meter reading, even though job.Success = false. Bonus :)
 

emexes

Well-Known Member
Licensed User
what is that java.io.IOException error?
This is clutching at straws, but... what happens if you add a delay (and Log) after the Wait For, eg:
B4X:
Dim job As HttpJob
job.Initialize("", Me)
job.Download2("http://190.160.1.12/restAPI", Array As String("get", "Actual"))
Wait For (job) JobDone(job As HttpJob)
Sleep(100)                             'add this
Log("job.Success = " & job.Success)    'and this
 
Top