Announcement

Collapse
No announcement yet.

I struggle to understand how to use Triggers in HS4

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    I struggle to understand how to use Triggers in HS4

    I may be completely stupid, but I struggle to understand how to use Triggers in HS4.

    I want to check if particular trigger should be fired, obviously. So I call one of
    Code:
    hs.TriggerMatches
    hs.GetTriggersByType
    hs.GetTriggersByInterface
    (already confusing - which one?)

    So I get an array of TrigActInfo. Now I need to compare some property of each trigger with some value. How? I need to de-serialize TrigActInfo to AbstractTriggerType, right?

    In your sample plugin you construct SampleTriggerType explicitly because you have only one trigger type. If I have multiple triggers/subtriggers - what do I do? Just try to construct each one from TrigActInfo and see if it fails? I'm lost...

    The wonderful SDK provides wonderful function
    Code:
    private AbstractTriggerType GetObjectFromTrigInfo(TrigActInfo trigInfo)
    That's what I need. But it's PRIVATE?

    #2
    Alex,
    here is what i did.

    #1 I used an event between my generic plugin code and the hspi object. testinfo is a trigactinfo object which i store the triger/subtrig number. dvref is the device i want to check against the trigger

    RaiseEvent onCheckTrigger(TestInfo, dvref)

    #2 here is the code that runs on the Event

    Code:
    Sub CheckTrigger(TestInfo As TrigActInfo, dvref As Integer) ' handles hsapi.onchecktrigger
    
    Dim TrigsToCheck() As TrigActInfo
    
    Try
    
    TrigsToCheck = hs4.GetTriggersByType(Name, InsteonTriggersClass.TriggerNumber)
    
    For Each TrigCheck In TrigsToCheck
    
      Dim ConfiguredTrigger = New InsteonTriggersClass(TrigCheck, Me) ' build the trigger from the data
    
      If ConfiguredTrigger.ShouldTriggerFire(TestInfo, dvref) Then ' this is my custom method in order to pass in the dvref
          hs4.TriggerFire(Id, TrigCheck)
      End If
    Next
    
    Catch ex As Exception
    gLogManager.ReportError("CheckTrigger", ex)
    End Try
    
    End Sub
    #3 here is my custom method in the trigger class this will compare the testinfo and dvref to see if matches the configured trigger. if so, return True

    Code:
    Public Function ShouldTriggerFire(TC As TrigActInfo, dvref As Integer) As Boolean
    
    If TC.SubTANumber = SelectedSubTriggerIndex Then
    
      Select Case SelectedSubTriggerIndex
    
      Case INSTEON_TRIGGER_TYPES.STARTRAMPDOWN, INSTEON_TRIGGER_TYPES.STARTRAMPUP, INSTEON_TRIGGER_TYPES.RAMPUP1, INSTEON_TRIGGER_TYPES.RAMPDOWN1, INSTEON_TRIGGER_TYPES.RAMPSTOP
       Return GetSelectedOptionKey(ConfigPage.GetViewById(DeviceFieldName) ) = dvref.ToString
    hope this helps
    Mark

    HS3 Pro 3.0.0.534
    Hardware: Insteon Serial PLM | AD2USB for Vista Alarm | HAI Omnistat2 | 1-Wire HA7E | RFXrec433 | Dahua Cameras | LiftMaster Internet Gateway
    Plugins: Insteon (mine) | Vista Alarm (mine) | Omnistat 3 (by Kirby) | Ultra1Wire3 | RFXCOM | NetCAM | MyQ | BLRadar | BLDenon | Jon00 Charting
    Platform: HP h8-1360t, Windows Server 2012 R2, i7-3.4GHz, 16GB memory

    Comment


      #3
      Thank you Mark,

      That's exactly what I mean - you assume the trigger is InsteonTriggersClass - same as sample plugin. I'm getting there, slowly.
      TrigActInfo has TANumber - which I use to construct proper trigger instance.

      In my calendar class I get all triggers matching the calendar ID:

      Click image for larger version

Name:	Screenshot 2021-01-29 013248.jpg
Views:	118
Size:	49.5 KB
ID:	1452009

      Base abstract controller class (in my base lib):

      Click image for larger version

Name:	Screenshot 2021-01-29 013403.jpg
Views:	115
Size:	108.8 KB
ID:	1452010

      And derived Calendar controller:

      Click image for larger version

