Created
December 6, 2017 09:34
-
-
Save oesolberg/95450ea4b3807c5bfac31546d33880f2 to your computer and use it in GitHub Desktop.
Homeseer device handling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading; | |
using HomeSeerAPI; | |
using RfLinkSeer.Common; | |
using RfLinkSeer.Common.Interfaces; | |
using Scheduler; | |
namespace RfLinkSeer.DeviceHandling | |
{ | |
public class RfLinkDeviceHandling | |
{ | |
private readonly IHSApplication _hs; | |
private readonly ILogging _log; | |
public RfLinkDeviceHandling(HomeSeerAPI.IHSApplication hs, ILogging log) | |
{ | |
_hs = hs; | |
_log = log; | |
} | |
/// <param name="name">The name of the device</param> | |
/// <remarks>By Moskus and http://www.homeseer.com/support/homeseer/HS3/HS3Help/scripting_devices_deviceclass1.htm </remarks> | |
public virtual int CreateBasicDevice(string name, string location, string location2) | |
{ | |
try | |
{ | |
//Creating a brand new device, and get the actual device from the device reference | |
var fullName = location2 + Utility.HsNameSeparator + location + Utility.HsNameSeparator + name; | |
Scheduler.Classes.DeviceClass dv = (Scheduler.Classes.DeviceClass)_hs.GetDeviceByRef(_hs.NewDeviceRef(fullName)); | |
int dvRef = dv.get_Ref(_hs); | |
//Setting the type to plugin device | |
DeviceTypeInfo_m.DeviceTypeInfo typeInfo = new DeviceTypeInfo_m.DeviceTypeInfo(); | |
typeInfo.Device_Type = (int)DeviceTypeInfo_m.DeviceTypeInfo.eDeviceAPI.Plug_In; | |
dv.set_DeviceType_Set(_hs, typeInfo); | |
dv.set_Interface(_hs, Utility.PluginName); //Don't change this, or the device won't be associated with your plugin | |
dv.set_InterfaceInstance(_hs, Utility.PluginInstanceName); //Don't change this, or the device won't be associated with that particular instance | |
dv.set_Device_Type_String(_hs, name); | |
dv.set_Can_Dim(_hs, false); | |
//Setting the name and locations | |
dv.set_Name(_hs, name); | |
dv.set_Location(_hs, location); | |
dv.set_Location2(_hs, location2); | |
//Misc options | |
dv.set_Status_Support(_hs, false); //Set to True if the devices can be polled, False if not. (See PollDevice in hspi.vb) | |
dv.MISC_Set(_hs, Enums.dvMISC.SHOW_VALUES); //If not set, device control options will not be displayed. | |
dv.MISC_Set(_hs, Enums.dvMISC.NO_LOG); //As default, we don't want to Log every device value change to the Log | |
//Committing to the database, clear value-status-pairs and graphic-status pairs | |
_hs.SaveEventsDevices(); | |
_hs.DeviceVSP_ClearAll(dvRef, true); | |
_hs.DeviceVGP_ClearAll(dvRef, true); | |
return dvRef; //Return the reference | |
} | |
catch (Exception ex) | |
{ | |
throw new Exception("Error creating basic device: " + ex.Message, ex); | |
} | |
} | |
public virtual int CreateRootDevice(string rootDeviceName, string location, string location2) | |
{ | |
try | |
{ | |
//Creating a brand new device, and get the actual device from the device reference | |
Scheduler.Classes.DeviceClass rootDevice = (Scheduler.Classes.DeviceClass)_hs.GetDeviceByRef(CreateBasicDevice(rootDeviceName, location, location2)); | |
rootDevice.set_Device_Type_String(_hs, rootDeviceName + Utility.HsNameSeparator + "root"); | |
rootDevice.set_Relationship(_hs, HomeSeerAPI.Enums.eRelationship.Parent_Root); | |
int dvRef = rootDevice.get_Ref(_hs); | |
//Committing to the database, clear value-status-pairs and graphic-status pairs | |
_hs.SaveEventsDevices(); | |
return dvRef; //Return the reference | |
} | |
catch (Exception ex) | |
{ | |
throw new Exception("Error creating root device: " + ex.Message, ex); | |
} | |
} | |
public virtual int CreateChildDevice(string ChildDeviceName, string location, string location2, Scheduler.Classes.DeviceClass rootDevice) | |
{ | |
try | |
{ | |
//Creating a brand new device, and get the actual device from the device reference | |
Scheduler.Classes.DeviceClass childDevice = (Scheduler.Classes.DeviceClass)_hs.GetDeviceByRef(CreateBasicDevice(ChildDeviceName, location, location2)); | |
childDevice.set_Device_Type_String(_hs, ChildDeviceName + Utility.HsNameSeparator+"child"); | |
childDevice.set_Relationship(_hs, HomeSeerAPI.Enums.eRelationship.Child); | |
int dvRef = childDevice.get_Ref(_hs); | |
rootDevice.AssociatedDevice_Add(_hs, dvRef); //Then associated that child reference with the root. | |
//Committing to the database, clear value-status-pairs and graphic-status pairs | |
_hs.SaveEventsDevices(); | |
return dvRef; //Return the reference | |
} | |
catch (Exception ex) | |
{ | |
throw new Exception("Error creating child device: " + ex.Message, ex); | |
} | |
} | |
public virtual int GetDeviceId(string name, string location, string location2) | |
{ | |
string fullName; | |
if (String.IsNullOrEmpty(location2)) | |
{ | |
fullName = location + " " + name; | |
} | |
else | |
{ | |
fullName = location2 + " " + location + " " + name; | |
} | |
var devices = GetHomeseerDevices(); | |
var foundDevices = devices.Where(x => x.get_Device_Type_String(_hs).Contains(name)).ToList(); | |
if (foundDevices.Any()) | |
{ | |
//foreach (var dev in foundDevices) | |
//{ | |
// _hs.SetDeviceValueByRef(dev.get_Ref(_hs), 999, true); | |
// _hs.SetDeviceString(dev.get_Ref(_hs), $"Last random value: {DateTime.Now.Second}", false); | |
//} | |
var rootDevice = devices.FirstOrDefault(x => x.get_Device_Type_String(_hs).Contains(name) && x.get_Device_Type_String(_hs).Contains("root")); | |
if (rootDevice != null) return rootDevice.get_Ref(_hs); | |
} | |
//int dvRef = _hs.GetDeviceRefByName(name); | |
return -1; | |
} | |
private List<Scheduler.Classes.DeviceClass> GetHomeseerDevices() | |
{ | |
var deviceList = new List<Scheduler.Classes.DeviceClass>(); | |
var deviceEnumerator = (Scheduler.Classes.clsDeviceEnumeration)_hs.GetDeviceEnumerator(); | |
while (!deviceEnumerator.Finished) | |
{ | |
var foundDevice = deviceEnumerator.GetNext(); | |
deviceList.Add(foundDevice); | |
} | |
//== Where d.Interface(hs) = Me.Name | |
return deviceList.Where(x => x.get_Interface(_hs) == Utility.PluginName).ToList(); | |
} | |
public virtual bool DeviceExists(string name, string location, string location2) | |
{ | |
if (GetDeviceId(name, location, location2) > 0) return true; | |
return false; | |
} | |
public List<Scheduler.Classes.DeviceClass> GetChildrenByHomeseerRefId(int refId) | |
{ | |
var rootDevice = (Scheduler.Classes.DeviceClass)_hs.GetDeviceByRef(refId); | |
if (rootDevice.get_AssociatedDevices_Count(_hs) < 1) return null; | |
var childIds = rootDevice.get_AssociatedDevices(_hs); | |
var childList = new List<Scheduler.Classes.DeviceClass>(); | |
foreach (var childId in childIds) | |
{ | |
childList.Add((Scheduler.Classes.DeviceClass)_hs.GetDeviceByRef(childId)); | |
} | |
return childList; | |
} | |
public Scheduler.Classes.DeviceClass GetDeviceByRefId(int refId) | |
{ | |
var foundDevice = (Scheduler.Classes.DeviceClass)_hs.GetDeviceByRef(refId); | |
return foundDevice; | |
} | |
public List<object> GetAllUnitsFromHomeseer() | |
{ | |
var devicesInHomeseerList = GetHomeseerDevices(); | |
if (devicesInHomeseerList != null && devicesInHomeseerList.Any()) | |
{ | |
foreach (var deviceClass in devicesInHomeseerList) | |
{ | |
Console.WriteLine($"found one {deviceClass.get_Address(_hs)}"); | |
} | |
} | |
return null; | |
} | |
public void UpdateOrAddUnitInHomeseer(ParsedRfLinkData rfLinkUnit) | |
{ | |
//Check if the unit already exists | |
var unitId = GetUnitId(rfLinkUnit.UnitId, Utility.PluginName, Utility.PluginName); | |
if (unitId > 0) | |
{ | |
UpdateHomeseerWithUnitData(rfLinkUnit, unitId); | |
} | |
//else | |
//{ | |
// CreateUnitInHomeseer(rfLinkUnit); | |
//} | |
} | |
private int GetUnitId(string name, string location, string location2) | |
{ | |
return GetDeviceId(name, location, location2); | |
} | |
private void UpdateHomeseerWithUnitData(ParsedRfLinkData linkUnit, int refId) | |
{ | |
var rootDevice = GetDeviceByRefId(refId); | |
var children = GetChildrenByHomeseerRefId(refId); | |
if (children != null) | |
{ | |
//update all subitems | |
foreach (var rfLinkDataInfo in linkUnit.DataInfoList) | |
{ | |
var deviceToUpdate = children.FirstOrDefault(x => x.get_Device_Type_String(_hs).Contains($"{linkUnit.UnitId} {rfLinkDataInfo.DataType}")); | |
if (deviceToUpdate != null) | |
{ | |
UpdateHomeSeerDevice(rfLinkDataInfo, deviceToUpdate); | |
} | |
} | |
//Check if the root value should be updated | |
} | |
var rootData = linkUnit.DataInfoList.FirstOrDefault(x => rootDevice.get_Device_Type_String(_hs).Contains(x.DataType)); | |
if (rootData != null) | |
{ | |
UpdateHomeSeerDevice(rootData, rootDevice); | |
} | |
} | |
private void UpdateHomeSeerDevice(RfLinkBaseDataInfo rfLinkDataInfo, Scheduler.Classes.DeviceClass deviceToUpdate) | |
{ | |
_hs.SetDeviceValueByRef(deviceToUpdate.get_Ref(_hs), rfLinkDataInfo.RfValue, true); | |
_hs.SetDeviceString(deviceToUpdate.get_Ref(_hs), $"{rfLinkDataInfo.DataType}: {rfLinkDataInfo.RfValue}", false); | |
} | |
public void CreateNewDevice(ParsedRfLinkData rfUnit) | |
{ | |
var rootTuple = CreateRootDevice(rfUnit); | |
if (rootTuple == null) return; | |
var root = (Scheduler.Classes.DeviceClass)_hs.GetDeviceByRef(rootTuple.Item2); | |
foreach (var dataInfo in rfUnit.DataInfoList) | |
{ | |
if (dataInfo.DataType != rootTuple.Item1) | |
{ | |
var childUnitDeviceId = CreateChildDevice($"{rfUnit.UnitId} {dataInfo.DataType}", Utility.PluginName, Utility.PluginName, root); | |
root.AssociatedDevice_Add(_hs, childUnitDeviceId); | |
} | |
} | |
} | |
private Tuple<string, int> CreateRootDevice(ParsedRfLinkData rfLinkUnit) | |
{ | |
var rootDevice = rfLinkUnit.DataInfoList.FirstOrDefault(x => x.DataType == "TEMP"); | |
if (rootDevice == null) rootDevice = rfLinkUnit.DataInfoList.FirstOrDefault(); | |
//Return null if the unit already exists | |
if (DeviceExists($"{rfLinkUnit.UnitId} {rootDevice.DataType}", Utility.PluginName, Utility.PluginName)) | |
{ | |
_log.LogDebug($"Unit already exists: '{rfLinkUnit.UnitId} {rootDevice.DataType}' "); | |
return null; | |
} | |
var rootId = CreateRootDevice($"{rfLinkUnit.UnitId};{rootDevice.DataType}", Utility.PluginName, Utility.PluginName); | |
return new Tuple<string, int>(rootDevice.DataType, rootId); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment