CodementorIO / rest-firebase

Ruby Firebase REST API client built on top of rest-core
Apache License 2.0
107 stars 22 forks source link

Setting up Listener in rest-firebase #17

Closed oscar-johnson closed 7 years ago

oscar-johnson commented 7 years ago

Very new to the rest-firebase gem. Would like to setup rest-firebase to listen for changes to a NEST client. Have successfully setup rest-firebase with the proper firebase URL, along with the SECRET assigned to NEST developer and have generated a token (does not look to be in the standard JWT format) . I am able to run an "f.get" and retrieve my NEST data successful; however, if I do too many of these, I get the standard 429 (too many requests error).

So, was wondering what the best way is to setup a listener using Ruby. Are there any examples out there?

The only example similar was for using the em-eventsource gem which I am assuming the same thing rest-firebase is capable of doing

require "em-eventsource"
EM.run do
    source = EventMachine::EventSource.new("http://example.com/streaming")
     source.message do |message|
         puts "new message #{message}"
     end
     source.start # Start listening
 end
godfat commented 7 years ago

I don't know what's a NEST client, but if you're looking for event source then it's there. Checkout README.

oscar-johnson commented 7 years ago

By using the callback based solution, I am able to change a value on the NEST and get an immediate response back from the rest-firebase program.

require 'rest-firebase' firebase = RestFirebase.new(:log_method => method(:puts)) puts "callback also works" firebase.get('users/tom') do |r| p r['name']end puts "It's not blocking... but doing concurrent requests underneath" firebase.wait # we block here to wait for the request done puts "DONE"

On Mon, Oct 24, 2016 at 12:29 PM, Eric Scalera eric.scalera@gmail.com wrote:

NEST works very closely with Firebase, I think they are both Google companies. The NEST thermostats all report to Firebase which allows real-time updating.

On Mon, Oct 24, 2016 at 12:27 PM, Eric Scalera eric.scalera@gmail.com wrote:

Yes, I am using the code, Thank you. The NEST is a thermostat company which was bought by Google a few years ago. Would like to monitor the thermostat and get a notification when something changes such as the temperature changing etc. If I run an f.get too many times I get a 429 HTTP error, so would like to know how to implement this code so that I get a message or reply from the firebase server only when a change has occurred on the thermostat.

On Mon, Oct 24, 2016 at 12:12 PM, Lin Jen-Shin (godfat) < notifications@github.com> wrote:

I don't know what's a NEST client, but if you're looking for event source then it's there. Checkout README https://github.com/CodementorIO/rest-firebase#synopsis.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/CodementorIO/rest-firebase/issues/17#issuecomment-255836605, or mute the thread https://github.com/notifications/unsubscribe-auth/AV-Kn2AGXzxboGxMsHEJWjvSYijVSmNWks5q3QMxgaJpZM4KfKN1 .

oscar-johnson commented 7 years ago

Lin

Do you know how to disable the ":log_method?" I am only looking to view the changed json element.

Thank you.

Eric

On Mon, Oct 24, 2016 at 1:18 PM, Eric Scalera eric.scalera@gmail.com wrote:

By using the callback based solution, I am able to change a value on the NEST and get an immediate response back from the rest-firebase program.

require 'rest-firebase' firebase = RestFirebase.new(:log_method => method(:puts)) puts "callback also works" firebase.get('users/tom') do |r| p r['name']end puts "It's not blocking... but doing concurrent requests underneath" firebase.wait # we block here to wait for the request done puts "DONE"

On Mon, Oct 24, 2016 at 12:29 PM, Eric Scalera eric.scalera@gmail.com wrote:

NEST works very closely with Firebase, I think they are both Google companies. The NEST thermostats all report to Firebase which allows real-time updating.

On Mon, Oct 24, 2016 at 12:27 PM, Eric Scalera eric.scalera@gmail.com wrote:

Yes, I am using the code, Thank you. The NEST is a thermostat company which was bought by Google a few years ago. Would like to monitor the thermostat and get a notification when something changes such as the temperature changing etc. If I run an f.get too many times I get a 429 HTTP error, so would like to know how to implement this code so that I get a message or reply from the firebase server only when a change has occurred on the thermostat.

On Mon, Oct 24, 2016 at 12:12 PM, Lin Jen-Shin (godfat) < notifications@github.com> wrote:

I don't know what's a NEST client, but if you're looking for event source then it's there. Checkout README https://github.com/CodementorIO/rest-firebase#synopsis.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/CodementorIO/rest-firebase/issues/17#issuecomment-255836605, or mute the thread https://github.com/notifications/unsubscribe-auth/AV-Kn2AGXzxboGxMsHEJWjvSYijVSmNWks5q3QMxgaJpZM4KfKN1 .

oscar-johnson commented 7 years ago

NEST works very closely with Firebase, I think they are both Google companies. The NEST thermostats all report to Firebase which allows real-time updating.

On Mon, Oct 24, 2016 at 12:27 PM, Eric Scalera eric.scalera@gmail.com wrote:

Yes, I am using the code, Thank you. The NEST is a thermostat company which was bought by Google a few years ago. Would like to monitor the thermostat and get a notification when something changes such as the temperature changing etc. If I run an f.get too many times I get a 429 HTTP error, so would like to know how to implement this code so that I get a message or reply from the firebase server only when a change has occurred on the thermostat.

On Mon, Oct 24, 2016 at 12:12 PM, Lin Jen-Shin (godfat) < notifications@github.com> wrote:

I don't know what's a NEST client, but if you're looking for event source then it's there. Checkout README https://github.com/CodementorIO/rest-firebase#synopsis.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/CodementorIO/rest-firebase/issues/17#issuecomment-255836605, or mute the thread https://github.com/notifications/unsubscribe-auth/AV-Kn2AGXzxboGxMsHEJWjvSYijVSmNWks5q3QMxgaJpZM4KfKN1 .

godfat commented 7 years ago

If you don't want :log_method then just don't pass it. I suppose this is what you want?

oscar-johnson commented 7 years ago

Yes, I am using the code, Thank you. The NEST is a thermostat company which was bought by Google a few years ago. Would like to monitor the thermostat and get a notification when something changes such as the temperature changing etc. If I run an f.get too many times I get a 429 HTTP error, so would like to know how to implement this code so that I get a message or reply from the firebase server only when a change has occurred on the thermostat.

On Mon, Oct 24, 2016 at 12:12 PM, Lin Jen-Shin (godfat) < notifications@github.com> wrote:

I don't know what's a NEST client, but if you're looking for event source then it's there. Checkout README https://github.com/CodementorIO/rest-firebase#synopsis.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/CodementorIO/rest-firebase/issues/17#issuecomment-255836605, or mute the thread https://github.com/notifications/unsubscribe-auth/AV-Kn2AGXzxboGxMsHEJWjvSYijVSmNWks5q3QMxgaJpZM4KfKN1 .

godfat commented 7 years ago

So does it work for you now?

oscar-johnson commented 7 years ago

Lin,

Was able to resolve the logging issue. Have been working on trying to debug a NilClass issue and was reading through some of the issues related to this. I'm not sure this is the same issue as issue #5, but the program is continually returning the following:

<NoMethodError: undefined method `[]' for nil:NilClass> "#IO:(closed)"

"RestCore: spent 0.728148 Requested GET https://firebase-apiserver08-tah01-iad01.dapi.production.nest.com:9553/.json?auth= <"NEST_TOKEN>

The program is working perfectly with the exception of the NilClass issue. Also , why does the program return the variable three times when I change the value on the thermostat?

NEST returned variables below


65

"off"

50

"Hallway (George Ross)"


The program does not call the REST get, but get is being sent at the top level which is what I want, so I do not have to explicitly write a get. For that reason, I have not figured out how to use the ".tap{} command.

Is there a way to resolve this nilClass issue?

require 'rest-firebase' require "awesome_print"

f = RestFirebase.new :site => 'https://firebase-apiserver08-tah01-iad01.dapi.production.nest.com:9553', :secret => 'NEST_SECRET_KEY', :d => {:auth_data => ''}, :log_method => method(:p),

timeout in seconds

                 :timeout => 20,
                 # `max_retries` upon failures. Default is: `0`
                 :max_retries => 3,
                 # `retry_exceptions` for which exceptions should retry
                 # Default is: `[IOError, SystemCallError]`
                 :retry_exceptions =>
                     [IOError, SystemCallError, Timeout::Error],
                 # `error_callback` would get called each time there's
                 # an exception. Useful for monitoring and logging.
                 :error_callback => method(:puts),
                 # `auth_ttl` describes when we should refresh the auth
                 # token. Set it to `false` to disable auto-refreshing.
                 # The default is 23 hours.
                 :auth_ttl => false,
                 #:auth_ttl => 82800,
                 # `auth` is the auth token from Firebase. Leave it alone
                 # to auto-generate. Set it to `false` to disable it.
                 :auth => 'NEST_AUTH_TOKEN' # Ignore auth for this example!

@reconnect = true

es = f.event_source('')

RestFirebase.pool_size = 10 RestFirebase.pool_idle_time = 60

es.onopen { |sock| p sock } # Called when connected es.onmessage{ |event, data, sock|

ap data

puts ""
ap data["data"]["devices"]["thermostats"]["9FN_YpImgnw0NxIECK1_U_3cnYxayIHr"]\
       ["ambient_temperature_f"]
ap data["data"]["devices"]["thermostats"]["9FN_YpImgnw0NxIECK1_U_3cnYxayIHr"]\
       ["hvac_state"]
ap data["data"]["devices"]["thermostats"]["9FN_YpImgnw0NxIECK1_U_3cnYxayIHr"]\
       ["target_temperature_f"]
ap data["data"]["devices"]["thermostats"]["9FN_YpImgnw0NxIECK1_U_3cnYxayIHr"]\
        ["name"]
#
        puts ""
 } # Called for each message

Called whenever there's an error

es.onerror { |error, sock| p error, sock.inspect}

Extra: If we return true in onreconnect callback, it would automatically

reconnect the node for us if disconnected.

es.onreconnect{ |error, sock| p error; @reconnect }

es.onreconnect{ |error, sock| ; @reconnect }

Start making the request

es.start

puts "callback also works"

0.upto(10) do

f.get('devices') do |r|

puts "======================"

p r['thermostats']["9FN_YpImgnw0NxIECK1_U_3cnYxayIHr"]["name"]

puts "======================"

#

end

sleep 10

end

puts "It's not blocking... but doing concurrent requests underneath" f.wait # we block here to wait for the request done

puts "DONE"

Try to close the connection and see it reconnects automatically

es.close

Update users/tom.json

f.put('User', :name => 'Tom')

f.post('User', :name => 'Tom')

puts "=======================================\n"

p f.get('/Users', :orderBy => '$key', :limitToFirst => 3)

ap nest.status, :raw => false, :color => {:hash => :blue}

puts "#{f.get('devices')}"

puts "=======================================\n"

sleep 10

f.get('User')

puts user

p f.delete('devices')

#

With Firebase queries (it would encode query in JSON for you)

p f.get('/User', :orderBy => '$key', :limitToFirst => 1)

Need to tell onreconnect stops reconnecting, or even if we close

the connection manually, it would still try to reconnect again.

@reconnect = false

Close the connection to gracefully shut it down.

es.close

Refresh the auth by resetting it

f.auth = nil

On Tue, Oct 25, 2016 at 11:33 AM, Lin Jen-Shin (godfat) < notifications@github.com> wrote:

If you don't want :log_method then just don't pass it. I suppose this is what you want?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/CodementorIO/rest-firebase/issues/17#issuecomment-256130293, or mute the thread https://github.com/notifications/unsubscribe-auth/AV-Kn61x33rHRr2JYBsuPTEcs6GZdd6Xks5q3ktlgaJpZM4KfKN1 .

oscar-johnson commented 7 years ago

Yes, it works except I have not yet been able to resolve the NilClass issue.

<NoMethodError: undefined method `[]' for nil:NilClass> "#IO:(closed)"

On Wed, Oct 26, 2016 at 3:32 AM, Lin Jen-Shin (godfat) < notifications@github.com> wrote:

So does it work for you now?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/CodementorIO/rest-firebase/issues/17#issuecomment-256309673, or mute the thread https://github.com/notifications/unsubscribe-auth/AV-Kn4ThLkReKuFihlTde_KUaMZkD6geks5q3yxIgaJpZM4KfKN1 .

godfat commented 7 years ago

Sorry but this is too hard to read. Could you please remove quotes if you're sending from emails, and maybe use gist to post the codes?

oscar-johnson commented 7 years ago

Sure, please go to the following link:

https://gist.github.com/oscar-johnson/804e92f834f85fe1f18cc0a475ac0eb4

