Announcement

Collapse
No announcement yet.

HSPI_MoskusSample - An easier plugin sample [VB.NET]

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

    #76
    Now it works as it should when running it locally on the server. I am not that good with the remoting stuff. Had to rip off https://github.com/alexdresko/HSPI. Thanks a lot to alexdresko for "paving the way".

    Comment


      #77
      Originally posted by Guahtdim View Post
      Now it works as it should when running it locally on the server. I am not that good with the remoting stuff. Had to rip off https://github.com/alexdresko/HSPI. Thanks a lot to alexdresko for "paving the way".
      Excellent! Thanks!
      Fred

      HomeSeer Pro 3.0.0.548, HS3Touch, Zwave 3.0.1.252, Envisalink DSC 3.0.0.40, WeatherXML, Z-stick, HS phone, Way2Call

      Comment


        #78
        Need a little help with CsharpSample.

        Please excuse the total "noob" question, but I'm tired of beating my head against this particular wall.
        I've created a new class (CallMgrCls) which contains a static method called CallMgr. [I have to use
        static methods because the Way2Call driver requires them.] What do I need to add to the new class
        (or method) to be able to use methods in Utils? I created a simple test method that will compile and
        run in a new thread started from InitIO. The first "generic" _utils.log executes, but when it reaches
        the first _utils.log debug statement, it abends with a null reference exception on _settings.

        Any help would be greatly appreciated!

        Here's the code for the class:

        <code>
        using System;

        using System.Configuration;
        using System.Collections.Specialized;
        using System.Collections.Generic;
        using System.Diagnostics;
        using System.Linq;
        using System.Web;
        using System.Reflection;
        using System.Runtime.CompilerServices;
        using System.Text;
        using System.Threading;
        using System.Threading.Tasks;
        using HSPI_CallMgr.Config;
        using HSPI_CallMgr.HomeSeerClasses;
        using HomeSeerAPI;
        using Scheduler;

        namespace HSPI_CallMgr
        {
        public class CallMgrCls
        {
        private Utils _utils;
        private Settings _settings;

        readonly static ConsoleColor cc = Console.ForegroundColor; // Console text color

        private HsCollection _triggers = new HsCollection();

        private IHSApplication _hs;

        public Utils Utils
        {
        get => _utils;
        set
        {
        _utils = value;
        _hs = Utils.Hs;

        }
        }

        public Settings Settings
        {
        get => _settings;
        set => _settings = value;
        }
        // ============================================================ ==================

        // ============================================================ ==================
        public static void CallMgr()
        {
        Console.WriteLine("CallMgr starting");

        Plugin pi = new Plugin();
        Utils _utils = new Utils(pi.Settings);

        _utils.Log("CallMgr starting - generic");

        _utils.Log("CallMgr starting - debug", LogType.Debug);


        ConsoleKeyInfo cki;

        while (true) // Loop indefinitely
        {
        // check if user requesting program exit
        Console.WriteLine("\nWaiting for call. Enter 'x' to exit pgm):");

        cki = Console.ReadKey(false);

        if (cki.KeyChar == 'x')
        {
        break;
        }

        }

        }
        Fred

        HomeSeer Pro 3.0.0.548, HS3Touch, Zwave 3.0.1.252, Envisalink DSC 3.0.0.40, WeatherXML, Z-stick, HS phone, Way2Call

        Comment


          #79
          If the log - CallMgr starting - generic is executed I really don't know

          It is hard to see where the error is, but a null reference exception will normally occure due to something not properly initialized. My guess is that your new utils class does not have the proper settings for HS. You need to add something like
          _utils.Hs=_hs
          within CallMgr() right after
          Utils _utils = new Utils(pi.Settings);

          But this is just speculation since I dont see how you start this thread from InitIO. Why do you start it as a new thread?

          Comment


            #80
            Originally posted by Guahtdim View Post
            If the log - CallMgr starting - generic is executed I really don't know

            It is hard to see where the error is, but a null reference exception will normally occure due to something not properly initialized. My guess is that your new utils class does not have the proper settings for HS. You need to add something like
            _utils.Hs=_hs
            within CallMgr() right after
            Utils _utils = new Utils(pi.Settings);
            Thanks for taking the time to help!!!

            When it throws the exception, it VS2017 highlights the red line below in "public void log" in Utils:

            Code:
            public void Log(string message, LogType logLevel = LogType.Normal)
                    {
                        switch (logLevel)
                        {
                            case LogType.Debug:
            [COLOR=#FF0000] if (_settings.DebugLog)[/COLOR]
                                {
                                    Hs.WriteLog(Utils.PluginName + " Debug", message);
                                }
            When I add _utils.Hs=_hs, I get this error in VS2017:

            Error CS0176 Member 'Utils.Hs' cannot be accessed with an instance reference; qualify it with a type name instead

            But this is just speculation since I dont see how you start this thread from InitIO. Why do you start it as a new thread?
            Well, because I don't know any better! The SDK discussions say to start a new thread out of INITIO so you can return from INITIO quickly, so I just blindly did that.
            Here's how I'm starting the thread:

            CallMgrCls CallMgrCls = new CallMgrCls();
            Thread thread = new Thread(CallMgrCls.CallMgr);
            thread.Start();

            Fred
            Fred

            HomeSeer Pro 3.0.0.548, HS3Touch, Zwave 3.0.1.252, Envisalink DSC 3.0.0.40, WeatherXML, Z-stick, HS phone, Way2Call

            Comment


              #81
              Ahh, but the discussion is if you only have a lot to do in the start. Say you need to load a lot of data or something.
              If all you have to do is create a class go ahead.

              But even more easy:
              Just use the csharpsample and start changing the Plugin.cs to fit your needs.

              Comment


                #82
                Originally posted by Guahtdim View Post
                Just use the csharpsample and start changing the Plugin.cs to fit your needs.
                Well, that's what I did. Remember you're dealing with a total noob to both plugins and C#, so I'm really dense. How can I start my method (CallMgr) containing my event handlers, etc. without tieing up INITIO?

                Fred

                HomeSeer Pro 3.0.0.548, HS3Touch, Zwave 3.0.1.252, Envisalink DSC 3.0.0.40, WeatherXML, Z-stick, HS phone, Way2Call

                Comment


                  #83
                  I think you have chosen a difficult way to learn both C# and Homeseer plugin programming.

                  You should read through the comments in Plugin. cs and get a feel for how the "flow" goes in a plugin.
                  What do you want to accomplish ?
                  As it is now your class is just waiting for keyboard input in the console. That will normally not happen that way in a Homeseer plugin.

                  Comment


                    #84
                    Originally posted by Guahtdim View Post
                    I think you have chosen a difficult way to learn both C# and Homeseer plugin programming.
                    Yeah, I'm sure you're right.

                    You should read through the comments in Plugin. cs and get a feel for how the "flow" goes in a plugin.
                    What do you want to accomplish ?
                    Yep, I've done that. See next answer for the goal.

                    As it is now your class is just waiting for keyboard input in the console. That will normally not happen that way in a Homeseer plugin.
                    That's because I stripped out all the code that does the real work to try to make it easier to see just the code that's causing the problem. The "real" code is a "proof of concept" that monitors a Way2Call Hi-phone interface by registering a bunch of methods for events and then will execute HS triggers when any of those events happen. That part of the code is working fine, except the HS triggers won't fire because of the same error as with _utils.log. I just thought concentrating on solving the one problem with _utils.log was simpler and would probably also solve the trigger problem. Guess I just confused the issue.

                    The base code is pretty much the CsharpSample with just the timer stuff removed, and some Way2Call error-checking and the thread-start added ti InitIO. IniIO code below.

                    Thanks for your help.

                    Here's the code for InitIO.
                    Code:
                            public string InitIO(string port)
                            {
                                Console.WriteLine("Starting initializiation.");
                                //Loading settings before we do anything else
                                _settings.Load();
                    
                                //Registering two pages
                                _utils.RegisterWebPage(ConfigPageName, "Config", "Configuration");
                                // _utils.RegisterWebPage(StatusPageName, "", "Demo test");
                    
                                //Adding a trigger 
                                //_triggers.Add(null, "Random value is lower than");
                    
                                //Adding a second trigger with subtriggers
                                //... so first let us create the subtriggers
                                var subtriggers = new HsTrigger();
                                subtriggers.Add(null, "On the first ring Of the phone");
                                subtriggers.Add(null, "On Each ring Of the phone");
                                subtriggers.Add(null, "When caller i.d. information Is available");
                                subtriggers.Add(null, "When the phone Is answered by a person");
                                subtriggers.Add(null, "When the phone Is answered by Homeseer");
                                subtriggers.Add(null, "When a voicemail message has been left");
                                subtriggers.Add(null, "When a voicemail message has been listened To");
                                subtriggers.Add(null, "When the phone handset Is lifted");
                                subtriggers.Add(null, "When the phone handset Is hung up");
                                subtriggers.Add(null, "When a phone call ends");
                                subtriggers.Add(null, "When digits entered on a telephone match");
                                subtriggers.Add(null, "When the dialed telephone number Is");
                                _utils.Log("Sub-triggers added", LogType.Debug);
                    
                                //... and then the trigger with the subtriggers
                                _triggers.Add(subtriggers, "A telephone Event occurs");
                                _utils.Log("Main trigger added", LogType.Debug);
                    
                                //Adding an action
                                _actions.Add(null, "Send a custom command somewhere");
                                _utils.Log("Action added", LogType.Debug);
                    
                                //Checks if plugin devices are present, and create them if not.
                                //CheckAndCreateDevices();
                                _utils.Log("Devices checked/added", LogType.Debug);
                    
                                // If modem type is 1 (Way2Call Hi-phone), check if Hi-phone is connected
                                if (_settings.ModemType == "1")
                                {
                                    CWay2callDriver w2cDrv = new CWay2callDriver();  // The Way2Call Driver object
                    
                                    int iErr = 0;
                    
                                    CWay2callDriver.Errors w2cErr = CWay2callDriver.Errors.SUCCESS;
                    
                                    Console.Clear();
                                    Console.WriteLine("Initializing Way2call driver ...\n");
                                    _utils.Log("Initializing Way2call HiPhone driver", LogType.Debug);
                    
                                    // Note the CWay2callDriver.Errors usage
                                    w2cErr = (CWay2callDriver.Errors)w2cDrv.InitializeDriver(0);//must be called first
                    
                                    if (CWay2callDriver.Errors.SUCCESS != w2cErr)
                                    {
                                        Console.WriteLine("Error opening the driver ...: " + w2cErr.ToString());
                                        _utils.Log("Error opening the HiPhone driver", LogType.Debug);
                                        iErr = w2cDrv.ShutdownDriver(0);
                                        return "Error opening Hi-phone driver";
                                    }
                    
                                    // no device(s)...
                                    if (w2cDrv.NumDevices == 0)
                                    {
                                        Console.WriteLine("There are no Hi-Phone devices connected to this PC.");
                                        _utils.Log("There are no Hi-Phone devices connected to this PC.", LogType.Debug);
                                        iErr = w2cDrv.ShutdownDriver(0);
                                        return "No hi-phone attached";
                                    }
                    
                                }
                    
                                // FOR TESTING - list all triggers for this plugin
                                TriggerCheck();
                    
                                Console.WriteLine("Initializing done! Ready...");
                                _utils.Log("Initializing done!", LogType.Debug);
                    
                                // Start the thread that does the actual work
                                //CallMgrCls CallMgrCls = new CallMgrCls();
                                //Thread thread = new Thread(CallMgrCls.CallMgr);
                                //thread.Start();
                    
                                // Start the thread that does the actual work
                                Plugin pi = new Plugin();
                                Thread thread = new Thread(pi.CallMgrStart);
                                thread.Start();
                    
                                _utils.Log("CallMgr thread submitted", LogType.Debug);
                    
                                return "";
                            }
                    
                    ​​​​​​​

                    Here's the code for the "real" CallMgr methods. In this early version, only the "On caller ID" handler actually tries to trigger a HS trigger.

                    Code:
                    using System;
                    
                    using System.Configuration;
                    using System.Collections.Specialized;
                    using System.Collections.Generic;
                    using System.Diagnostics;
                    using System.Linq;
                    using System.Web;
                    using System.Reflection;
                    using System.Runtime.CompilerServices;
                    using System.Text;
                    using System.Threading;
                    using System.Threading.Tasks;
                    using HSPI_CallMgr.Config;
                    using HSPI_CallMgr.HomeSeerClasses;
                    using HomeSeerAPI;
                    using Scheduler;
                    //
                    using Way2call;
                    using Way2call.Driver;
                    
                    namespace HSPI_CallMgr
                    {
                        public class CallMgrCls
                        {
                            //private Utils _utils;
                            //private Settings _settings;
                    
                            // Global vars
                            const string sLogo = ".NET Call Manager console application\n";
                            static CWay2callDriver w2cDrv = new CWay2callDriver();  // The Way2Call Driver object
                            readonly static ConsoleColor cc = Console.ForegroundColor;       // Console text color
                            static int MyCallConnected = 0;                         // Call connected flag
                            static int MyCallHangup = 0;                            // Hangup current call flag
                    
                            private HsCollection _triggers = new HsCollection();
                    
                            private IHSApplication _hs;
                    
                            //public Utils Utils
                            //{
                            //    get => _utils;
                            //    set
                            //    {
                            //        _utils = value;
                            //        _hs = Utils.Hs;
                    
                            //    }
                            //}
                    
                            //public Settings Settings
                            //    {
                            //        get => _settings;
                            //        set => _settings = value;
                            //    }
                            // ==============================================================================
                    
                    
                            ///Enum to determine which type of trigger we have
                            ///</summary>
                            private enum TriggerTypes
                            {
                                WithoutSubtriggers = 1,
                                WithSubtriggers = 2
                            }
                    
                            ///Enum to get the subtrigger, if the current trigger type = TriggerTypes.WithSubTriggers (2) for the current Event.
                            ///</summary>
                            private enum SubTriggerTypes
                            {
                                FirstRing = 1,
                                EveryRing = 2,
                                CIDavail = 3,
                                AnswerPerson = 4,
                                AnswerHS = 5,
                                VoiceMailLeft = 6,
                                VoiceMailListened = 7,
                                HandsetLifted = 8,
                                HandsetHungUp = 9,
                                PhoneCallEnds = 10,
                                DigitsMatch = 11,
                                DialedNumberIs = 12
                    
                            }
                            // ==============================================================================
                            //public static void CallMgr()
                            public void CallMgr()
                            {
                                Console.WriteLine("CallMgr starting");
                    
                                Plugin pi = new Plugin();
                                Utils _utils = new Utils(pi.Settings);
                                _utils.Log("CallMgr starting", LogType.Debug);
                    
                    
                                int iErr = 0;
                    
                                ConsoleKeyInfo cki;
                    
                                // int ModemType = 1;                              // Modem type 1 is Hi-phone
                                // This will allow for later addition of other types of modems
                    
                                // if modem is a Way2Call Hi-phone, process using these methods
                                // if (ModemType == 1)
                                //{
                                // Note the CWay2callDriver.Errors usage
                                CWay2callDriver.Errors w2cErr = CWay2callDriver.Errors.SUCCESS;
                    
                    
                                Console.WriteLine(sLogo);
                    
                                // add the event handlers. Note that these are REQUIRED to be static.
                    
                                // Generic handler - just shows events received
                                CWay2callDriver.OnNativeDeviceEvent +=
                                    new CWay2callDriver.DelegateNativeDeviceEvent(CWay2callDriver_OnNativeDeviceEvent);
                    
                                // When Hi-phone detects call connected
                                CWay2callDriver.OnCallConnected +=
                                    new CWay2callDriver.DelegateNoParams(CWay2callDriver_OnCallConnected);
                    
                                // Silence detected on line
                                CWay2callDriver.OnSilentDetected += new CWay2callDriver.DelegateNoParams(CWay2callDriver_OnSilentDetected);
                    
                                // Line current drop detected on line
                                CWay2callDriver.OnLineCurrentDrop +=
                                    new CWay2callDriver.DelegateNoParams(CWay2callDriver_OnLineCurrentDrop);
                    
                                // Caller id info has been received
                                CWay2callDriver.OnCallerID +=
                                   new CWay2callDriver.DelegateOnCallerID(CWay2callDriver_OnCallerID);
                    
                                // Async playback completed - raised when an audio file finishes playing
                                CWay2callDriver.OnAsyncPlaybackDone +=
                                    new CWay2callDriver.DelegateNoParams(CWay2callDriver_OnAsyncPlaybackDone);
                    
                    
                                Console.WriteLine("Driver version: " + w2cDrv.Version.ToString() + "\n");
                    
                                //assume device #0 exists
                                w2cErr = (CWay2callDriver.Errors)w2cDrv.Device.Open(0);//open the device
                                if (CWay2callDriver.Errors.SUCCESS != w2cErr)
                                {
                                    Console.WriteLine("Error opening the device ...: " + w2cErr.ToString());
                                    iErr = w2cDrv.ShutdownDriver(0);//must be last called
                                    return;
                                }
                    
                                // Setup the Hiphone unit from ini file
                                Setup_hip();
                                //}
                    
                                Console.WriteLine("Checking for triggers");
                                //Plugin pi = new Plugin();
                                //Utils _utils = new Utils(pi.Settings);
                                pi.TriggerCheck();
                    
                                while (true) // Loop indefinitely
                                {
                                    // check if user requesting program exit
                                    Console.WriteLine("\nWaiting for call.  Enter 'x' to exit pgm):");
                    
                                    cki = Console.ReadKey(false);
                    
                                    if (cki.KeyChar == 'x')
                                    {
                                        break;
                                    }
                    
                                }
                    
                                iErr = w2cDrv.Device.Close(0);      //close the device
                    
                                iErr = w2cDrv.ShutdownDriver(0);    //shut down the driver - must be last called 
                    
                            }
                    
                            // -------------------------------------------------------------------------
                            // generic / native device event handler
                            static void CWay2callDriver_OnNativeDeviceEvent(ushort DeviceID, uint Event, uint EventData, uint EventDataEx, byte[] pEventBuffer)
                            {
                                //print event's description
                                Console.ForegroundColor = ConsoleColor.DarkCyan;
                                Console.WriteLine("Device Event: " + w2cDrv.Device[DeviceID].EventDescription(Event, EventData));
                                Console.ForegroundColor = cc;
                            }
                    
                            // -------------------------------------------------------------------------
                            // line current dropped (remote hung up) so we set flag and hang up call
                            static void CWay2callDriver_OnLineCurrentDrop(ushort DeviceID)
                            {
                                Console.WriteLine("Caller hung up\n");
                    
                                w2cDrv.Device.HangUp(false);
                    
                                // MyCallHangup = 0;
                                Hangup();
                    
                            }
                    
                            // -------------------------------------------------------------------------
                            // call connected event handler (for outbound calls)
                            static void CWay2callDriver_OnCallConnected(ushort DeviceID)
                            {
                                if (0 != MyCallConnected)
                                    return;//event may be fired mutiple times
                    
                                MyCallConnected = 1;//mark call connected;
                    
                                // unmute local device
                                w2cDrv.Device.AudioControl.LocalDeviceToLine = CWay2callDriver.CDevice.CAudioControl.SIGNAL_SWITCH.UnMute;
                    
                                // connect local device to both line and PC audio
                                w2cDrv.Device.SwitchingMode = CWay2callDriver.CDevice.SwitchingModes.Line_PcAudio_Phone;
                    
                                Console.WriteLine("Call connected\n");
                    
                                return;
                            }
                            // -------------------------------------------------------------------------
                            // Caller ID info received handler
                            static void CWay2callDriver_OnCallerID(ushort DeviceID, string sCid)
                            {
                    
                                Console.ForegroundColor = ConsoleColor.DarkCyan;
                                Console.WriteLine("CID detected\n");
                                Console.WriteLine("CID string: " + sCid + "\n");
                                Console.ForegroundColor = cc;
                    
                                Console.WriteLine("Calling TriggerCheckFire ");
                    
                    
                                //Getting all triggers for this plugin (this only returns triggers where it is the FIRST option in an event, not when it's used as a condition)
                                //HomeSeerAPI.IPlugInAPI.strTrigActInfo[] triggers = _utils.Callback.GetTriggers(Utils.PluginName);
                    
                                //Console.WriteLine("\tTriggers found: " + Utils.triggers.Count());
                    
                                Plugin pi = new Plugin();
                                pi.TriggerCheckFire();
                    
                                return;
                            }
                            // -------------------------------------------------------------------------
                            // silence-detection event handler
                            static void CWay2callDriver_OnSilentDetected(ushort DeviceID)
                            {
                                Console.ForegroundColor = ConsoleColor.DarkCyan;
                                Console.WriteLine("Silence detected\n");
                                Console.ForegroundColor = cc;
                    
                            }
                            // -------------------------------------------------------------------------
                            // playback done event handler
                            static void CWay2callDriver_OnAsyncPlaybackDone(ushort DeviceID)
                            {
                                Console.WriteLine("\n Announcement fileplay is complete.");
                    
                                if (0 == MyCallHangup)
                                    return;
                    
                                // call should now be hung up
                                Hangup();
                    
                            }
                            // -------------------------------------------------------------------------
                            // Setup Hi-Phone
                            static void Setup_hip()
                            {
                                Console.WriteLine("Setting up the Hi-Phone...\n");
                            }
                            // -------------------------------------------------------------------------
                            // Hangup Hi-Phone
                            static void Hangup()
                            {
                                Console.WriteLine("Hanging up the Hi-Phone...\n");
                    
                                w2cDrv.Device.HangUp(false);
                    
                                MyCallHangup = 0;
                            }
                         }
                    }

                    Fred

                    HomeSeer Pro 3.0.0.548, HS3Touch, Zwave 3.0.1.252, Envisalink DSC 3.0.0.40, WeatherXML, Z-stick, HS phone, Way2Call

                    Comment


                      #85
                      I would probably do this first:
                      Create a standalone Console application that does what you want without involving Homeseer. As it is I think you need to focus on the main problem - Connecting to Way2Call and see that you can register the different events that you want to trigger in HomeSeer. Just use the most primitive method we have: Console.WriteLine("Something happend!")

                      When you have a working console application up and running, catching all the events you want to trigger then you try to make it into a plugin.
                      I often start that way since I get a much shorter develop/see response cycle. If you involve HomeSeer in the early stages you only add more complication.

                      Test-driven development would also be a good idea since you might have to split out the Way2CallDriver just for easier testing of your application.

                      Comment


                        #86
                        Originally posted by Guahtdim View Post
                        I would probably do this first:
                        Create a standalone Console application that does what you want without involving Homeseer.
                        That's exactly what I did! The standalone version works fine. In fact, the plugin version using threading works fine except for accessing methods from Utils! It will catch the Way2Call events and display the Console.Writeline code. I'm going to put aside the _utils.Log issue for now and work on testing trigger processing. I know I had similar issues with that, but I'll collect some testing detail and then post.

                        Thanks again for your help!

                        Fred

                        HomeSeer Pro 3.0.0.548, HS3Touch, Zwave 3.0.1.252, Envisalink DSC 3.0.0.40, WeatherXML, Z-stick, HS phone, Way2Call

                        Comment


                          #87
                          OK, I decided to take a step back. Here's what I did:
                          1. Created a fresh copy of CsharpSample - Master
                          2. Built it and verified that it runs correctly.
                          3. Added a new method to Plugin.cs called TriggerCheck. [code is below]. It just lists triggers for this plugin to the console.
                          4. Added a call to TriggerCheck in InitIO. [code below]
                          5. Rebuilt and verified that the new method ran properly.
                          6. Added my simplified CallMgrCls to the project. [code below]
                          7. Added a thread start to InitIO to start the CallMgr method.
                          8. Rebuilt
                          9. Ran new build in debug. TriggerCheck in InitIO runs properly. Thread for CallMgr starts properly and shows "CallMgr starting" on the console.
                          The call to TriggerCheck abends with a "null reference" exception for _utils on the line :
                          HomeSeerAPI.IPlugInAPI.strTrigActInfo[] triggers = _utils.Callback.GetTriggers(Utils.PluginName);

                          I tried adding the _utils.hs = .hs that you suggested, but it gives a compiler error of:

                          Error CS0176 Member 'Utils.Hs' cannot be accessed with an instance reference; qualify it with a type name instead

                          If I can just get by this issue of being able to access the trigger-related stuff in Utils, I'd be ready to rock and roll.

                          I know it's asking a lot, but if you could just recreate what I've done here, you'll be able to see exactly what's happening.

                          Thanks!

                          Code for TriggerCheck

                          Code:
                          #region "Test routines"
                          
                                  // ====================================================================
                                  // Check triggers and list them to console
                                  // ====================================================================
                                  public void TriggerCheck()
                                  {
                                      Console.WriteLine("TriggerCheck has been called");
                                      Console.WriteLine("Looking for triggers for plugin: " + Utils.PluginName);
                          
                                      //Getting all triggers for this plugin (this only returns triggers where it is the FIRST option in an event, not when it's used as a condition)
                                      HomeSeerAPI.IPlugInAPI.strTrigActInfo[] triggers = _utils.Callback.GetTriggers(Utils.PluginName);
                          
                                      Console.WriteLine("\tTriggers found: " + triggers.Count());
                          
                                      foreach (var trigger in triggers)
                                      {
                                          Console.WriteLine("Event found with ref:  " + trigger.evRef);
                                      }
                                  }
                          
                                  #endregion
                          Code for InitIO

                          Code:
                                  public string InitIO(string port)
                                  {
                                      Console.WriteLine("Starting initializiation.");
                                      //Loading settings before we do anything else
                                      _settings.Load();
                                      //Registering two pages
                                      _utils.RegisterWebPage(ConfigPageName, "Config", "Configuration");
                                      _utils.RegisterWebPage(StatusPageName, "", "Demo test");
                          
                                      //Adding a trigger 
                                      _triggers.Add(null, "Random value is lower than");
                                      //Adding a second trigger with subtriggers
                                      //... so first let us create the subtriggers
                                      var subtriggers = new HsTrigger();
                                      subtriggers.Add(null, "Random value is lower than");
                                      subtriggers.Add(null, "Random value is equal to");
                                      subtriggers.Add(null, "Random value is higher than");
                          
                                      //... and then the trigger with the subtriggers
                                      _triggers.Add(subtriggers, "Random value is...");
                                      //Adding an action
                                      _actions.Add(null, "Send a custom command somewhere");
                          
                                      //Checks if plugin devices are present, and create them if not.
                                      CheckAndCreateDevices();
                          
                                      //'Starting the update timer; a timer for fetching updates from the web (for example). However, in this sample, the UpdateTimerTrigger just generates a random value. (Should ideally be placed in its own thread, but I use a Timer here for simplicity).
                                      _updateTimer = new System.Threading.Timer(new TimerCallback(UpdateRandomValue), null, Timeout.Infinite,
                                          _settings.TimerInterval);
                                      RestartTimer();
                          
                                      // FOR TESTING - list all triggers for this plugin
                                      TriggerCheck();
                          
                                      // Start the thread that does the actual work
                                      CallMgrCls CallMgrCls = new CallMgrCls();
                                      Thread thread = new Thread(CallMgrCls.CallMgr);
                                      thread.Start();
                          
                                      Console.WriteLine("Initializing done! Ready...");
                          
                                      return "";
                                  }
                          Code for CallMgrCls

                          Code:
                          using System;
                          
                          using System.Configuration;
                          using System.Collections.Specialized;
                          using System.Collections.Generic;
                          using System.Diagnostics;
                          using System.Linq;
                          using System.Web;
                          using System.Reflection;
                          using System.Runtime.CompilerServices;
                          using System.Text;
                          using System.Threading;
                          using System.Threading.Tasks;
                          using HSPI_CsharpSample.Config;
                          using HSPI_CsharpSample.HomeSeerClasses;
                          
                          using HomeSeerAPI;
                          using Scheduler;
                          
                          namespace HSPI_CsharpSample
                          {
                              public class CallMgrCls
                              {
                                  //private Utils _utils;
                                  //private Settings _settings;
                          
                                  //private HsCollection _triggers = new HsCollection();
                          
                                  private IHSApplication _hs;
                          
                          
                                  // ==============================================================================
                          
                                  // ==============================================================================
                                  public void CallMgr()
                                  {
                                      Console.WriteLine("CallMgr starting");
                          
                                      Plugin pi = new Plugin();
                                      Utils _utils = new Utils(pi.Settings);
                                      //_utils.Hs = _hs;
                          
                          
                                      pi.TriggerCheck();
                          
                                      ConsoleKeyInfo cki;
                          
                                      while (true) // Loop indefinitely
                                      {
                                          // check if user requesting program exit
                                          Console.WriteLine("\nWaiting for call.  Enter 'x' to exit pgm):");
                          
                                          cki = Console.ReadKey(false);
                          
                                          if (cki.KeyChar == 'x')
                                          {
                                              break;
                                          }
                          
                                      }
                                  }
                               }
                          }
                          Fred

                          HomeSeer Pro 3.0.0.548, HS3Touch, Zwave 3.0.1.252, Envisalink DSC 3.0.0.40, WeatherXML, Z-stick, HS phone, Way2Call

                          Comment


                            #88

                            Keep rewriting this post over and over again.

                            1. Do not create a new Plugin class inside CallMgrCls since this new class has no idea about all the stuff set up in the first Plugin created in Hspi.cs. You are better off asigning the existing plugin to your new class on New or as a property.

                            (this code is not good code, but it might get you started)

                            // Start the thread that does the actual work
                            CallMgrCls callMgrCls = new CallMgrCls();
                            callMgrCls.Plugin=this;
                            Thread thread = new Thread(CallMgrCls.CallMgr);
                            thread.Start();
                            ..
                            ..

                            in CallMgrCls
                            public class CallMgrCls {
                            private Plugin _plugin;
                            public Plugin Plugin {
                            set { _plugin=value; }
                            }
                            ..
                            ..
                            (remove the following 3 lines)
                            Plugin pi = new Plugin();
                            Utils _utils = new Utils(pi.Settings);
                            //_utils.Hs = _hs;

                            (replace pi.TriggerCheck(); with the following line)
                            _plugin.TriggerCheck();


                            This might work, but it is an ugly beast.

                            Comment


                              #89
                              Originally posted by Guahtdim View Post
                              Keep rewriting this post over and over again.

                              1. Do not create a new Plugin class inside CallMgrCls since this new class has no idea about all the stuff set up in the first Plugin created in Hspi.cs. You are better off asigning the existing plugin to your new class on New or as a property.

                              (this code is not good code, but it might get you started)

                              // Start the thread that does the actual work
                              CallMgrCls callMgrCls = new CallMgrCls();
                              callMgrCls.Plugin=this;
                              Thread thread = new Thread(CallMgrCls.CallMgr);
                              thread.Start();
                              ..
                              ..

                              in CallMgrCls
                              public class CallMgrCls {
                              private Plugin _plugin;
                              public Plugin Plugin {
                              set { _plugin=value; }
                              }
                              ..
                              ..
                              (remove the following 3 lines)
                              Plugin pi = new Plugin();
                              Utils _utils = new Utils(pi.Settings);
                              //_utils.Hs = _hs;

                              (replace pi.TriggerCheck(); with the following line)
                              _plugin.TriggerCheck();


                              This might work, but it is an ugly beast.
                              Thanks so much for your help. Unfortunately, the changes above almost work, but not quite. The info below is strictly for your information, as I believe this would be an issue for anyone trying to use the CsharpSample with static methods! I am not requesting any further help! CsharpSample is great work and has helped me greatly in understanding how the pieces of a HS plugin fit together - it's just not going to work for me because of the Way2Call requirement that event handlers be static.

                              Using your suggested changes, because CallMgr is a static method, VS2017 still gives the CS0120 error saying that an object reference is required. I've done a lot of reading this morning (again) of the Microsoft C# documentation, as well as lots of posts on StackOverflow regarding similar issues. I know from experimenting that the issue is strictly related to trying to call a non-static method from within a static method - TriggerCheck in this case, but it applies to any of the methods in the sample.

                              Just to eliminate the extra class (CallMgrCls) as a possibility, I created another version where the simplified test CallMgr method is just included in the Plugin class. That works fine as long as CallMgr is not static. TriggerCheck runs fine from within CallMgr, and even _utils.Log works fine. But as soon as I change CallMgr to static, then the
                              CS0120 An object reference is required for the non-static field, method, or property 'Plugin.TriggerCheck()' error returns.

                              My conclusion is that there is something about the way CsharpSample is structured that just makes it impossible to use a static method with it .
                              Fred

                              HomeSeer Pro 3.0.0.548, HS3Touch, Zwave 3.0.1.252, Envisalink DSC 3.0.0.40, WeatherXML, Z-stick, HS phone, Way2Call

                              Comment


                                #90
                                Have you tried the delegates as non static? I don't understand why you need them to be static.

                                Comment

                                Working...
                                X