Jump to content

Recommended Posts

4 hours ago, jompa68 said:

All sorted now. In my HomeTable i define scene not scenes that are setup with iOSLocator.
Added scenes and moved iOSLocator parts to that and all working as we want when we set

 local _test = false

Thanks again.

Now time for 1000m swimming before go to work, have a nice morning.

Cool, have you added the place for the swimming pool to iOSLocator? :-)

 

If you have any tips how to make these services easier to setup let me know, I have some ideas about other services too, and it would be nice to make them as easy as possible to install.

I guess that many of the scenes people have developed in this community, like notifiers, loggers, etc that use fibaro:startScene({...}) can just be used as is. However, if based on the EventRunner framework we can easily both send and receive events from them - like subroutines that can return values. 

In the iOSLocator example it was one way as the iOSLocator only sent events to the client scene. However, iOSLocator also listen to the event  '{type= 'getLocations'} and responds with resending all locations it is aware of to the asking scene. That means that the client scene(s) when they start up can ask the iOSLocator for all the known locations and get a response immediately. Otherwise the client need to wait until people move to get an update (if iOSLocator already knows where everyone is it will only send events when someone moves). Ex. Client rule:

Rule.eval("#autostart => iOSLocator:start=#getLocations")
Rule.eval("#other => iOSLocator:start=#getLocations")

..and the scene will immediately start to receive #location events for each person the iOSLocator knows about. This is very convenient if the client scene needs to restart. However, if the whole HC2 is restarted it is a good chance that the iOSLocator has not got any updates yet, and it may take some minutes.
 

 

Edited by jgab
misspelled getLocations
Link to post
Share on other sites
  • Replies 2.6k
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

Note. The first ~2000 posts of this thread is mainly about EventRunner3 that is for the HC2. EventRunner3 is not developed further, but bugs are fixed as they are reported. For HC3, the version i

I've been playing with the HC3 a bit  (I don't own a HC3 but a friend has allowed me to remotely login to do testing - I'm very grateful for that). ...and I have made some progress with EventRunn

Working with event runner rules it can be useful to understand a bit how they work behind the "hood". Rules are always on the form   <test> => <statments> Ex 88:breached

Posted Images

53 minutes ago, jgab said:

Cool, have you added the place for the swimming pool to iOSLocator?

Haha, i will add that and send some updates to my HC2, perhaps set a RGB bulb to a fancy color :D

 

53 minutes ago, jgab said:

Rule.eval("#autostart => iOSLocator:start=#geLocations") Rule.eval("#other => iOSLocator:start=#geLocations")

 

Should be

Rule.eval("#autostart => iOSLocator:start=#getLocations")
Rule.eval("#other => iOSLocator:start=#getLocations")

 

Edited by jompa68
Link to post
Share on other sites
37 minutes ago, jompa68 said:

Haha, i will add that and send some updates to my HC2, perhaps set a RGB bulb to a fancy color :D

 

 

Should be

Rule.eval("#autostart => iOSLocator:start=#getLocations")
Rule.eval("#other => iOSLocator:start=#getLocations")

 

Thanks, fixed.

Link to post
Share on other sites
2 minutes ago, jompa68 said:

Is this in kilometers?

yes. sometimes iCloud can think that you are wandering around +/-100m even when you are standing still so it is good to have a margin - 200-400m radius to a place. Maybe in the future when we get better GPSes...

Edited by jgab
Link to post
Share on other sites

Just a cosmetic thing.

"name":"Sparköp Rubinen"},

When using swedish letter ÅÄÖ in name it gives this

 

Untitled.png.980c075b160bb403465ecc227035c235.png

Link to post
Share on other sites

Yes, I know about this. Something happens when strings with foreign chars are sent as arguments to fibaro:start between scenes.... I could get around it by doing an urlencode/urldecode on the payload... but I was kind of hoping that it would get fixed.... anyway, will add it in next push.

20 hours ago, jgab said:

Yes, I know about this. Something happens when strings with foreign chars are sent as arguments to fibaro:start between scenes.... I could get around it by doing an urlencode/urldecode on the payload... but I was kind of hoping that it would get fixed.... anyway, will add it in next push.

Ok, I have pushed a version that urlencode the payload when doing postRemote, and urldecode when receiving events. (EventRunner.lua and iOSLocator.lua)

 

Edited by jgab
Link to post
Share on other sites
19 hours ago, jgab said:

Ok, I have pushed a version that urlencode the payload when doing postRemote, and urlencode when receiving events. (EventRunner.lua and iOSLocator.lua)

Implemented and urlencode is ok now.

Thank you.

Link to post
Share on other sites

This morning i got this error in iOSLocator.lua

 

[DEBUG] 07:10:37: 2018-10-25 07:10:37.305245 [ debug] Detected chunk with zero size, terminating connection
[DEBUG] 07:10:37:
[DEBUG] 07:10:37: 2018-10-25 07:10:37.307359 [ fatal] LUA error: /opt/fibaro/scenes/456.lua:166: attempt to index a nil value

 

Link to post
Share on other sites

Ooops. have had the locator run for months and haven't seen that error before. Anyway, is the version of iOSLocator identical with the one on GitHub? i.e. is line 166 equal to "     ["X-Client-Name"]= "iPad"," ?

Worst case, the iCloud service returns something strange that the net.HTTPClient() fails on and there is no way to capture that error, and it's crashing the iOSLocator... If that is the case, we can monitor the iOSLocator with a 'ping' routine' and restart it if it crashes. 

Let me check some more when I come home.

Link to post
Share on other sites

Yes looks the same..

    local headers = {
      ["Authorization"]="Basic ".. enc(event.user..":"..event.pwd), 
      ["Content-Type"] = "application/json; charset=utf-8",
      ["X-Apple-Find-Api-Ver"] = "2.0",
      ["X-Apple-Authscheme"] = "UserIdGuest",
      ["X-Apple-Realm-Support"] = "1.0",
      ["User-agent"] = "Find iPhone/1.3 MeKit (iPad: iPhone OS/4.2.1)",
      ["X-Client-Name"]= "iPad",
      ["X-Client-UUID"]= "0cf3dc501ff812adb0b202baed4f37274b210853",
      ["Accept-Language"]= "en-us",
      ["Connection"]= "keep-alive"}

A restart of scene did solve the problem.

Link to post
Share on other sites
On 10/25/2018 at 2:05 PM, jompa68 said:

Yes looks the same..

    local headers = {
      ["Authorization"]="Basic ".. enc(event.user..":"..event.pwd), 
      ["Content-Type"] = "application/json; charset=utf-8",
      ["X-Apple-Find-Api-Ver"] = "2.0",
      ["X-Apple-Authscheme"] = "UserIdGuest",
      ["X-Apple-Realm-Support"] = "1.0",
      ["User-agent"] = "Find iPhone/1.3 MeKit (iPad: iPhone OS/4.2.1)",
      ["X-Client-Name"]= "iPad",
      ["X-Client-UUID"]= "0cf3dc501ff812adb0b202baed4f37274b210853",
      ["Accept-Language"]= "en-us",
      ["Connection"]= "keep-alive"}

A restart of scene did solve the problem.

If this happens again, add this to your scene - preferably at the end of your function main() ... end It's ok to mix script rules with Lua event rules.

function main() 
  :
  :
  
  local pingTimeout = "+/00:01"
  local scenesToWatch={133,144,155}
  local watchRefs = {}

  Event.event({type='watchScene', scene='$scene'}, 
    function(env)
    	watchRefs[env.p.scene] = Event.post({type='pingTimeout',scene=env.p.scene},pingTimeout)
        Log(LOG.LOG,"PING")
    	Event.postRemote(env.p.scene,{type='%%PING%%',scene=env.p.scene})
    end) 
  
  Event.event({type='pingTimeout', scene='$scene'}, -- restart scene
    function(env)
        watchRefs[env.p.scene]=nil
    	Log(LOG.LOG,"Scene %s not answering, restarting scene!",env.p.scene)
    	fibaro:killScenes(env.p.scene) 
    	fibaro:startScene(env.p.scene) 
    	Event.post({type='watchScene',scene=env.p.scene},"+/00:01")-- Start watching in a minute to give scene time to start up 
     end)
  
  Event.event({type='%%PONG%%', scene='$scene'}, -- Got a pong back from client, cancel 'timeout' and watch again 
    function(env)
        Log(LOG.LOG,"PONG")
    	watchRefs[env.p.scene]=Event.cancel(watchRefs[env.p.scene]) 
    	Event.post({type='watchScene',scene=env.p.scene},pingTimeout) 
    end)
  
  Event.event({{type='autostart'},{type='other'}}, -- at startup, start watching client scenes 
  	function(env)
    	for _,scene in ipairs(scenesToWatch) do Event.post({type='watchScene',scene=scene}) end 
    end)

end -- main()

