iOS Question httpJob GET events

Status
Not open for further replies.

alizeti

Member
Licensed User
I'm having issues with the httpJob library

I have no problems in reading variables from the cloud using GET and call function from the cloud using POST.

The problem is when I want to get EVENTS from the cloud. Can’t make it work.
I use the same function as for reading variable (GET) but it doesn’t work.

This is what I send using the GET :
http = "https://api.particle.io/v1/devices/DEVICE_ID/events?access_token=MY_TOKEN"
jobGet.Download(http)

From Particle io reference documentation :
Definition
GET /v1/events/:eventPrefix

Example request :
curl "https://api.particle.io/v1/events/temp?access_token=1234"

Example Response:
GET /v1/events/temp
HTTP/1.1 200 OK
:eek:k

event: temperature
data: {"data":"25.34","ttl":"60","published_at":"2015-07-18T00:12:18.174Z","coreid":"0123456789abcdef01234567"}


If I do it on terminal, it works.
On B4I, i doen't work.

Any idea?

If I execute the exact same command on my windows terminal, it works. I see my event when it occurs.
 

alizeti

Member
Licensed User
What happens when it doesn't work? What is the error message?

Nothing happens!! No error message! When I generate the event on the particle module, I just don’t receive anything on the app!!

If I go on terminal and start listening for events, it works!!!!
 
Upvote 0

alizeti

Member
Licensed User
I was not shouting.

This is the code when I start the listening of an event from the device
B4X:
http = "https://api.particle.io/v1/devices/MY_DEVICE_ID/events?access_token=MY_TOKEN"

jobGet.Download(http)

This is the JobDone event :

B4X:
Sub JobDone (Job As HttpJob)
    Log("JobName = " & Job.JobName & ", Success = " & Job.Success)
   
    If Job.Success = True Then
        Select Job.JobName
            Case "jobGet"
                Log(Job.GetString)
                cloudRx = Job.GetString
            Case "jobPost"
                Log(Job.GetString)
                cloudRx = Job.GetString
                'could check for error code to see if command was successfull
        End Select
       
        updateState
    Else
        Log("Error: " & Job.ErrorMessage)
        'mess'messagePToastMessageShow("Error: " & Job.ErrorMessage, True)
    End If
    Job.Release
End Sub


If I go on a terminal and I send the same command, there is a response from the cloud like this
":eek:k"

Then he is ready to get any events trigger by the device on the cloud
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Show the complete code that you use to set up your jobGet variable/object and the JobDone routine. Both should be in the same code module. Right now we just have fragments and the issue may lay in what you are not posting here.
 
Upvote 0

alizeti

Member
Licensed User
Here is the code :


B4X:
Sub Process_Globals
    'These global variables will be ghdeclared once when the application starts.
    'Public variables can be accessed from all modules.
    Public App As Application
    Public NavControl As NavigationController
    Private Page1, Page2, Page3, Page4, Page5 As Page
    
    Private jobGet, jobPost As HttpJob
    Private dataLog As Phone 'to save data
    Private result As String
    Dim messagePopup As HUD
    Dim manControlFlag As Boolean
    
    'timer
    Dim valveUpdateTimer As Timer
    
    'page 1
    Private p1NameZone1 As Label
    Private p1NameZone2 As Label
    Private p1NameZone3 As Label
    Private p1NameZone4 As Label
    Private p1NameZone5 As Label
    Private p1NameZone6 As Label
    Private p1NameZone7 As Label
    Private p1NameZone8 As Label
    Private manCtrlZone1 As SegmentedControl
    Private manCtrlZone2 As SegmentedControl
    Private manCtrlZone3 As SegmentedControl
    Private manCtrlZone4 As SegmentedControl
    Private manCtrlZone5 As SegmentedControl
    Private manCtrlZone6 As SegmentedControl
    Private manCtrlZone7 As SegmentedControl
    Private manCtrlZone8 As SegmentedControl
    Private controlMode As SegmentedControl
    
    'page 2
    Private irrigationStartTime As Picker
    Private irrigTimeInMin As TextField
    
    Private zoneCkbox1 As Panel
    Private zoneCkbox2 As Panel
    Private zoneCkbox3 As Panel
    Private zoneCkbox4 As Panel
    Private zoneCkbox5 As Panel
    Private zoneCkbox6 As Panel
    Private zoneCkbox7 As Panel
    Private zCkbox1 As clsCheckBox
    Private zCkbox2 As clsCheckBox
    Private zCkbox3 As clsCheckBox
    Private zCkbox4 As clsCheckBox
    Private zCkbox5 As clsCheckBox
    Private zCkbox6 As clsCheckBox
    Private zCkbox7 As clsCheckBox
    
    Private pnlCkbox1 As Panel
    Private pnlCkbox2 As Panel
    Private pnlCkbox3 As Panel
    Private pnlCkbox4 As Panel
    Private pnlCkbox5 As Panel
    Private pnlCkbox6 As Panel
    Private pnlCkbox7 As Panel
    Private dCkbox1 As clsCheckBox
    Private dCkbox2 As clsCheckBox
    Private dCkbox3 As clsCheckBox
    Private dCkbox4 As clsCheckBox
    Private dCkbox5 As clsCheckBox
    Private dCkbox6 As clsCheckBox
    Private dCkbox7 As clsCheckBox
    
    'page 3
    Private zoneName1 As TextField
    Private zoneName2 As TextField
    Private zoneName3 As TextField
    Private zoneName4 As TextField
    Private zoneName5 As TextField
    Private zoneName6 As TextField
    Private zoneName7 As TextField
    Private zoneName8 As TextField
    
    'page 4
    'to be saved
    Private user As TextField
    Private password As TextField
    Private deviceName As String
    Private deviceList As Picker
    Private status As Label
    Private connectionActivity As ActivityIndicator
    
    
    Private http As String
    Private cloudRx As String
    Dim flag As Int = 0
    Private accessToken As String = "XXXXXXXXXXXXXXXXXX"
    
    Private discoverlist As List
    Private jasonList As JSONParser
    
    
    'define zone pinout
    Private pinZone1 As String = "D0"
    Private pinZone2 As String = "D1"
    Private pinZone3 As String = "D2"
    Private pinZone4 As String = "D3"
    Private pinZone5 As String = "D4"
    Private pinZone6 As String = "D5"
    Private pinZone7 As String = "D6"
    Private pinZone8 As String = "D7"
    
    Private ON As String = "1"
    Private OFF As String = "0"
    
    'state machine
    Private currentState As Int = 0
    Private DISCOVERY_MODE As Int = 1
    Private CONNECTION_MODE As Int = 2
    Private MANUAL_MODE As Int = 3
    Private READ_GET As Int = 4
    Private READ_POST As Int = 5
    Private EVENT_MODE As Int = 6
    Private connectionStatus As Boolean = False
    
End Sub

Private Sub Application_Start (Nav As NavigationController)
    'SetDebugAutoFlushLogs(True) 'Uncomment if program crashes before all logs are printed.
    NavControl.Initialize("NavControl")
    NavControl = Nav
    
    SetTitleColor(Nav, 0xFF00AEFF, Colors.White)
        
    'main
    Page1.Initialize("page1")
    Page1.Title = "Main"
    Page1.RootPanel.Color = Colors.White
    NavControl.ShowPage(Page1)
    NavControl.ToolBarVisible = True
    NavControl.NavigationBarVisible = True
    Page1.RootPanel.LoadLayout("page1")
    Page1.HideBackButton = True
    
    'schedule
    Page2.Initialize("Page2")
    Page2.Title = "Schedule"
    Page2.RootPanel.LoadLayout("page2")
    Page2.HideBackButton = True
    
    'zone settings
    Page3.Initialize("Page3")
    Page3.Title = "Zones"
    Page3.RootPanel.LoadLayout("page3")
    Page3.HideBackButton = True
    
    'connection page
    Page4.Initialize("Page4")
    Page4.Title = "Settings"
    Page4.RootPanel.LoadLayout("page4")
    Page4.HideBackButton = True
    
    jobGet.Initialize("jobGet", Me)
    jobPost.Initialize("jobPost", Me)
    
    'deviceList.Initialize("deviceSelection")
    
    'init zoneName
    connectionActivity.Visible = False
    initZoneInfo
    initHomePage
    initSchedule
    'should check ctrl mode and schedule
    
