Announcement

Collapse
No announcement yet.

RegisterEventCB and HSEvent in C#

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

    RegisterEventCB and HSEvent in C#

    My RegisterEventCB function is never invoked. Does anybody see what I messed up here? I know the connection is good because I can turn devices on and off.

    My program is c# .net and is a class library. I am not sure if this does not work will class libraries.

    Code:
            public void RegisterCallback(ref object frm)
            {
                /* 
                 * Call back into HS and get a reference to the HomeSeer ActiveX interface
                 * this can be used make calls back into HS like hs.SetDeviceStatus, etc.
                 * The callback object is a different interface reserved for plug-ins.
                 */
                callback = frm;
    
                hsi.SetHost("localhost");   
                string result = hsi.Connect("default", "default");
                hs = hsi.GetHSRef();
                
                if (hs == null)
                {
                    //Interaction.MsgBox("Unable to access HS interface", MsgBoxStyle.Critical);
                    // UNABLE TO CONNECT TO HOMESEER
                }
                else
                {
                    InterfaceVersion = hs.InterfaceVersion();
                }
                hsi.RegisterEventCB(4, this);
                Test();
            }
    
            public void HSEvent(int evtype, object[] parms)
            {
                string dc = null;
    
                dc = parms.ElementAt(0).ToString();
                hs.WriteLog(IFACE_NAME, "Something happened " + dc);
            }
    Last edited by ; March 18, 2010, 06:13 PM.

    #2
    Does anyone have any ideas?

    Does anyone have any idea why this would not work? I am still stuck on this.

    Code:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public static HomeSeer2.application hsapp;
            public static Scheduler.hsapplication hs;
    
            public Form1()
            {
                InitializeComponent();
    
                hsapp = new HomeSeer2.application();
                hsapp.SetHost("localhost");
                hsapp.Connect("", "");
                hs = hsapp.GetHSRef();
                hsapp.RegisterEventCB(4,this);
            }
    
            public void HSEvent(int evtype, object[] parms)
            {
                label1.Text = "A device just changed state";
            }
        }
    }

    Comment


      #3
      I don't see anything wrong with your code.

      I have experienced unresolved situations similar to yours. I distribute software (tenScripting) that registers for events similiarly and have had a few users who did not receive events.

      Solutions typically are network or firewall related. One we never resolved until he reinstalled his OS for another reason, and then all worked!

      Some things to try. I assume you are running this code on the same computer that HomeSeer is running?

      Make sure you can successfully run speaker.exe on the computer where the register is failing. Check the port specified for speaker.exe. Stop speaker.exe and try using that same port for your code (something like: localhost:8742). Make sure your firewalls or anti-virus, etc have port 8742 open.

      Can you try running on another computer on your home network (same router)?

      Do you have an externally recognizable IP address for your HS computer? If so, I could try connecting to it.

      Good luck. Let us know if you do/do not make any progress.

      tenholde
      tenholde

      Comment


        #4
        Thanks

        I very much appreciate your help.

        I have tried a few of your ideas to try to isolate the problem.

        --------------------------------------------------------------------
        "Some things to try. I assume you are running this code on the same computer that HomeSeer is running?"

        --Yes

        Make sure you can successfully run speaker.exe on the computer where the register is failing. Check the port specified for speaker.exe. Stop speaker.exe and try using that same port for your code (something like: localhost:8742). Make sure your firewalls or anti-virus, etc have port 8742 open.

        -- Speaker.exe is working fine. I tried your suggestion of localhost:8742 with no luck. To be certain that the firewall wasn't breaking things I completely disabled it during the test. Whats odd is that I know my code is connecting to homeseer because in the homeseer log it prints the following:
        "4/5/2010 11:07:57 PM - Network - Remote client connected from: 127.0.0.1" Yet my HSEvent function is never called when a device changes state.

        Some more notes. I downloaded the HSRealTime project from the sticky on this issue. It is basically a demo project on how to use RegisterEventCB. It is written in VB.net and it connects to homeseer and is notified of status changes in real time successfully. So given that fact, I think I can rule out any network, homeseer, or firewall issues. My C# code is a direct port from that code yet for some reason it will not work.

        I also read on the forums that for some reason on a 64-bit windows you need to specify to compile your project for a 32-bit process or you may not receive event notification. I have tried forcing it to 32-bit and that did not work either.

        HSRealTime Sticky...
        http://board.homeseer.com/showthread...EventCB+HSReal

        If you have any other ideas I can give them a shot.

        Thanks for the help.

        Comment


          #5
          Think I just figured it out

          Update I think I just figured it out!

          I think the problem was a difference between how VB and C# handle class references. I think homeseer was unable to see my HSEvent function.

          I made the HSEvent function a static (i.e. it always exist and to call it you don't need to first instantiate a copy of the class). I think the homeseer code must have not been able to see the function without making it a static.

          public static void HSEvent(int evtype, object[] parms)
          {
          //label1.Text = "A device just changed state";
          MessageBox.Show("evtype = " + evtype);
          }

          It looks like I am getting flooded with many events at this point.

          Comment


            #6
            I'm glad it is working.

            tenholde
            tenholde

            Comment


              #7
              Static doesn't work

              Originally posted by metalideath View Post
              Update I think I just figured it out!

              I think the problem was a difference between how VB and C# handle class references. I think homeseer was unable to see my HSEvent function.

              I made the HSEvent function a static (i.e. it always exist and to call it you don't need to first instantiate a copy of the class). I think the homeseer code must have not been able to see the function without making it a static.
              Making HSEvent static generates errors in the HomeSeer Log and the code is never called. I eventually got it to work by setting the projects to AnyCPU and unchecking prefer 32 bit. Futher it doesn't meet the requirements of IPluInAPI so it won't compile.


              If you are working in c#, I strongly recommend using the HomeSeer dlls and specifically IPlugInAPI to get the correct signatures. All you have to do is inherit from HomeSeerAPI.IPlugInAPI and Visual Studio will auto generate all the correct signatures. Futhermore the actual types and enums are in the dlls. It saves a ton of time and effort, especially if you wander into the CAPI space
              Code:
              using HomeSeerAPI;
              
              …
              
              public class HSPI : IPlugInAPI
              For example the autogenerated signature for HSEVent is
              Code:
              public void HSEvent(Enums.HSEvent EventType, object[] parms)
              Enums.HSEvent is defined in HomeSeerAPI.

              Code:
                      public enum HSEvent
                      {
                          LOG = 2,
                          AUDIO = 8,
                          CONFIG_CHANGE = 32,
                          STRING_CHANGE = 64,
                          SPEAKER_CONNECT = 128,
                          CALLER_ID = 256,
                          VALUE_CHANGE = 1024,
                          VALUE_SET = 2048,
                          VOICE_REC = 4096,
                          SETUP_CHANGE = 8192,
                          RUN_SCRIPT_SPECIAL = 16384,
                          GENERIC = 32768
                      }
              Similarly RegisterEventCB takes the defined enums. The signature is:
              Code:
              void RegisterEventCB(Enums.HSEvent evType, string PIName, string PIInstance);
              e.g.

              Code:
                          Callback.RegisterEventCB(Enums.HSEvent.STRING_CHANGE, IFACE_NAME, "");
                          Callback.RegisterEventCB(Enums.HSEvent.CONFIG_CHANGE, IFACE_NAME, "");
                          Callback.RegisterEventCB(Enums.HSEvent.LOG, IFACE_NAME, "");
                          Callback.RegisterEventCB(Enums.HSEvent.VALUE_CHANGE, IFACE_NAME, "");

              Comment


                #8
                This is an old thread so I hope this is still relevant. I ran into a similar problem on HS4.
                I properly register for various events and generic events although I was not receiving the callback into HsEvent() for my registered generic events.

                At one point I registered for a Generic event using the non generic callback:
                Code:
                hs4.RegisterEventCB(Enums.HSEvent.GENERIC, this.Id);
                and everything started working. As an experiment I removed that line and re-ran ... everything was still working just fine.

                My conclusion is that (at least) generic events in the HS platform are, uh, touchy. If they are not working, restart your plugin. Kind of like hitting the side of a TV or kicking a car's tire.

                Comment


                  #9
                  Okay, this is interesting. Apologies for wasting your time if this is already known/obvious. But the docs are not clear on this nor are the samples/source.
                  I was left with the impression that RegisterGenericEventCB() automatically registered your plugin to receive generic events.

                  Observation:
                  A plugin must register to receive generic events using:
                  Code:
                  hs4.RegisterEventCB(Enums.HSEvent.GENERIC, myPluginId);
                  Then it must register for which generic codes it will receive:
                  Code:
                  hs4.RegisterGenericEventCB(myGenericEventId, myPluginId);
                  The important part here is the initial call to RegisterEventCB() to start receiving any generic events.
                  This plugin registration will persist across multiple reboots of your plugin. But it must be called at least once per running instance of the HS.exe.

                  Repo Steps:
                  1. Run HS.exe
                  2. Run your plugin with a call to hs4.RegisterEventCB(Enums.HSEvent.GENERIC, myPluginId);
                  3. Observe generic event callbacks
                  4. Terminate your plugin
                  5. Relaunch your plugin this time with hs4.RegisterEventCB(Enums.HSEvent.GENERIC, myPluginId); disabled/removed.
                  6. Happily continue observing generic event callbacks.
                  7. Terminate your plugin and HS.exe
                  8. Relaunch HS.exe
                  9. Relaunch your plugin this time with hs4.RegisterEventCB(Enums.HSEvent.GENERIC, myPluginId); disabled/removed.
                  10. Notice no generic callbacks.
                  11. Relaunch your plugin with a call to hs4.RegisterEventCB(Enums.HSEvent.GENERIC, myPluginId);
                  12. Rejoice as you observe generic callbacks!
                  It is weird to me that the registration is persisted across instances of the plugin. But at least I now know what I am dealing with.

                  Comment


                    #10
                    Originally posted by mrslother View Post
                    The important part here is the initial call to RegisterEventCB() to start receiving any generic events.
                    This plugin registration will persist across multiple reboots of your plugin. But it must be called at least once per running instance of the HS.exe.


                    It is weird to me that the registration is persisted across instances of the plugin. But at least I now know what I am dealing with.
                    This persistence of the event registration has been a problem for some time. There is no way to unregister for these events. No matter what you do to disconnect your plugin from HS (3 or 4) and then terminate the plugin program, HS keeps trying to send events to your nonexistent plugin and you receive errors in the log.
                    tenholde

                    Comment

                    Working...
                    X