Jump to content

Welcome to Smart Home Forum by FIBARO

Dear Guest,

 

as you can notice parts of Smart Home Forum by FIBARO is not available for you. You have to register in order to view all content and post in our community. Don't worry! Registration is a simple free process that requires minimal information for you to sign up. Become a part of of Smart Home Forum by FIBARO by creating an account.

 

As a member you can:

  •     Start new topics and reply to others
  •     Follow topics and users to get email updates
  •     Get your own profile page and make new friends
  •     Send personal messages
  •     ... and learn a lot about our system!

 

Regards,

Smart Home Forum by FIBARO Team


SourceTriggerSubscriber


jgab

Recommended Posts

Thanks once again :D Yeah the stop is there before I know how it works 😅 Have hade some spam from the sub function 😅 

 

just so I understand the "Post" since we are only asking for the weather (1:), and if ill make a Sub for each weather condition(2:).
I may not need more then one post for all of them? or is it a more proper way to sub to the weather and get the string stored like (3:)

 

1:

Please login or register to see this code.

 

2:

on for rain:

 local SubWeatherrain = SourceTriggerSubscriber()
    SubWeatherrain:subscribe(
{type='weather',property= "weatherCondition", value="Rain"}

one for snow:

 local SubWeathersnow = SourceTriggerSubscriber()
    SubWeathersnow:subscribe(
{type='weather',property= "weatherCondition", value="Snow"}

 

 

3:

Weather = "Snow"

 

 

 

 

 

----------Edit---------------

 

 

 

 

I guess this is not the proper way to get the weather value but it works 😅 

 

----Weather partlyCloudy-------
 local SubWeathersnow = SourceTriggerSubscriber()
    SubWeathersnow:subscribe(
{type='weather',property= "WeatherCondition", value="snow"}, ------------snow partlyCloudy   fog    clear   storm     rain    cloudy----------
function(event)      ----{type='weather',property=<string>, value=<number>, old=<number>}
print("SubWeathersnow")
Weather = "Snow"
self:setVariable("Weather", Weather)
 
print("SubWeathersnow2")
end)
-----oninit-------
SubWeathersnow:run()
 
----Weather partlyCloudy-------
 local SubWeatherpartlyCloudy = SourceTriggerSubscriber()
    SubWeatherpartlyCloudy:subscribe(
{type='weather',property= "WeatherCondition", value="partlyCloudy"}, ------------snow PartlyCloudy   fog    clear   storm      rain    cloudy----------
function(event)      ----{type='weather',property=<string>, value=<number>, old=<number>}
print("SubWeatherpartlyCloudy")
Weather = "PartlyCloudy"
self:setVariable("Weather", Weather)
print("SubWeatherpartlyCloudy2")
end)
-----oninit-------
SubWeatherpartlyCloudy:run()
 
----Weather fog-------
 local SubWeatherfog = SourceTriggerSubscriber()
    SubWeatherfog:subscribe(
{type='weather',property= "WeatherCondition", value="fog"}, ------------snow partlyCloudy   fog    clear   storm      rain    cloudy----------
function(event)      ----{type='weather',property=<string>, value=<number>, old=<number>}
print("SubWeatherfog")
Weather = "Fog"
self:setVariable("Weather", Weather)
 
print("SubWeatherfog2")
end)
-----oninit-------
SubWeatherfog:run()
 
----Weather clear-------
 local SubWeatherclear = SourceTriggerSubscriber()
    SubWeatherclear:subscribe(
{type='weather',property= "WeatherCondition", value="clear"}, ------------snow partlyCloudy   fog    clear   storm      rain    cloudy----------
function(event)      ----{type='weather',property=<string>, value=<number>, old=<number>}
print("SubWeatherclear")
Weather = "Clear"
self:setVariable("Weather", Weather)
print("SubWeatherclear2")
end)
-----oninit-------
SubWeatherclear:run()
 
----Weather storm-------
 local SubWeatherstorm = SourceTriggerSubscriber()
    SubWeatherstorm:subscribe(
{type='weather',property= "WeatherCondition", value="storm"}, ------------snow partlyCloudy   fog    clear   storm      rain    cloudy----------
function(event)      ----{type='weather',property=<string>, value=<number>, old=<number>}
print("SubWeatherstorm")
Weather = "Storm"
self:setVariable("Weather", Weather)
print("SubWeatherstorm2")
end)
-----oninit-------
SubWeatherstorm:run()
 
----Weather rain-------
 local SubWeatherrain = SourceTriggerSubscriber()
    SubWeatherrain:subscribe(
{type='weather',property= "WeatherCondition", value="rain"}, ------------snow partlyCloudy   fog    clear   storm      rain    cloudy----------
function(event)      ----{type='weather',property=<string>, value=<number>, old=<number>}
print("SubWeatherrain")
Weather = "Rain"
self:setVariable("Weather", Weather)
print("SubWeatherrain2")
end)
-----oninit-------
SubWeatherrain:run()
 
----Weather cloudy-------
 local SubWeathercloudy = SourceTriggerSubscriber()
    SubWeathercloudy:subscribe(
{type='weather',property= "weatherCondition", value="cloudy"}, ------------snow partlyCloudy   fog    clear   storm      rain    cloudy----------
function(event)      ----{type='weather',property=<string>, value=<number>, old=<number>}
print("SubWeathercloudy")
Weather = "Cloudy"
self:setVariable("Weather", Weather)
print("SubWeathercloudy")
end)
-----oninit-------
SubWeathercloudy:run()
 
for k,v in pairs(api.get("/weather")) do -- post weather events to ourselves when we start up
  SubWeathersnow:post({type='weather', property=k, value=v})
  SubWeatherpartlyCloudy:post({type='weather', property=k, value=v})
  SubWeatherfog:post({type='weather', property=k, value=v})
  SubWeatherclear:post({type='weather', property=k, value=v})
  SubWeatherstorm:post({type='weather', property=k, value=v})
  SubWeatherrain:post({type='weather', property=k, value=v})
  SubWeathercloudy:post({type='weather', property=k, value=v})
end

 

 

 

Is it an shorter way to code it to sub to the weather state? 

and store it in Weather = "snow" 

 

 

 

 

 

 

 

Edited by Brors94
Link to comment
Share on other sites

  • Topic Author
  • Please login or register to see this code.

     

    If you leave out the value key for the event you subscribe to, it will match all WeatherConditions, but you can pick up what the actual value is by looking at event.value

    1. The post function allow you to post your own events that can be picked up by subscriptions.

    In the example we read the current weather condition from the REST api and re-post them as events. That way you will get the weather trigger when the QA starts.

    • Thanks 1
    Link to comment
    Share on other sites

    8 minutes ago, jgab said:

    Please login or register to see this code.

     

    If you leave out the value key for the event you subscribe to, it will match all WeatherConditions, but you can pick up what the actual value is by looking at event.value

    1. The post function allow you to post your own events that can be picked up by subscriptions.

    In the example we read the current weather condition from the REST api and re-post them as events. That way you will get the weather trigger when the QA starts.

     

    Awesome :D 

    It is greath too have you here Jgab. have learnt alot from your stuff :D dont understand everything, but I have too say it is quite fun to code stuff 😃

    Link to comment
    Share on other sites

    Hi Again Jgab. 

     

    I am trying to subscribe to a spesific time set by some buttons. 

    and dosent want to use the standard Refreshstatesubscriber, since it spams alot even if you have the "Self:subtimeoff:stop()" First it triggers 2-10 times... 

     

    Is it a way to use the sourcetriggersubscriber other then posting the times like in the example below? :D 

     

     

    I am justing this today: 

    -----subTimeon on------
    self.subTimeon = RefreshStateSubscriber()
    local subcription = self.subTimeon:subscribe(
    function(event)
    return
    os.date("%H:%M")== Timeon
    end,
    function(event)
    self:debug("subTimeon")
    weekday = tonumber(os.date("%w"))
    hub.call(QuickAppID, "Triggerontime")
    self.subTimeon:stop()
    hub.setTimeout(50*1000, function()
    self.subTimeoff:run()
    self.subTimeon:run()
    end)

     

     

     

     

     

     

    Link to comment
    Share on other sites

  • Topic Author
  • 41 minutes ago, Brors94 said:

    Hi Again Jgab. 

     

    I am trying to subscribe to a spesific time set by some buttons. 

    and dosent want to use the standard Refreshstatesubscriber, since it spams alot even if you have the "Self:subtimeoff:stop()" First it triggers 2-10 times... 

     

    Is it a way to use the sourcetriggersubscriber other then posting the times like in the example below? :D 

     

    I am justing this today: 

    -----subTimeon on------
    self.subTimeon = RefreshStateSubscriber()
    local subcription = self.subTimeon:subscribe(
    function(event)
    return
    os.date("%H:%M")== Timeon
    end,
    function(event)
    self:debug("subTimeon")
    weekday = tonumber(os.date("%w"))
    hub.call(QuickAppID, "Triggerontime")
    self.subTimeon:stop()
    hub.setTimeout(50*1000, function()
    self.subTimeoff:run()
    self.subTimeon:run()
    end)

     

    Well, first this is not the way to use RefreshStateSubscriber. The first function will be called whenever there is any type of event - that can take 1 second or 20min - so it's a bad place to test if your time is up - especially as you test against a specific hour:minute which you easily could miss...

     

    Secondly, this is a thread about SourceTriggerSubscriber - which is a different take on the subject of events....

     

    Third, why can't your button just start a setTimeout for the time when it should execute the action you want?

     

    Fourth, SourceTriggerSubscriber can post it's own events at specific times when you can run the actions

    Something like:

    Please login or register to see this code.

     

    Link to comment
    Share on other sites

    ah, sry  😅

     

    I see I formulated myself wrong. 

    I meant I use the Refreshstatesubscriber today like that.

    (I dont know how else it should be used 😅 Fibaro hc3 is my only experience with scripts)

     

    And was wondering if it is possible to use the sourcetriggersubscriber to trigger on the variable Timeon (05:32)

     

    This is the layout of the buttons :D 

    It is meant to be used to turn ON the Relay every day at that time.
    so I wont be pushing the button to start a trigger. 

    and the 05:32 is the Timeon variable.

    image.png.35323e7b5d1a86b6209b0f9b1cb1044f.png

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    Link to comment
    Share on other sites

  • Topic Author
  • Is Timeon a fibaro global variable?

    In that case

    Please login or register to see this code.

     

    • Thanks 1
    Link to comment
    Share on other sites

    @jgab Jan, the asnwer is probably not, but who knows the result when asking you :-)

     

    So the subscriber class can be used in any way , like we use fibaroextra's publish / subscribe pattern?

    I want to publish an event with arguments, then on other QA that subscribes for it, it takes those arguments, and does some action with given arguments...

    Probably refreshSubscribe is not suited for this right?

     

    Edited by Neo Andersson
    Link to comment
    Share on other sites

  • Topic Author
  • 24 minutes ago, Neo Andersson said:

    @jgab Jan, the asnwer is probably not, but who knows the result when asking you :-)

     

    So the subscriber class can be used in any way , like we use fibaroextra's publish / subscribe pattern?

    I want to publish an event with arguments, then on other QA that subscribes for it, it takes those arguments, and does some action with given arguments...

    Probably refreshSubscribe is not suited for this right?

     

    SourceTriggerSubscriber works but it's pretty large now...

    Probably the smallest code is to use the refreshStateSubscriber that comes built in and listen for a globalVariable that changes.

    This is of course not compatible with fibaroExtra, and in general I would avoid running two refreshState loops in a QA (fibaroExtra has one already) - but listening for a global this way would be simple to do in fibaroExtra too - making it compatible.

    Please login or register to see this code.

     

    Edited by jgab
    • Thanks 1
    Link to comment
    Share on other sites

    8 hours ago, jgab said:

    Is Timeon a fibaro global variable?

    In that case

    Please login or register to see this code.

     

    This works Perfect :D TY!!

    Link to comment
    Share on other sites

    • 2 weeks later...

    I must not understand how to use the RefreshStateSubscriber() class. I was listening for the onAction event and I was receiving it. But I found that it was received AFTER the action had been executed, not prior to its being executed. I used the os.clock() method to examine the milliseconds and found that the RefreshStateSubscriber() occurred after the onAction() method. I presumed it would be called prior to control being passed to the onAction handler. I junked that idea and came up with a seemingly reliable method using class variables to store my state. This refers to setting the heating and cooling setpoints for the thermostat. Sadly, the thermostat has a Set button that sends each setpoint to the thermostat. But the thermostat requires BOTH setpoints to be sent to update it when in Auto mode. Now I set a self.eventProcessing flag to true before anything else is done and test for that flag in the other handler (and vice versa). This seems to work reliably. Sometimes the second event even arrives early enough that the first event can pass both new values to the thermostat or the first event calls the second handler directly if the second event occurred while the first event was processing the API call to the cloud. This mechanism works well enough in my limited testing but I worry a bit that maybe they could both happen too close together so as to send the wrong setpoints "simultaneously" (or seemingly so).

     

    Having given that long winded description, I'm curious what the RefreshStateSubscriber() class accomplishes with respect to the onAction() methods. Should I be considering using the RefreshStateSubscriber() class only now I would rely on it to occur only after I have updated the device property which happens on the completion of the call to the cloud?

     

    Thanks in advance.

     

    Peter

    Link to comment
    Share on other sites

  • Topic Author
  • 14 hours ago, PeterV959 said:

    I must not understand how to use the RefreshStateSubscriber() class. I was listening for the onAction event and I was receiving it. But I found that it was received AFTER the action had been executed, not prior to its being executed. I used the os.clock() method to examine the milliseconds and found that the RefreshStateSubscriber() occurred after the onAction() method. I presumed it would be called prior to control being passed to the onAction handler. I junked that idea and came up with a seemingly reliable method using class variables to store my state. This refers to setting the heating and cooling setpoints for the thermostat. Sadly, the thermostat has a Set button that sends each setpoint to the thermostat. But the thermostat requires BOTH setpoints to be sent to update it when in Auto mode. Now I set a self.eventProcessing flag to true before anything else is done and test for that flag in the other handler (and vice versa). This seems to work reliably. Sometimes the second event even arrives early enough that the first event can pass both new values to the thermostat or the first event calls the second handler directly if the second event occurred while the first event was processing the API call to the cloud. This mechanism works well enough in my limited testing but I worry a bit that maybe they could both happen too close together so as to send the wrong setpoints "simultaneously" (or seemingly so).

     

    Having given that long winded description, I'm curious what the RefreshStateSubscriber() class accomplishes with respect to the onAction() methods. Should I be considering using the RefreshStateSubscriber() class only now I would rely on it to occur only after I have updated the device property which happens on the completion of the call to the cloud?

     

    Thanks in advance.

     

    Peter

    Yes, RefreshStateSubscriber should be seen as a "log" - event about what has happened.

    Link to comment
    Share on other sites

    Hi again @jgab :D 

    I am back with a question. The sourcetriggersubscriber works as the triggers in scenes as I understand it 😅

     

    Is it possible to set a duration true for a spesefic time and subscribe too that? with this: 

    Please login or register to see this code.

     

    Like this inn a scene (60sec) :

     

    {
      conditions = { {
          duration = 60,
          id = 1822,
          isTrigger = true,
          operator = "==",
          property = "state",
          type = "device",
          value = false
        } },
      operator = "all"
    }

     

     

    Somthing like this: 

    ----------------FibaroPiroff---------------
     local FibaroPiroff = SourceTriggerSubscriber()
      FibaroPiroff:subscribe(
    {type='device', id=PirFibaroID, value=false, duration=60},
    function(event)                  
    print("FibaroPiroff")
    end)
    ----oninit-----
    FibaroPiroff:run()

     

    it dosent work like this, but is it a way too make it work somthing like this? :D 

     

     

     

     

     

     

    Link to comment
    Share on other sites

  • Topic Author
  • On 2/8/2024 at 6:54 PM, Brors94 said:

    Hi again @jgab :D 

    I am back with a question. The sourcetriggersubscriber works as the triggers in scenes as I understand it 😅

     

    Is it possible to set a duration true for a spesefic time and subscribe too that? with this: 

    Please login or register to see this code.

     

    No, timers and durations are not in sourceTriggerSubscriber (I have a more extensive lib for that)
    But you can achieve it with 2 more rules that watches when the device becomes true and false.

    When false post another event in 60s that is picked up by the first rule, when true cancel the post.

    Please login or register to see this code.

     

    Edited by jgab
    Link to comment
    Share on other sites

    Thanks for the help @jgab :D 

    You gave me an ide on how to do it, ill tried the post and canceling subscribe.
    But got some error and it canceled the sub after the first trigger, so it only worked the first time. 
    but ill do the same with the hub.settimeout :D i think? 😅

     

     

    counter = hub.setTimeout(0, function()end)
    ----------------FibaroPir---------------
     local FibaroPir = SourceTriggerSubscriber()
      FibaroPir:subscribe(
    {type='device', id=PirFibaroID, value=true},
    function(event)                  
    print("FibaroPir")
    PirStatus = 1
    self:setVariable("PirStatus", 1)
     
    hub.clearTimeout(counter)
     
    print("Fibaro pir sourcetrigger on")
    end)
    ----oninit-----
    FibaroPir:run()
     
    ----------------FibaroPiroff---------------
     local FibaroPiroff = SourceTriggerSubscriber()
      FibaroPiroff:subscribe(
    {type='device', id=PirFibaroID, value=false},
    function(event)                  
    print("FibaroPiroff")
     
    counter = hub.setTimeout(3*60*1000, function()
          print("FibaroPiroff  PirStatus check")
          PirStatus = 0
          self:setVariable("PirStatus", 0)
          print("FibaroPiroff  PirStatus off")
    end)
     
    end)
    ----oninit-----
    FibaroPiroff:run()
    Link to comment
    Share on other sites

  • Topic Author
  • 58 minutes ago, Brors94 said:

    Thanks for the help @jgab :D 

    You gave me an ide on how to do it, ill tried the post and canceling subscribe.
    But got some error and it canceled the sub after the first trigger, so it only worked the first time. 
    but ill do the same with the hub.settimeout :D i think? 😅

     

     

    counter = hub.setTimeout(0, function()end)
    ----------------FibaroPir---------------
     local FibaroPir = SourceTriggerSubscriber()
      FibaroPir:subscribe(
    {type='device', id=PirFibaroID, value=true},
    function(event)                  
    print("FibaroPir")
    PirStatus = 1
    self:setVariable("PirStatus", 1)
     
    hub.clearTimeout(counter)
     
    print("Fibaro pir sourcetrigger on")
    end)
    ----oninit-----
    FibaroPir:run()
     
    ----------------FibaroPiroff---------------
     local FibaroPiroff = SourceTriggerSubscriber()
      FibaroPiroff:subscribe(
    {type='device', id=PirFibaroID, value=false},
    function(event)                  
    print("FibaroPiroff")
     
    counter = hub.setTimeout(3*60*1000, function()
          print("FibaroPiroff  PirStatus check")
          PirStatus = 0
          self:setVariable("PirStatus", 0)
          print("FibaroPiroff  PirStatus off")
    end)
     
    end)
    ----oninit-----
    FibaroPiroff:run()

    Your code doesn't work if the sensor is turned off and on within the time...

    What error did you get when you run my example?

    Link to comment
    Share on other sites

  • Topic Author
  • 32 minutes ago, jgab said:

    Your code doesn't work if the sensor is turned off and on within the time...

    What error did you get when you run my example?

    Fixed original post so it works, I think.

    Link to comment
    Share on other sites

    The thing I try to accomplish with it, is a form off extra delay on the off signal of a fibaro Sensor 😅

     

    I use the sourcetrigger for some "Dumb" Presence Sensor that is connected to a S2 input. and the delay are 10min on them and i do not need extra delay on them. 

    and I am trying to get somthing like that with a Fibaro Motion detector too in the same QA and thats why I need some delay on the fibaro sensor in its Off/safe State. But when it turn on/detected it should reset/remove the timer/delay. 

     

    and I like the way the Sourcetrigger works 😄 but it is hard to add an extra delay to it  😅

     

    So when the "PirStatus" QAvar goes to 1 lights should go ON and when it goes to 0 the Lights go off, this works with the S2 inputs. 

     

    And I dont know what is most effective code too do this kinda things. What does put the lowest load on the hc3, since the source subscriber will trigger often when it is a Fibaro pir, But only once every 10 min at max if it is a S2 input.

     


     

     

    Edited by Brors94
    Link to comment
    Share on other sites

  • Topic Author
  • So, I have been rethinking the SourceTrigger function a bit

    This is my new approach - if you are willing to re-learn a bit I believe it solves your problems.

     

    • Thanks 1
    Link to comment
    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...