End Sub


Sub SetTitleColor(nav As NavigationController, backgroundColor As Int, textColor As Int)
    Dim attributes As NativeObject
    Dim no As NativeObject = nav
    
    no.GetField("navigationBar").RunMethod("setBarTintColor:", Array(no.ColorToUIColor(backgroundColor))) '0xFF1E90FF
        
    attributes = attributes.Initialize("B4IAttributedString").RunMethod("createAttributes::", _
     Array(Font.CreateNew(18), attributes.ColorToUIColor(textColor)))
    
    no.GetField("navigationBar").RunMethod("setTitleTextAttributes:", Array(attributes))
End Sub


Private Sub initHomePage
    Dim tmp As String
    
    tmp = dataLog.KeyChainGet("ctrlMode")
    
    If Not(tmp == "") Then
        controlMode.SelectedIndex = tmp
    Else
        'controlMode.SelectedIndex = 0
    End If
    
    'get name from databse
    p1NameZone1.Text = dataLog.KeyChainGet("zone1")
    p1NameZone2.Text = dataLog.KeyChainGet("zone2")
    p1NameZone3.Text = dataLog.KeyChainGet("zone3")
    p1NameZone4.Text = dataLog.KeyChainGet("zone4")
    p1NameZone5.Text = dataLog.KeyChainGet("zone5")
    p1NameZone6.Text = dataLog.KeyChainGet("zone6")
    p1NameZone7.Text = dataLog.KeyChainGet("zone7")
    p1NameZone8.Text = dataLog.KeyChainGet("zone8")

    manCtrlZone1.SelectedIndex = 0
    manCtrlZone2.SelectedIndex = 0
    manCtrlZone3.SelectedIndex = 0
    manCtrlZone4.SelectedIndex = 0
    manCtrlZone5.SelectedIndex = 0
    manCtrlZone6.SelectedIndex = 0
    manCtrlZone7.SelectedIndex = 0
    manCtrlZone8.SelectedIndex = 0
    
    controlMode.SelectedIndex = 0
End Sub


Private Sub initZoneInfo
    
    zoneName1.Text = dataLog.KeyChainGet("zone1")
    zoneName2.Text = dataLog.KeyChainGet("zone2")
    zoneName3.Text = dataLog.KeyChainGet("zone3")
    zoneName4.Text = dataLog.KeyChainGet("zone4")
    zoneName5.Text = dataLog.KeyChainGet("zone5")
    zoneName6.Text = dataLog.KeyChainGet("zone6")
    zoneName7.Text = dataLog.KeyChainGet("zone7")
    zoneName8.Text = dataLog.KeyChainGet("zone8")
    
End Sub

Private Sub initSchedule
    Dim timeList As List
    Dim index As Int = 0
    Dim time As Int = 0
    Dim tmpList As String
        
    timeList.Initialize
    
    timeList.Add("00:00")
    For index = 1 To 23
        tmpList = index & ":00"       
        timeList.Add(tmpList)
    Next
    
    irrigationStartTime.SetItems(0, timeList)
    
    zCkbox1.Initialize(Me, zoneCkbox1, "Ckbox")
    zCkbox1.Text = zoneName1.Text
    zCkbox2.Initialize(Me, zoneCkbox2, "Ckbox")
    zCkbox2.Text = zoneName2.Text
    zCkbox3.Initialize(Me, zoneCkbox3, "Ckbox")
    zCkbox3.Text = zoneName3.Text
    zCkbox4.Initialize(Me, zoneCkbox4, "Ckbox")
    zCkbox4.Text = zoneName4.Text
    zCkbox5.Initialize(Me, zoneCkbox5, "Ckbox")
    zCkbox5.Text = zoneName5.Text
    zCkbox6.Initialize(Me, zoneCkbox6, "Ckbox")
    zCkbox6.Text = zoneName6.Text
    zCkbox7.Initialize(Me, zoneCkbox7, "Ckbox")
    zCkbox7.Text = zoneName7.Text
    
    dCkbox1.Initialize(Me, pnlCkbox1, "Ckbox")
    dCkbox1.Text = "Mon."
    dCkbox2.Initialize(Me, pnlCkbox2, "Ckbox")
    dCkbox2.Text = "Tues."
    dCkbox3.Initialize(Me, pnlCkbox3, "Ckbox")
    dCkbox3.Text = "Wed."
    dCkbox4.Initialize(Me, pnlCkbox4, "Ckbox")
    dCkbox4.Text = "Thurs."
    dCkbox5.Initialize(Me, pnlCkbox5, "Ckbox")
    dCkbox5.Text = "Fri."
    dCkbox6.Initialize(Me, pnlCkbox6, "Ckbox")
    dCkbox6.Text = "Sat."
    dCkbox7.Initialize(Me, pnlCkbox7, "Ckbox")
    dCkbox7.Text = "Sun."
    
    'gettimer from database
    
    