On Wed, Oct 26, 2016 at 8:45 AM, Lin Jen-Shin (godfat) < notifications@github.com> wrote:

Sorry but this is too hard to read. Could you please remove quotes if you're sending from emails, and maybe use gist to post the codes?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/CodementorIO/rest-firebase/issues/17#issuecomment-256389408, or mute the thread https://github.com/notifications/unsubscribe-auth/AV-Kn1LE_BA6y4VWDat_ld9nNGzjpQoaks5q33WOgaJpZM4KfKN1 .

oscar-johnson commented 7 years ago

Please try this link rather than the original link:

https://gist.github.com/oscar-johnson/cde65aa5976fbefb339457930f6d78f5

On Wed, Oct 26, 2016 at 10:11 AM, Eric Scalera eric.scalera@gmail.com wrote:

Sure, please go to the following link:

https://gist.github.com/oscar-johnson/804e92f834f85fe1f18cc0a475ac0eb4

On Wed, Oct 26, 2016 at 8:45 AM, Lin Jen-Shin (godfat) < notifications@github.com> wrote:

Sorry but this is too hard to read. Could you please remove quotes if you're sending from emails, and maybe use gist to post the codes?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/CodementorIO/rest-firebase/issues/17#issuecomment-256389408, or mute the thread https://github.com/notifications/unsubscribe-auth/AV-Kn1LE_BA6y4VWDat_ld9nNGzjpQoaks5q33WOgaJpZM4KfKN1 .

godfat commented 7 years ago

I think your server was somehow not returning a proper message. You should check what's returning from your server.

oscar-johnson commented 7 years ago

It looks like its receiving a keep-alive from the server with null data so the socket is closing.

The highlighted text is what I am seeing in the debugger.

def onmessage_for sock while IO.select([sock], [], [], READ_WAIT) event = sock.readline("\n\n").split("\n").inject({}) do |r, i| event: {data: null, event: keep-alive} k, v = i.split(': ', 2) r[k] = v r end onmessage(event['event'], event['data'], sock) end close_sock(sock) onerror(EOFError.new, sock) rescue IOError, SystemCallError => e close_sock(sock) onerror(e, sock) end

On Wed, Oct 26, 2016 at 10:34 AM, Lin Jen-Shin (godfat) < notifications@github.com> wrote:

I think your server was somehow not returning a proper message. You should check what's returning from your server.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/CodementorIO/rest-firebase/issues/17#issuecomment-256421580, or mute the thread https://github.com/notifications/unsubscribe-auth/AV-Kn1DEfpcV-xAhc_PpWQ5SrXq0dFnFks5q348jgaJpZM4KfKN1 .

godfat commented 7 years ago

Then you should probably skip keep-alive event in your code. Also HTML doesn't work in email reply. There's no highlights at all.

oscar-johnson commented 7 years ago

Agreed, working on skipping keep-alive events.

On Wed, Oct 26, 2016 at 11:31 AM, Lin Jen-Shin (godfat) < notifications@github.com> wrote:

Then you should probably skip keep-alive event in your code. Also HTML doesn't work in email reply. There's no highlights at all.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/CodementorIO/rest-firebase/issues/17#issuecomment-256437289, or mute the thread https://github.com/notifications/unsubscribe-auth/AV-Kn636vublb8QiHLl6JL8t2G5x4jJ_ks5q35yJgaJpZM4KfKN1 .

godfat commented 7 years ago

I am closing this issue. If you have other questions, you could try chatting on gitter. I'm also there.

oscar-johnson commented 7 years ago

Lin,

Thanks for your help and thank you for writing such a wonderfully robust program for everybody to use. Excellent job.

Regards,

Eric R. Scalera

On Thu, Oct 27, 2016 at 9:09 AM, Lin Jen-Shin (godfat) < notifications@github.com> wrote:

I am closing this issue. If you have other questions, you could try chatting on gitter https://gitter.im/CodementorIO/rest-firebase. I'm also there.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/CodementorIO/rest-firebase/issues/17#issuecomment-256691682, or mute the thread https://github.com/notifications/unsubscribe-auth/AV-Kn5Sj6oC_lWVlouVFee4ylFXLB7Slks5q4MzGgaJpZM4KfKN1 .

godfat commented 7 years ago

No problems :)

Thanks for using it!