WPFxUPnP 2 その3
WPFxUPnP 2 その3
public class UPnPLightDevice : INotifyPropertyChanged { public UPnPDevice Device { get; set; } public UPnPService SwitchPowerService { get; set; } public UPnPLightDevice(UPnPDevice pDevice) { try { Device = (UPnPDevice)Marshal.GetUniqueObjectForIUnknown(Marshal.GetIUnknownForObject(pDevice)); SwitchPowerService = Device.Services["urn:upnp-org:serviceId:SwitchPower:1"]; SwitchPowerService.AddCallback(this); } catch (Exception) { if (SwitchPowerService != null) { Marshal.ReleaseComObject(SwitchPowerService); } if (Device != null) { Marshal.ReleaseComObject(Device); } throw; } } #region INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; #endregion bool _Status = false; public bool Status { get { return _Status; } set { _Status = value; if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("Status")); } } }
コンストラクタで、DeviceFinderで見つけたUPnPDeviceを残し、そこから、urn:upnp-org:serviceId:SwitchPower:1サービスを取得します。
後は、ライトの値をプロパティとして、出して、値が変わるとINotifyPropertyChangedを用いて、WPFへ変更通知を送るようにしています。
そして、urn:upnp-org:serviceId:SwitchPower:1のアクションをそれぞれ定義します。
public void SetTarget(bool status) { object[] inarg = new object[1] { (status ? 1 : 0) }; object[] outarg = new object[1]; SwitchPowerService.InvokeAction("SetTarget", inarg, outarg); } public bool GetTarget() { object[] inarg = new object[1]; object outarg = new object(); SwitchPowerService.InvokeAction("GetTarget", inarg, ref outarg); return (bool)(((object[])outarg)[0]); } public bool GetStatus() { object[] inarg = new object[1]; object outarg = new object(); SwitchPowerService.InvokeAction("GetStatus", inarg, ref outarg); return (bool)(((object[])outarg)[0]); }
あと、SwitchPowerService.AddCallback(this);で、urn:upnp-org:serviceId:SwitchPower:1サービスの状態変更通知を貰えるように、設定します。
AddCallbackで指定するには、IUPnPServiceCallbackインターフェースを継承する必要があります。
よって、クラス定義が次のようになります。
public class UPnPLightDevice : IUPnPServiceCallback, INotifyPropertyChanged { ・・・(省略)・・・ #region IUPnPServiceCallback public void ServiceInstanceDied(UPnPService pus) { Marshal.ReleaseComObject(pus); } public void StateVariableChanged(UPnPService pus, string pcwszStateVarName, object vaValue) { try { if (pcwszStateVarName == "Status") { Status = ((bool)vaValue); } } catch (Exception) { } finally { Marshal.ReleaseComObject(pus); } } #endregion }