End Sub


Private Sub updateZoneNameInfo
    'on home page
    p1NameZone1.Text = zoneName1.Text
    p1NameZone2.Text = zoneName2.Text
    p1NameZone3.Text = zoneName3.Text
    p1NameZone4.Text = zoneName4.Text
    p1NameZone5.Text = zoneName5.Text
    p1NameZone6.Text = zoneName6.Text
    p1NameZone7.Text = zoneName7.Text
    p1NameZone8.Text = zoneName8.Text
        
    'on schedule page
    zCkbox1.Text = zoneName1.Text
    zCkbox2.Text = zoneName2.Text
    zCkbox3.Text = zoneName3.Text
    zCkbox4.Text = zoneName4.Text
    zCkbox5.Text = zoneName5.Text
    zCkbox6.Text = zoneName6.Text
    zCkbox7.Text = zoneName7.Text
    
End Sub

Sub Page1_BarButtonClick (Tag As String)
    If Tag="schedule" Then
        NavControl.ShowPage(Page2)
    Else If Tag="zones" Then
        NavControl.ShowPage(Page3)
    Else If Tag = "settings" Then
        settingsAutoFill
        NavControl.ShowPage(Page4)
    End If
End Sub

Sub Page2_BarButtonClick (Tag As String)
    If Tag="main" Then
        NavControl.ShowPage(Page1)
    Else If Tag="zones" Then
        NavControl.ShowPage(Page3)
    Else If Tag = "settings" Then
        settingsAutoFill
        NavControl.ShowPage(Page4)
    Else if Tag = "saveScheduleSettings" Then
        scheduleSettings
        'need to save data from schedule   
    End If
End Sub


Sub Page3_BarButtonClick (Tag As String)
    If Tag="main" Then
        NavControl.ShowPage(Page1)
    Else If Tag="schedule" Then
        NavControl.ShowPage(Page2)
    Else If Tag = "settings" Then
        settingsAutoFill
        NavControl.ShowPage(Page4)
    Else if Tag = "saveZoneSettings" Then
        'save zone name
        dataLog.KeyChainPut("zone1", zoneName1.Text)
        dataLog.KeyChainPut("zone2", zoneName2.Text)
        dataLog.KeyChainPut("zone3", zoneName3.Text)
        dataLog.KeyChainPut("zone4", zoneName4.Text)
        dataLog.KeyChainPut("zone5", zoneName5.Text)
        dataLog.KeyChainPut("zone6", zoneName6.Text)
        dataLog.KeyChainPut("zone7", zoneName7.Text)
        dataLog.KeyChainPut("zone8", zoneName8.Text)
    
        'update schedule and home page name for the zone
        updateZoneNameInfo
        
    End If
End Sub


Sub Page4_BarButtonClick (Tag As String)
    If Tag="main" Then
        NavControl.ShowPage(Page1)
        http = "https://api.particle.io/v1/devices/events?access_token=MY_ACCES_TOKEN"
        jobGet.Download(http)
    Else If Tag="schedule" Then
        NavControl.ShowPage(Page2)
    Else If Tag = "zones" Then
        NavControl.ShowPage(Page3)
    End If
