Find Belkin WeMo devices with UPnP.FindByType

I am trying to create a C # application for managing WeMo devices. I followed the code examples and instructions given by Bernacules here .

The corresponding code bit will be inserted below.

private void GetAllDevices() { var finder = new UPnPDeviceFinder(); var foundDevices = new List<UPnPDevice>(); var deviceType = "upnp:rootdevice"; var devices = finder.FindByType(deviceType, 1); foreach (UPnPDevice upnpDevice in devices) { if (upnpDevice.Type.StartsWith("urn:Belkin:")) { .... } } } 

When I repeat the devices found by UPnPDeviceFinder, I come up with all kinds of things, my media server, some kind of application running on my Android phone, my Chromecast, but without WeMos, nothing that Belkin even remotely had in the bin.

After a bit more Googling, I found this article , which allowed me to figure out how to request "setup.xml" for each device. Replacing "upnp: rootdevice" in the above code with the value from <DeviceType> in xml (I believe it is "urn: Belkin: device: controllee: 1"), I came up with 0 results from UPnPDeviceFinder. I guess Belkin recently changed his configuration, but can someone with a little more mobility connect me to what value can I use for the “deviceType” that my WeMos will find?

+8
c # upnp
source share
4 answers

What version of windows are you using?

My UPnP scanner detects that Wemo just works fine on Windows 7, but it doesn't work on Windows 8.1

On Windows 8.1, all my other UPnP devices are displayed, but Wemo is not displayed at all.

+3
source share

I managed to make a workaround. It is a bit hacked and doesn’t actually use the upnp protocol (since I couldn’t get this working at all on Windows 10).

Basically, we do the netsh command to get a list of devices and their addresses. Then we try to access setup.xml on different ports, which, as we know, can work on wemo devices. When we get the correct answer, it contains all the information about the upnp device, which we can parse into everything that we would like to know about the device. In this example, I simply simplified the parsing by simply checking to see if it contains the word "Belkin." This is some kind of work, but we have to parse the UDN to determine the model, and friendlyName to show the end user. Otherwise, other devices created by Belkin may appear.

This method works for me on a Windows 10 PC. I have not tried other platforms. This is a kind of brute force method, but all requests are executed async and in parallel, so we get the answer pretty quickly. Anyway, here is a class that does all the magic:

 public class WemoScanner { public delegate void WemoDeviceFound(WemoDevice device); public event WemoDeviceFound OnWemoDeviceFound; public void StartScanning() { var addresses = GetAddresses().Where(a => a.Type == "Dynamic"); var tasks = addresses.SelectMany(CheckWemoDevice); Task.Run(async () => { await Task.WhenAll(tasks).ConfigureAwait(false); }); } public List<WemoDevice> GetWemoDevices() { var devices = new List<WemoDevice>(); OnWemoDeviceFound += device => devices.Add(device); var addresses = GetAddresses().Where(a => a.Type == "Dynamic"); var tasks = addresses.SelectMany(CheckWemoDevice); Task.WhenAll(tasks).GetAwaiter().GetResult(); return devices; } private NetshResult[] GetAddresses() { Process p = new Process(); p.StartInfo.FileName = "netsh.exe"; p.StartInfo.Arguments = "interface ip show ipnet"; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.Start(); string output = p.StandardOutput.ReadToEnd(); var lines = output.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries) .SkipWhile(l => !l.StartsWith("--------")) .Skip(1); var results = lines.Select(l => new NetshResult(l.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))) .ToArray(); return results; } private IEnumerable<Task> CheckWemoDevice(NetshResult netshResult) { var tasks = new List<Task>(); for (uint i = 49150; i <= 49156; i++) { tasks.Add(CheckWemoDevice(netshResult.IpAddress, i)); } return tasks; } private async Task CheckWemoDevice(string ip, uint port) { var url = $"http://{ip}:{port}/setup.xml"; try { using (var wc = new WebClient()) { var resp = await wc.DownloadStringTaskAsync(url); if (resp.Contains("Belkin")) // TODO: Parse upnp device data and determine device OnWemoDeviceFound?.Invoke(new WemoDevice {Address = ip, Port = port}); } } catch (Exception) { } } } 

And several classes of models:

 public class NetshResult { public NetshResult(string[] columns) { PhysicalAddress = columns[0]; IpAddress = columns[1]; Type = columns[2]; Interface = columns[3]; } public string PhysicalAddress { get; private set; } public string IpAddress { get; private set; } public string Type { get; private set; } public string Interface { get; private set; } } public class WemoDevice { public string Address { get; set; } public uint Port { get; set; } } 

The use is pretty simple. If you want it to run asynchronously (in the background), just hook into the OnWemoDeviceFound event and call StartScanning() as follows:

 var scanner = new WemoScanner(); scanner.OnWemoDeviceFound += device => Console.WriteLine($"{device.Address}:{device.Port}"); scanner.StartScanning(); 

If you need a method that works synchronously and returns a list of devices, just call GetWemoDevices() . Keep in mind that this is not recommended, as it will not be returned until a timeout occurs in all "invalid" requests. You can change the timeout for web requests if you want to reduce the time.

+3
source share

I know this is a very old thread, but I had problems getting any of the above solutions running on Windows 10 in 2018. I was able to get it in Windows 10 with a combination of code from the @Inrego and .NET TcpClient class, checking open port 49153.

  public IList<WemoDevice> GetWemoIPs() { var wemos = new List<WemoDevice>(); Parallel.For(1, 255, (i) => { var ip = string.Format(this.IpFormat, i); var device = new WemoDevice(ip); if (IsWemo(ip)) wemos.Add(device); }); return wemos; } public bool IsWemo(string ipAddress) { using (TcpClient tcpClient = new TcpClient()) { try { tcpClient.Connect(ipAddress, 49153); return true; } catch { return false; } } } 
0
source share

With the upnp:rootdevice WeMo was also not found on Windows 10. In Inrego, you posted your “other way”. In another case, I’m going to record a MAC, and then I perform ARP each time to see if the IP address has changed, the control ports 49152, 49153, 49154 (as I understand, they can change)

-one
source share

All Articles