Name:	Screenshot 2021-01-29 013711.jpg
Views:	113
Size:	19.1 KB
ID:	1452011

      Comment


        #4
        Alex,

        Right now i only have one triggerclass. I thought that was the preferred approach like a single actionclass with sub actions

        I have a list of sub-triggers (about 13) within my single triggerclass.

        If I add a second triggerclass then I will need to do something like you outline above. But that is way down the road from where I am at right now.

        As we discussed, after going through the hs2 to hs3 migration; its nearly impossible to write the perfect abstract layer that will work with the next hs version; So I'm ok with making a few assumptions here and there. don't drive yourself crazy
        Mark

        HS3 Pro 3.0.0.534
        Hardware: Insteon Serial PLM | AD2USB for Vista Alarm | HAI Omnistat2 | 1-Wire HA7E | RFXrec433 | Dahua Cameras | LiftMaster Internet Gateway
        Plugins: Insteon (mine) | Vista Alarm (mine) | Omnistat 3 (by Kirby) | Ultra1Wire3 | RFXCOM | NetCAM | MyQ | BLRadar | BLDenon | Jon00 Charting
        Platform: HP h8-1360t, Windows Server 2012 R2, i7-3.4GHz, 16GB memory

        Comment


          #5
          Originally posted by mnsandler View Post
          don't drive yourself crazy
          I try. I have 12 plugins, and have more plans... So it's nice to have a good library. So the plugin code itself is pretty minimal.

          For example, in all plugins I have a table of all my devices, below a couple of examples (AKGoogleCalendar and AKShelly).

          The library code takes care of generating HTML (from single template), JS, adding controls and handling postback.

          So I don't need to create any HTML pages manually at all.

          And the complete source code for building AKGoogleCalendar table below.

          Click image for larger version

Name:	MyDevicesFeaturePage.png
Views:	110
Size:	49.0 KB
ID:	1452024

          Click image for larger version

Name:	MyDevices.jpg
Views:	108
Size:	74.6 KB
ID:	1452025

          Click image for larger version

Name:	Screenshot 2021-01-29 021356.jpg
Views:	109
Size:	147.5 KB
ID:	1452026

          Comment


            #6
            And for AKGoogleCalendar main Settings page:

            Click image for larger version

Name:	settings.png
Views:	112
Size:	66.4 KB
ID:	1452028

            Click image for larger version

Name:	Screenshot 2021-01-29 021802.jpg
Views:	108
Size:	151.3 KB
ID:	1452029

            Comment


              #7
              Hi mnsandler , I know this is a few months old but I am struggling with this as well. I think I got most of it right, but you've got me puzzled on the "event" thing: "#1 I used an event between my generic plugin code and the hspi object."

              Can you elaborate on how you've implemented this? Thanks!
              stefxx

              Comment


                #8
                Never mind. The issue was that EventTriggerReceived needs a reference to the HSPI object, which is unavailable outside the HSPI class. So I created a global variable holding a reference to it. Problem solved!
                stefxx

                Comment


                  #9
                  Originally posted by stefxx View Post
                  Never mind. The issue was that EventTriggerReceived needs a reference to the HSPI object, which is unavailable outside the HSPI class. So I created a global variable holding a reference to it. Problem solved!
                  Code:
                  protected AbstractTriggerType(int id, int eventRef, int selectedSubTriggerIndex, byte[] dataIn, TriggerTypeCollection.ITriggerTypeListener listener, bool logDebug = false)
                  The listener should be your HSPI object, as I remember you should add ITriggerTypeListener interface to your HSPI for that

                  Comment


                    #10
                    I used it in my some plugins, if you stefxx need - I can dig it out

                    Comment


                      #11
                      HI. I have my triggers working now, but being able to trigger an event in the HSPI class, outside of the class is something I still don't quite understand and might come-in handy one day. I wouldn't mind an example on how you've accomplished that. Just as a learning experience for myself!
                      stefxx

                      Comment


                        #12
                        Originally posted by stefxx View Post
                        HI. I have my triggers working now, but being able to trigger an event in the HSPI class, outside of the class is something I still don't quite understand and might come-in handy one day. I wouldn't mind an example on how you've accomplished that. Just as a learning experience for myself!
                        It's actually handy to read docs (comments):

                        /// <summary>
                        /// The base implementation of a trigger type interface that facilitates communication between
                        /// <see cref="AbstractTriggerType"/>s and the <see cref="AbstractPlugin"/> that owns them.
                        /// <para>
                        /// Extend this interface and have your <see cref="AbstractPlugin"/> implementation inherit it to make it
                        /// accessible through the <see cref="AbstractTriggerType.TriggerListener"/> field.
                        /// </para>
                        /// </summary>
                        public interface ITriggerTypeListener {}
                        So you do
                        Code:
                        public interface IMyTriggerTypeListener ITriggerTypeListener
                        {
                            // Your methods declarations here
                        }
                        
                        public class HSPI : AbstractPlugin, IMyTriggerTypeListener
                        {
                           // Your IMyTriggerTypeListener implementations here
                        }
                        Then inside your triggers (derived from AbstractTriggerType) you access it via TriggerListener member:

                        public abstract class AbstractTriggerType {
                        /// <summary>
                        /// An interface reference to the plugin that owns this trigger type.
                        /// <para>
                        /// Define your own interface that inherits from <see cref="TriggerTypeCollection.ITriggerTypeListener"/>
                        /// and then cast this as the type you defined to get a reference to your plugin that can handle any methods
                        /// you wish to define.
                        /// </para>
                        /// </summary>
                        public TriggerTypeCollection.ITriggerTypeListener TriggerListener { get; internal set; }
                        }

                        Comment

                        Working...
                        X