End Sub



Private Sub settingsAutoFill
    
    user.Text = dataLog.KeyChainGet("user")
    password.Text = dataLog.KeyChainGet("password")
    
End Sub

Private Sub scheduleSettings
    'setTimer
    dataLog.KeyChainPut("timer", irrigTimeInMin.Text)
    
    currentState = READ_POST
    jobPost.PostString("https://api.particle.io/v1/devices/" & deviceName & "/setSchedule", "access_token=" & accessToken & "&params=" & irrigTimeInMin.Text)
End Sub


Private Sub Page1_Resize(Width As Int, Height As Int)
    
End Sub

Private Sub Application_Background
    
End Sub


Private Sub updateState
    Dim posi As Int
    Dim posi2 As Int
    Dim tempList As List
        
    Select Case currentState
        Case DISCOVERY_MODE
            tempList.Initialize()
            jasonList.Initialize(cloudRx)
            discoverlist = jasonList.NextArray 'the whole file is parsed now
            Log(discoverlist)
            
            For Each id As String In discoverlist
                posi = id.IndexOf("name")
                posi2 = id.IndexOf2(";", posi)
                deviceName = id.SubString2(posi+7, posi2)
                tempList.Add(deviceName)
                If deviceName.Length > 0  Then
                    connectionStatus = True
                End If
            Next
            
            'display on picker
            deviceList.SetItems(0,tempList)
            
        Case CONNECTION_MODE
            status.Text = deviceName.ToUpperCase
            connectionActivity.Visible = False
            dataLog.KeyChainPut("device", deviceName)
            
        Case READ_GET
            'need to check answer from device
            posi = cloudRx.IndexOf("result")
            posi2 = cloudRx.IndexOf2(",", posi)
            result = cloudRx.SubString2(posi+8, posi2)
        Case READ_POST
            'need to check answer from device
            posi = cloudRx.IndexOf("return_value")
            posi2 = cloudRx.IndexOf2("}", posi)
            result = cloudRx.SubString2(posi+14, posi2)
            'manCtrlZone8_IndexChanged(1)
        Case MANUAL_MODE
            'need to check answer from device
            posi = cloudRx.IndexOf("return_value")
            posi2 = cloudRx.IndexOf2("}", posi)
            result = cloudRx.SubString2(posi+14, posi2)
            
            
            'start the timer to check event from particle module
            'valveUpdateTimer.Initialize("manCtrlTimer", 1000)
            'valveUpdateTimer.Enabled = True
            End If
            
        Case EVENT_MODE
            posi = cloudRx.IndexOf("return_value")
            posi2 = cloudRx.IndexOf2("}", posi)
            result = cloudRx.SubString2(posi+14, posi2)
    End Select
    
End Sub


Sub JobDone (Job As HttpJob)
    Log("JobName = " & Job.JobName & ", Success = " & Job.Success)
    
    If Job.Success = True Then
        Select Job.JobName
            Case "jobGet"
                Log(Job.GetString)
                cloudRx = Job.GetString
            Case "jobPost"
                Log(Job.GetString)
                cloudRx = Job.GetString
                'could check for error code to see if command was successfull
        End Select
        
        updateState
    Else
        Log("Error: " & Job.ErrorMessage)
        'mess'messagePToastMessageShow("Error: " & Job.ErrorMessage, True)
    End If
    Job.Release
End Sub


Sub irrigationStartTime_ItemSelected (Column As Int, Row As Int)
    
End Sub

'user connection to module
Sub connectBtn_Click
    
    'deviceName = deviceList.Get
    
    'If connectionStatus Then
    '    currentState = CONNECTION_MODE
    '    updateState
    'End If
            
End Sub