In scenesToWatch it should list the scene ID of the iOSLocator scene. You main scene will then ping it every minute and if it is not running it will restart the iOSLocator scene.

In iOSLocator there has to be code to respond to the ping, something I added to the iOSLocator I just pushed.

function main(sourceTrigger)
  local event = sourceTrigger
  :
  :
  
  if event.type=='%%PING%%' then event.type='%%PONG%'; postRemote(event._from,event) end -- respond to ping...
end -- main()

If there is a scene based on the full EventFramework, the pong routine should look like.

function main()


  :
  :

  Event.event({type='%%PING%%'},function(env) env.event.type='%%PONG%%'; Event.postRemote(env.event._from,env.event) end)

 

Edited by jgab
Link to post
Share on other sites

In watch scene there are some errors - undefined variables e.i.

1. clientsToWatch vs. scenesToWatch , 

2. timeoutMinutes, 

3. type='watchScene'  vs. type='watch',

4. cancel, ...

etc. - could you please check your code?

 

and also check code bellow - in my case event.type is nil - I try to use it in standard EventRunner scene

if event.type=='%%PING%%' then postRemote(event._from,{type='%%PONG%%'}) end -- respond to ping...

my code:

  Event.event({type='%%PING%%'}, 
    function(env)
      Event.postRemote(env.event._from,{type='%%PONG%%'})
    end)

 

Edited by petrkl12
Link to post
Share on other sites
3 hours ago, petrkl12 said:

In watch scene there are some errors - undefined variables e.i.

1. clientsToWatch vs. scenesToWatch , 

2. timeoutMinutes, 

3. type='watchScene'  vs. type='watch',

4. cancel, ...

etc. - could you please check your code?

 

and also check code bellow - in my case event.type is nil - I try to use it in standard EventRunner scene

if event.type=='%%PING%%' then postRemote(event._from,{type='%%PONG%%'}) end -- respond to ping...

my code:

  Event.event({type='%%PING%%'}, 
    function(env)
      Event.postRemote(env.event._from,{type='%%PONG%%'})
    end)

 

Thanks, it was a complete mess. I corrected the previous post (I hope).

Yes, the pong code for iOSLocator looks like that because it's based on the EventRunnerLite framework that doesn't have the Event.* functions.

Yes, your code is almost correct (you are getting it! :-) ). However, 

Event.event({type='%%PING%%'},
  function(env) 
    env.event.type='%%PONG%%'
    Event.postRemote(env.event._from,env.event) 
  end)

We reuse the event we get. This way the ping client can send arguments with the ping that it will get back. In the keep alive example above the ping routine get back the scene ID and ref so it can do another watch on the same scene.

Also pushed a new version of iOSLocator that sends back the ping arguments.

Edited by jgab
Link to post
Share on other sites

 

13 hours ago, jgab said:

If there is a scene based on the full EventFramework, the pong routine should look like.

function main()


  :
  :

  Event.event({type='%%PING%%'},function(env) env.event.type='%%PONG%%'; Event.postRemote(env.event._from,env.event) end)

I use that, so should i add this to iOSLocator scene?

Link to post
Share on other sites
3 minutes ago, jompa68 said:

 

I use that, so should i add this to iOSLocator scene?

No, it's the 

if event.type=='%%PING%%' then event.type='%%PONG%'; postRemote(event._from,event) end -- respond to ping...

because it's based on the EventRunnerLite framework.. However, I already added it to a version I pushed this morning. If you modified your own version of iOSLocator it could be easier to just add the above line.

Link to post
Share on other sites

Ok, I changed the ping/pong code again.

 

The reason is that the ref returned from the offline version of setTimeout (sed by postRemote) contains stuff that can not be json.encoded... It doesn't really affect code on the HC2 but I like the same code to be able to run online as well as offline. Anyway, the result is that the client can't send the ref in the ping but needs to keep it in a separate table. I may change the offline setTimeout to be more compliant in the future but i's some more work...

Link to post
Share on other sites

I have tried your scene it looks that it's still doesn't work fully (restart scene).

I have stoped manualy one of watch scene and I can see this message in that scene every minute:  "Aborting: Server not started yet" and scene is not starting ...

Link to post
Share on other sites

Another question:

 

I have a lot of rules that use timers:

 rule("@@hh:mm") 

it means that after restart all that rules run in one time at the beginning - impact is big load i.e. during Fibaro restart or scene restart

 

Is there possibility to add some parameter that first run will be after end of first interval?

 

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...