Announcement

Collapse
No announcement yet.

SetDeviceValueByRef vs CAPIControlHandler

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

  • alexbk66
    replied
    Originally posted by bsobel View Post

    Correct. CapiControll is always OUTGOING control to a device, SetDeviceValue is INCOMING to drive the UI. The RaspBerriPi plugin should be setting the value after controlling the IO board, just bug that it's not.
    Click image for larger version

Name:	good.png
Views:	42
Size:	8.2 KB
ID:	1281602

    Leave a comment:


  • bsobel
    replied
    Originally posted by alexbk66 View Post
    Thanks again Bill.
    So, if I understand correctly - in my plugin to control devices (both my and others) I always use CapiControlHandler.
    And in SetIOMulti I use SetDeviceValueByRef.
    And in case of RaspberryIO - I use both just because it's a problem in the plugin, and until the developer fixes the problem?
    Correct. CapiControll is always OUTGOING control to a device, SetDeviceValue is INCOMING to drive the UI. The RaspBerriPi plugin should be setting the value after controlling the IO board, just bug that it's not.

    Leave a comment:


  • alexbk66
    replied
    Originally posted by bsobel View Post
    Read this a few times, it will click, I promise...
    Thanks again Bill.
    So, if I understand correctly - in my plugin to control devices (both my and others) I always use CapiControlHandler.
    And in SetIOMulti I use SetDeviceValueByRef.
    And in case of RaspberryIO - I use both just because it's a problem in the plugin, and until the developer fixes the problem?

    Leave a comment:


  • alexbk66
    replied
    Originally posted by aa6vh View Post
    The SetDeviceValue/SetDeviceValueByName was how they did it in the old days, before the CAPI stuff was implemented. It does not work properly now. Unfortunately, the documentation has not caught up yet.
    I think it's opposite - in HS3 they removed this simple functionality (in HS2 function was called something like SendValue or similar). And introduced CAPI - and developers complained that lots of scripts were broken and opened a poll asking for this functionality in HS3. So HS added SetDeviceValueByName. But I could be wrong...

    Leave a comment:


  • bsobel
    replied
    Originally posted by alexbk66 View Post
    Thank you Bill I'm not really "confused" - I was using CapiControlHandler, but for RaspberryIO it wasn't showing in HS, but SetDeviceValueByRef was showing in HS, but wasn't changing outputs - that's the problem.

    Also, I'm not sure which one really should be used in SetIOMulti()? All examples and Help use SetDeviceValueByRef. And I did have problems with CapiControlHandler here.

    I reckon something is wrong with HS here - both functions should behave the same IMHO. Why do they have different effect?
    Alex, you are confused (sorry, again its a normal part of learning this system). They do not do the same thing. In the example you mentioned (RaspberryPi) it sounds like a plugin bug you ran into that calling CapiControlHandler is not updating the device values. You should report that to the plugin author.

    SetIOMulti is what is called to actually change a device, while SetDeviceValue is what is called to update the HS UI for the device. Lets take an example that will help:

    DeviceX is a wifi light bulb. It has a plugin to control it from HS, and can also be controlled locally.
    DeviceX supports ON and OFF.
    The plugin exposes two controls set as both (so both status and control). One is the 'Off' and has the value 0 in HS, and On which has the value 9999

    When a user clicks on the 'On' button on the device management page, or an event wants to turn the light On. It looks up the 'On' value and sends it via the capicontrolhandler. The plugin responsible for controlling that device type receives it in its SetIOMulti() and then is expected to PHYSICALLY CHANGE THE LIGHT TO ON (e.g. send the actual TCP or UDP data to the device to force a state change). If the change is successful (e.g. no errors sending the state change to DeviceX) then you should call SetDeviceByValue() to update the HomeSeer UI. The docs state this directly; "If setting the value in the hardware fails, do not call hs.SetDeviceValueByRef and log a warning or error message."

    Now if the light is on and a user turns it off from a wall switch or say a non HS related app on their phone. In that case the plugin determines the light is off (maybe it polls for status like JowiHue does for the Hue bridge, or maybe it receives an updated message via TCP like the Tuya bulbs do, or maybe smoke signals are used ,) point is the plugin determine the device is off). In that case the device does NOT need to physically change anything on the bulb, it JUST needs to update the HomeSeer UI. So it calls SetDeviceValue with 0 so the UI reflects 'Off'.

    Read this a few times, it will click, I promise...

    Bill

    Leave a comment:


  • aa6vh
    replied
    Originally posted by alexbk66 View Post

    Sorry, my bad - I meant SetDeviceValueByName (not SetDeviceStringByName)
    The SetDeviceValue/SetDeviceValueByName was how they did it in the old days, before the CAPI stuff was implemented. It does not work properly now. Unfortunately, the documentation has not caught up yet.

    Leave a comment:


  • alexbk66
    replied
    Originally posted by aa6vh View Post
    What was said above. But since you asked about DeviceString, here is my understanding of where one would utilize the DeviceString:
    Sorry, my bad - I meant SetDeviceValueByName (not SetDeviceStringByName)

    Leave a comment:


  • aa6vh
    replied
    Originally posted by alexbk66 View Post
    2. Since you use the device name anyway - why not just call SetDeviceStringByName?
    What was said above. But since you asked about DeviceString, here is my understanding of where one would utilize the DeviceString:

    A device will have pairs of numeric numbers and corresponding labels. For example, a standard binary switch might have 0 and off, and 100 and on. The "off" and "on" can be changed to whatever you want, but that label is associated with that value.

    HS uses the value when setting a device, not the label. The label is for us humans. (BTW, a label text string can be associated with a range of values, such as on a dimmer). A label is locked to its corresponding value (or values).

    On some devices, you might want to use something more than that label. For example on a thermostat, you might want to see a label that is more useful than the label associated with the value - label pair. For example, instead of just having "72 F" for a label, you might want a label that says "72 F (Heater is on)". You set that modified label using the DeviceString call. It sets the device's label to that string, but does not change the value (or state) of the device.

    So you use CapiControl to change the value or state of a device. You use DeviceString if you want the text associated with that device to be something different. The UI will use the DeviceString if it is non-blank, otherwise it uses the label that is associated with the device's current value.

    Hopefully I got that right. I am sure someone will correct me otherwise!

    Leave a comment:


  • MattL0
    replied
    Originally posted by alexbk66 View Post
    MattL0 what do you mean?
    I just quoted someone, because i want him to read that thread

    Leave a comment:


  • alexbk66
    replied
    Originally posted by MattL0 View Post
    MattL0 what do you mean?

    Leave a comment:


  • alexbk66
    replied
    Thank you Bill I'm not really "confused" - I was using CapiControlHandler, but for RaspberryIO it wasn't showing in HS, but SetDeviceValueByRef was showing in HS, but wasn't changing outputs - that's the problem.

    Also, I'm not sure which one really should be used in SetIOMulti()? All examples and Help use SetDeviceValueByRef. And I did have problems with CapiControlHandler here.

    I reckon something is wrong with HS here - both functions should behave the same IMHO. Why do they have different effect?

    Leave a comment:


  • MattL0
    replied
    risquare

    Leave a comment:


  • bsobel
    replied
    Originally posted by alexbk66 View Post
    So, there are two ways to set device value - SetDeviceValueByRef and CAPIControlHandler. First I thought that SetDeviceValueByRef is just a convinience wrapper for CAPIControlHandler. But.

    SetDeviceValueByRef doen't seem to work with physical devices like Raspberry IO outputs. It looks like it changes the value in HS ui, but output doesn't change.
    So. I try CAPIControlHandler - it does work with Raspberry IO outputs - but is not reflected in HS ui.

    So WTH should I be using? I use both and it seems to work - but it's ridiculous.
    You should absolutely not being using both, and you are definitely confused (and its a confusing subject).

    To control a device you should always being the CapiControlHandler. If you are a plugin author that controls a device (say a bulb) you should respond to the SetIOMulti() and set your devices to their proper state AND call set value, however you should NOT respond to set value being set. This will cause horrible logic loops.

    You are doing a linking program so you are in a special case of hell ,) Since the devices are not yours you need to use CapiControlHandler but since you are forcing the change you don't want to retriever on the later value change. In your very special case you will need to keep track of the values you send to CapiControl handler for each device and ignore the corresponding value change when it arrives a bit later.

    Leave a comment:


  • alexbk66
    replied
    Originally posted by aa6vh View Post
    This code works for me, and sets both the device and the HS UI:
    ]
    It looks similar to what I'm doing, the problem is - you are setting virtual device, but as I said the real issue is with physical devices, like Raspberry IO output, and I saw similar discussions about setting thermostats as well.
    A couple notes:
    1. For performance I keep device ID and create CAPIControl dictionary at start, instead of 'for' looping at run time
    2. Since you use the device name anyway - why not just call SetDeviceStringByName?

    Leave a comment:


  • aa6vh
    replied
    This code works for me, and sets both the device and the HS UI:

    Code:
    Public Function SetVirtual(ByVal sDevName As String, ByVal sLabel As String) As Integer
      Dim iRef As Integer = hs.GetDeviceRefByName(sDevName)
      Dim CS As ICAPIStatus = hs.CAPIGetStatus(iRef)
      For Each objCAPIControl As CAPIControl In hs.CAPIGetControl(iRef)
        If LCase(objCAPIControl.Label) = LCase(sLabel) Then
          hs.CAPIControlHandler(objCAPIControl)
          Return 0
        End If
      Next
      Return 1
    End Function

    Leave a comment:

Working...
X