Sub detectBtn_IndexChanged (Index As Int)
    'Dim jobGet As HttpJob
    'jobGet.Initialize("jobGet", Me)
    
    dataLog.KeyChainPut("user", user.Text)
    dataLog.KeyChainPut("password", password.Text)
    dataLog.KeyChainPut("device", deviceName)
    
    jobGet.Username = user.Text
    jobGet.Password = password.Text
    currentState = DISCOVERY_MODE
    
    'get device list
    http = "https://api.particle.io/v1/devices?access_token=" & accessToken
    jobGet.Download(http)
    
    'Wait For (jobGet) JobDone(jobGet As HttpJob)
    'If jobGet.Success = True Then
    '    Log(jobGet.GetString)
    '    cloudRx = jobGet.GetString
        
    '    updateState
        
    'End If
    
    'jobGet.Release
    
    connectionActivity.Visible = True
End Sub

Sub deviceList_ItemSelected (Column As Int, Row As Int)
    
    deviceName = deviceList.GetSelectedItem(Column)
    
    If connectionStatus Then
        currentState = CONNECTION_MODE
        updateState
    End If
    
End Sub


Private Sub manualControl (zone As String, controlPin As String, state As Int)
    
    'Dim jobGet, jobPost As HttpJob
    
    'jobGet.Initialize("jobGet", Me)
    'jobPost.Initialize("jobPost", Me)
    
    'currentState = READ_GET
    'http = "https://api.particle.io/v1/devices/" & deviceName & "/" & zone & "?access_token=" & accessToken
    'jobGet.Download(http)
    'Sleep(5000)
    'Wait For (jobGet) JobDone(jobGet As HttpJob)
    'If jobGet.Success = True Then
    '    Log(jobGet.GetString)
    '    cloudRx = jobGet.GetString
    '    updateState
    '    Log("result from Get is : " & result)
    'End If
    
    'jobGet.Release
    
    'check result
    currentState = MANUAL_MODE
    If state == 1 Then
        'not activate, so need to activate
        jobPost.PostString("https://api.particle.io/v1/devices/" & deviceName & "/zoneCtrlId", "access_token=" & accessToken & "&params=" & controlPin & "," & ON)
        manControlFlag = True
    Else If state == 0 Then
        'not activate, so need to activate
        jobPost.PostString("https://api.particle.io/v1/devices/" & deviceName & "/zoneCtrlId", "access_token=" & accessToken & "&params=" & controlPin & "," & OFF)
        manControlFlag = False
    End If
    
    
    'Wait For (jobPost) JobDone(jobPost As HttpJob)
    'If jobPost.Success = True Then
    '    Log(jobPost.GetString)
    '    cloudRx = jobPost.GetString
    '    updateState
    '    Log("result from Post is : " & result)
    'Else
    '    Log("job failed")
    'End If
    
    'jobPost.Release
End Sub

Sub manCtrlTimer_tick()
    'check for events
    
End Sub

Sub manCtrlZone1_IndexChanged (Index As Int)
    
    If Not(connectionStatus) Then
        messagePopup.ToastMessageShow("Not Connected", True)
        manCtrlZone1.SelectedIndex = 0
    Else
        manualControl("zone1", pinZone1, Index)
    End If
    
End Sub

Sub manCtrlZone2_IndexChanged (Index As Int)
    
    If Not(connectionStatus) Then
        messagePopup.ToastMessageShow("Not Connected", True)
        manCtrlZone2.SelectedIndex = 0
    Else
        manualControl("zone2", pinZone2, Index)
    End If
    
End Sub

Sub manCtrlZone3_IndexChanged (Index As Int)
    
    If Not(connectionStatus) Then
        messagePopup.ToastMessageShow("Not Connected", True)
        manCtrlZone3.SelectedIndex = 0
    Else
        manualControl("zone3", pinZone3, Index)
    End If
    
End Sub

Sub manCtrlZone4_IndexChanged (Index As Int)
    
    If Not(connectionStatus) Then
        messagePopup.ToastMessageShow("Not Connected", True)
        manCtrlZone4.SelectedIndex = 0
    Else
        manualControl("zone4", pinZone4, Index)
    End If
    
End Sub

Sub manCtrlZone5_IndexChanged (Index As Int)
    
    If Not(connectionStatus) Then
        messagePopup.ToastMessageShow("Not Connected", True)
        manCtrlZone5.SelectedIndex = 0
    Else
        manualControl("zone5", pinZone5, Index)
    End If
    
