zehnm / neeo-mystrom-switch

NEEO driver for myStrom WiFi Switch
MIT License
3 stars 0 forks source link

Auto discovery of myStrom WiFi Switch v1 devices #1

Open zehnm opened 6 years ago

zehnm commented 6 years ago

The auto discovery of WiFi Switch v2 devices is already implemented and working fine. Version 2 is the currently available device with integrated temperature sensor. V1 devices have the same REST API but don't have a temperature sensor and don't announce themself by UDP broadcast on port 7979.

Enhancement: auto discovery for v1 switches.

Official information received from mystrom.ch support:

in case of WSW - WiFi Switch v1 it broadcast itself over UPNP.

Unfortunately I've been unable to discover a v1 switch with UPNP. I've tried various tools, libraries and my own code under Linux and OSX. My analysis so far:

PORT     STATE         SERVICE
1900/udp open|filtered upnp
#!/usr/bin/env python
import socket

msg = \
    'M-SEARCH * HTTP/1.1\r\n' \
    'HOST:239.255.255.250:1900\r\n' \
    'MAN:"ssdp:discover"\r\n' \
    'MX:5\r\n' \
    'ST:ssdp:all\r\n' \
    '\r\n'

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.settimeout(10)
s.sendto(msg, ('239.255.255.250', 1900) )

try:
    while True:
        data, addr = s.recvfrom(8192)
        print addr, data
except socket.timeout:
    pass
#!/usr/bin/env python
import socket
import struct

MCAST_GRP = '239.255.255.250'
MCAST_PORT = 1900

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((MCAST_GRP, MCAST_PORT))  # use '' instead of MCAST_GRP to listen to all groups on MCAST_PORT
mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

while True:
    data, addr = sock.recvfrom(8192)
    print addr, data

I’m able to discover all other UPNP devices on my network (router, Logitech Harmony, TV, Radio, NEEO remote, Plex), with upnp tools, Wireshark and my own code. Therefore I assume something is wrong or ‘special’ with the myStrom WiFi Switch v1.

Does anyone have an idea or further information?

zehnm commented 6 years ago

MDNS analysis:

Node.js test:

'use strict';
const bonjour = require('bonjour')();

function printObject(o) {
  let out = '';
  Object.getOwnPropertyNames(o).forEach( (name, index) => {
    out += (index > 0 ? ',' : '') + name + '=' + o[name];
  });
  return out;
}

function serviceUpListener(service) {
  if (!service || !service.txt || !service.host) {
    return;
  }
  if (service.host.startsWith('myStrom-Switch')) {
    console.log('MDNS discovered "%s": host=%s, MAC=%s, txt=[%s]', service.name, service.host, service.txt.id, printObject(service.txt));
  }
}

const mdnsBrowser = bonjour.find({ type: 'hap' }, serviceUpListener);
mdnsBrowser.start();

Output (with masked mac addresses):

MDNS discovered "Switch-ef0011": host=myStrom-Switch-ef0011.local, MAC=de:ad:be:ef:00:11, txt=[c#=1,ff=0,id=de:ad:be:ef:00:11,md=Switch-ef0011,pv=1.0,s#=2,sf=1,ci=8]
MDNS discovered "Outlet ef0022": host=myStrom-Switch-ef0022.local, MAC=de:ad:be:ef:00:22, txt=[c#=1025720861,ff=0,id=de:ad:be:ef:00:22,md=Outlet ef0022,pv=1.0,s#=1,sf=1,ci=7]