klausmeyer / fritzbox-smarthome

🏡 💡 Ruby client for AVM Home Automation Interface
https://rubygems.org/gems/fritzbox-smarthome
MIT License
6 stars 5 forks source link

Refresh data for single device #34

Closed mkoegel closed 1 year ago

mkoegel commented 1 year ago

Hi, in my use-case I need the current temperatur of a heater every couple of minutes. I could not find a way to refresh data of a individual device in the API. Could this be added via a update or refresh method?

I was able to achieve this with the following calls:

data = Fritzbox::Smarthome::Resource.get(command: 'getdeviceinfos', ain: heater.ain)
Fritzbox::Smarthome::Heater.new_from_api(data['device'])

However the ain and id are missing from the new heater.

'getdeviceinfos' is a new command that has apparently not been used in the API yet.

Unfortunately my ruby skills are not good enough for a PR.

Best Regards, Michael

carpodaster commented 1 year ago

@mkoegel re. the refresh every couple of minutes, you can do it with a loop:

loop do
  # query the smarthome api and do stuff with the response
  sleep 60 # 1 minute
end

Note: this is a blocking call. If you want your program to do other things while it's waiting, you'll need to wrap that into a thread.

mkoegel commented 1 year ago

@carpodaster That's what I do right now:

heaters = Fritzbox::Smarthome::Heater.all
heater = heaters.select{|heater| heater.name==HEATER}.first

Is there a easier way to get the data from a single device?

klausmeyer commented 1 year ago

I personally never had the need but it might be really a good idea to allow refreshing the data of a single actor instead of having the user of the library always to work with the list.

Your approach trying to use getdeviceinfos is correct I think - maybe just a few things missing under the hood in the library.

Maybe I can have a look later.

klausmeyer commented 1 year ago

I've shuffled some things around - feel free to give it a try.

You can point your Gemfile against my branch:

gem 'fritzbox-smarthome', github: 'klausmeyer/fritzbox-smarthome', branch: 'feat/reload-actors'

Each Actor now has a #reload method which should do what you were looking for.

actors = Fritzbox::Smarthome::Actor.all

actor = actors.first

while true
  actor.reload
  puts actor.inspect
  sleep(60)
end

In addition I implemented Actor.find_by!(ain:) to load a single actor directly without loading the list first.

Let me know if that works for you.

mkoegel commented 1 year ago

Thank you! It's working for me now.

A single reload call still takes ~6 sec, but I don't have any comparissons with curl or another API.

mkoegel commented 1 year ago

Fixed with #35

klausmeyer commented 1 year ago

Ok, I'll ship a new version then :)

klausmeyer commented 1 year ago

https://rubygems.org/gems/fritzbox-smarthome/versions/0.6.0