End Sub

Sub manCtrlZone6_IndexChanged (Index As Int)
    
    If Not(connectionStatus) Then
        messagePopup.ToastMessageShow("Not Connected", True)
        manCtrlZone6.SelectedIndex = 0
    Else
        manualControl("zone6", pinZone6, Index)
    End If
    
End Sub

Sub manCtrlZone7_IndexChanged (Index As Int)
    
    If Not(connectionStatus) Then
        messagePopup.ToastMessageShow("Not Connected", True)
        manCtrlZone7.SelectedIndex = 0
    Else
        manualControl("zone7", pinZone7, Index)
    End If
    
End Sub

Sub manCtrlZone8_IndexChanged (Index As Int)
    
    If Not(connectionStatus) Then
        messagePopup.ToastMessageShow("Not Connected", True)
        manCtrlZone8.SelectedIndex = 0
    Else
        'zone 1 need to be activated
        manualControl("zone8", pinZone8, Index)

    End If
    
End Sub

Sub controlMode_IndexChanged (Index As Int)
    
    'if mode automatic is selected, need to disable the zone manual control
    If Index == 0 Then
        'mode manual
        controlMode.SelectedIndex = 0
        manCtrlZone1.Enabled = True
        manCtrlZone2.Enabled = True
        manCtrlZone3.Enabled = True
        manCtrlZone4.Enabled = True
        manCtrlZone5.Enabled = True
        manCtrlZone6.Enabled = True
        manCtrlZone7.Enabled = True
        manCtrlZone8.Enabled = True
    Else
        'mode automatic
        controlMode.SelectedIndex = 1
        manCtrlZone1.Enabled = False
        manCtrlZone2.Enabled = False
        manCtrlZone3.Enabled = False
        manCtrlZone4.Enabled = False
        manCtrlZone5.Enabled = False
        manCtrlZone6.Enabled = False
        manCtrlZone7.Enabled = False
        manCtrlZone8.Enabled = False
    End If
    
    dataLog.KeyChainPut("ctrlMode", Index)
    
End Sub
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
For each jobGet.Download or jobPost.PostString, you need a corresponding dim'd jobGet and jobPost variable. Do not use a global variable.
Is this cleaned up code or should it be
B4X:
http = $"https://api.particle.io/v1/devices/events?access_token=${accessToken}"$
In all other places you use the accessToken variable.
In your Wait For code, why did you use a Sleep between the Download call and the wait for?
'jobGet.Download(http)
'Sleep(5000)
'Wait For (jobGet) JobDone(jobGet As HttpJob)
 
Upvote 0

alizeti

Member
Licensed User
I used 2 global variables for the jobGet and jobPostand both used the same jobDone callback.

Everything works perfectly except for the event command.
I never catch any events on the app. There is no callback triggered when the event happens on the particle module.

But when I call the event command on windows terminal using curl it catch the event i’m waiting for when the event actually happens in the particle module.

Example : I enable an output for 10 secs. After 10 sec, the particle send an event to the cloud. On windows terminal, I see it happen but on the app, nothing.


For each jobGet.Download or jobPost.PostString, you need a corresponding dim'd jobGet and jobPost variable. Do not use a global variable.

Is this cleaned up code or should it be
B4X:
http = $"https://api.particle.io/v1/devices/events?access_token=${accessToken}"$
In all other places you use the accessToken variable.
In your Wait For code, why did you use a Sleep between the Download call and the wait for?

You are right. I hard code the acces token for test purpose for this command only. I just replace the real access code with a dummy word for explanation purpose only.

