HomeSeer / Plugin-SDK

Plugin development kit for the 4th major edition of the HomeSeer platform.
https://www.nuget.org/packages/HomeSeer-PluginSDK/
GNU Affero General Public License v3.0
21 stars 5 forks source link

Updating the associated devices appears to add more device as opposed to overwrite them #82

Closed dcorsus closed 3 years ago

dcorsus commented 4 years ago

Environment and System Config

When I do migration from HS3 devices to the HS4 structure I would have in HS3 a parent device (with controls on it) and children. When going to HS4, I create a new device and turn the HS3 parent into a feature so it can keep its controls. While doing that, I need to move the list of children from old parent (which is now a feature) to the new device.

After all is done, I can see that using this code myHomeSeerSystem.UpdatePropertyByRef(devRef, EProperty.AssociatedDevices, associatedDevicesList)

is just adding more associated devices and is not overwriting what is already there.

dcorsus commented 4 years ago

I have a strong suspicion there is a difference between the child list in HS3 and the associated device list in HS4. When I do a myHomeSeerSystem.GetDeviceByRef(MasterHSFeatureRef).AssociatedDevices on a HS3 device with many children, it return an empty list. Hope this helps to pinpoint the issue.

dcorsus commented 4 years ago

I did a simple test:

On a device/feature that already has some associated devices, if you issue this command myHomeSeerSystem.UpdatePropertyByRef(devRef, EProperty.AssociatedDevices, associatedDevicesList)

With associatedDevicesList, just having a single entry, you'll see that it just gets added to the list instead of replacing the list.

jldubz commented 4 years ago

@dcorsus

We will have to look into this a little deeper to understand exactly what is going on. It doesn't make sense that the child list of an HS3 device is empty when it should have associations. There isn't anything being done to that data. A good way to validate the state of your data is by doing a getstatus JSON call http://<HOMESEER_IP>/JSON?request=getstatus and checking that there are actually associations listed for that device.

The GetDeviceByRef() method is doing very minor data manipulation before it hands you the device data. You can see it here:

        Public Function ToModernDevice(ByVal ind As DeviceClass) As HsDevice
            Dim dev As HsDevice = New HsDevice(ind.HSRef)
            dev.LastChange = ind.HSLast_Change
            dev.Name = ind.HSName
            dev.Image = ind.HSImage
            dev.Value = ind.HSdevValue
            dev.Status = ind.HSdevString
            dev.Address = ind.HSmvarAddress
            dev.Location = ind.HSLocation
            dev.Location2 = ind.HSLocation2
            dev.Interface = ind.HSInterface
            dev.Relationship = ind.HSRelationship
            dev.UserNote = ind.HSUserNote
            dev.UserAccess = ind.HSUserAccess
            dev.Misc = ind.Misc
            dev.AssociatedDevices = New HashSet(Of Integer)(ind.HSAssociatedDevices)
            dev.VoiceCommand = ind.HSVoiceCommand
            dev.IsValueInvalid = ind.InvalidValue
            dev.TypeInfo = ind.HSDeviceType.ToModernType()
            dev.PlugExtraData = ind.HSPlugExtraData.ToModernType()

            Return dev

        End Function

It does look like the UpdatePropertyByRef() method is performing an add instead of a replace on that list. A replace is definitely expected when this is called.

Case EProperty.AssociatedDevices
    If TypeOf value IsNot ICollection(Of Integer) Then Throw New ArgumentException("Invalid type for property")
    For Each devRef As Integer In value
        device.HSAssociatedDevice_Add(devRef)
    Next

Will update this issue with linked ticket numbers for these.

dcorsus commented 4 years ago

While you are looking into this, check also on setting misc flags. I think you can set them but I have no idea how to reset a flag using the updatepropertybyref.

jldubz commented 4 years ago

@dcorsus

Use AbstractHsDevice.SetMiscFlag() or AbstractHsDevice.RemoveMiscFlag() and then call update with the current value on the AbstractHsDevice.

myDevice.SetMiscFlag(EMiscFlag.NoLog);
HsSystem.UpdatePropertyByRef(myDevice.Ref, EProperty.Misc, myDevice.Misc);

The same thing can be done for any property.

dcorsus commented 4 years ago

Jon any update on this?

spudwebb commented 3 years ago

This bug is now tracked as HS-1075, and there is another github issue for it: #112 so I'm closing this one