For the delay, if you take a look closer, it’s in comments. It is not used. I was doing some test
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
I enable an output for 10 secs. After 10 sec, the particle send an event to the cloud. On windows terminal, I see it happen but on the app, nothing.
Because JobDone is only called after a page is finished loading. Looks like the events page (I'm guessing here from your description) never finishes loading, but is updated constantly. HttpClient does not work with such pages.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
The problem is when I want to get EVENTS from the cloud. Can’t make it work.
After doing some research, it looks like the site is using server side events, using Content-Type: text/event-stream. OkHttp3 does not support this out of the box. Looks like there is a "Java EventSource implementation based on OkHttp" called okhttp-eventsource. Even though the page mentions OkHttp, the source uses
B4X:
import okhttp3.*;
So until someone wraps this library or shows how to use the library via JavaObject, it looks like you will not be able to read your events.

Sources:
https://golb.hplar.ch/2018/02/Access-Server-Sent-Events-from-Java.html
https://github.com/launchdarkly/okhttp-eventsource
https://github.com/launchdarkly/okh.../launchdarkly/eventsource/EventSource.java#L3
 
Upvote 0

alizeti

Member
Licensed User
@OliverA This is B4i not B4J/A.

@alizeti
As written above you should create a new HttpJob for each request.
You can simplify your code: [B4X] OkHttpUtils2 with Wait For

What is the output of:
Log("JobName = " & Job.JobName & ", Success = " & Job.Success)

Does this explain why I don’t receive events?!
Another thing, if I do a wait for in the same function, this will stop the rest of the code?!
 
Last edited:
Upvote 0

OliverA

Expert
Licensed User
Longtime User
@OliverA This is B4i not B4J/A.
Mea culpa (as usual). But, I'm certain that the issue is Server Side Events (SSEs). JobDone is never "fired" since the page sort of never ends and therefore does not complete. In order to handle SSEs, something else besides HttpJob needs to be used or HttpJob needs to be updated to allow for the handling of SSEs.
if I do a wait for in the same function, this will stop the rest of the code?!
See https://www.b4x.com/android/forum/threads/b4x-resumable-subs-sleep-wait-for.78601/#content
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Does this explain why I don’t receive events?!
Another thing, if I do a wait for in the same function, this will stop the rest of the code?!
How can we help you if you don't provide the information we ask for...

Does this explain why I don’t receive events?!
I don't know. You still haven't explained what happens.

Another thing, if I do a wait for in the same function, this will stop the rest of the code?!
Time to learn about resumable subs: https://www.b4x.com/search?query=resumable+subs

If you want me to try to help you then start a new thread with the relevant information. I cannot keep asking you for more information.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
I don't know. You still haven't explained what happens.
In a round about way he has. When he uses
This is what I send using the GET :
http = "https://api.particle.io/v1/devices/DEVICE_ID/events?access_token=MY_TOKEN"
jobGet.Download(http)
JobDone is not fired. Therefore he is unable to report what he gets (since he cannot print GetString nor ErrorMessage inside JobDone, since JobDone is never executed).
If he tries
He sees events published continuously
Example : I enable an output for 10 secs. After 10 sec, the particle send an event to the cloud. On windows terminal, I see it happen but on the app, nothing.
If you look at the API docs of particle.io for events (https://docs.particle.io/reference/api/#events) you'll see the mentioning of streams. All this supports my "guess" that particle.io is using Server Side Events (SSEs) for publishing events and that HttpJob is currently not the right tool to deal with SSEs. A possible solution may be an implementation of this library (https://github.com/launchdarkly/ios-eventsource) for B4i. Please note that library was just a quick search (two others had no activity in awhile: https://github.com/neilco/EventSource and https://github.com/travisjeffery/TRVSEventSource).
 
Upvote 0

alizeti

Member
Licensed User
On windows terminal using curl, this is my steps :

step 1 : start the event listening
command :
curl "https://api.particle.io/v1/devices/dasilvaCore/events?access_token=access_token"
Response :
:eek:k

Step 2 : generate the event on the cloud through the particle module

Step 3 : Receive the event on windows terminal after 10 sec (for test purpose)
Response:
event: manCtrlTimer
data: {"data":"Valve close","ttl":60,"published_at":"2018-06-08T14:14:46.017Z","coreid":"device_id"}


On the App, if I do the same steps, I get nothing.
jobDone is not triggered.
I just replace all the global jobDone function with local to to Subs and still nothing.
 
Upvote 0
Status
Not open for further replies.
Top