n8henrie / fauxmo

Emulated Belkin WeMo devices that work with the Amazon Echo
https://n8henrie.com/2016/02/fauxmo-home-automation-with-the-amazon-echo-raspberry-pi-and-homeassistant/
Other
375 stars 78 forks source link

Fauxmo - Raspi - Python - no response of Eco after sending setup xml #96

Closed Silberbart closed 4 years ago

Silberbart commented 4 years ago

My Issue

First of all, thank you in advance for your help!

After starting Fauxmo and config is read, doing the search for devices via the Alex App. I can see in the log the response from Fauxmo, but after that nothing happens, only some polling. Alexa says as well no device found.

WHYT

config.json

{
"FAUXMO": {
    "ip_address": "auto"
  },
  "PLUGINS": {
    "CommandLinePlugin": {
      "path": "/home/pi/plc/Fauxmo/commandlineplugin.py",
      "DEVICES": [
        {
            "name": "Wohnzimmer",
            "port": 49915,
            "on_cmd": "python3 /home/pi/plc/Fauxmo/test.py",
            "off_cmd": "python3 /home/pi/plc/Fauxmo/test.py"
        },
        {
            "name": "Esszimmer",
            "port": 49916,
            "on_cmd": "python3 /home/pi/plc/Fauxmo/test.py",
            "off_cmd": "python3 /home/pi/plc/Fauxmo/test.py"
        }
      ]
    }
  }
}

Log

pi@raspberrypi:~/plc/Fauxmo $ python3 -m fauxmo.cli -c /home/pi/plc/Fauxmo/config.json -vvv
2020-04-22 11:01:48 fauxmo:42       INFO     Fauxmo v0.5.0
2020-04-22 11:01:48 fauxmo:43       DEBUG    3.7.3 (default, Apr  3 2019, 05:39:12) 
[GCC 8.2.0]
2020-04-22 11:01:48 fauxmo:25       DEBUG    Attempting to get IP address automatically
2020-04-22 11:01:48 fauxmo:40       DEBUG    Using IP address: 192.168.2.123
2020-04-22 11:01:48 fauxmo:112      DEBUG    plugin_vars: {}
2020-04-22 11:01:48 fauxmo:115      DEBUG    device config: {'name': 'Wohnzimmer', 'port': 49915, 'on_cmd': 'python3 /home/pi/plc/Fauxmo/test.py', 'off_cmd': 'python3 /home/pi/plc/Fauxmo/test.py'}
2020-04-22 11:01:48 asyncio:1403     INFO     <Server sockets=[<socket.socket fd=7, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('192.168.2.123', 49915)>]> is serving
2020-04-22 11:01:48 fauxmo:134      DEBUG    Started fauxmo device: {'name': 'Wohnzimmer', 'plugin': <fauxmo.plugins.commandlineplugin.CommandLinePlugin object at 0x75f8f3f0>}
2020-04-22 11:01:48 fauxmo:115      DEBUG    device config: {'name': 'Esszimmer', 'port': 49916, 'on_cmd': 'python3 /home/pi/plc/Fauxmo/test.py', 'off_cmd': 'python3 /home/pi/plc/Fauxmo/test.py'}
2020-04-22 11:01:48 asyncio:1403     INFO     <Server sockets=[<socket.socket fd=8, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('192.168.2.123', 49916)>]> is serving
2020-04-22 11:01:48 fauxmo:134      DEBUG    Started fauxmo device: {'name': 'Esszimmer', 'plugin': <fauxmo.plugins.commandlineplugin.CommandLinePlugin object at 0x75f8f7b0>}
2020-04-22 11:01:48 fauxmo:136      INFO     Starting UDP server
2020-04-22 11:01:48 asyncio:1259     DEBUG    Datagram endpoint remote_addr=None created: (<_SelectorDatagramTransport fd=9 read=idle write=<idle, bufsize=0>>, <fauxmo.protocols.SSDPServer object at 0x75f8f290>)
2020-04-22 11:02:08 asyncio:1729     INFO     poll took 19725.328 ms: 1 events
2020-04-22 11:02:08 fauxmo:344      DEBUG    Received data below from ('192.168.2.251', 34779):
2020-04-22 11:02:08 fauxmo:345      DEBUG    NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age=1801
NTS: ssdp:alive
LOCATION: http://192.168.2.251:49152/wps_device.xml
SERVER: Unspecified, UPnP/1.0, Unspecified
NT: upnp:rootdevice
USN: uuid:00000000-0000-1000-0000-18d6c7cb51f0::upnp:
....
.... Some polling in between
....
2020-04-22 11:02:43 fauxmo:57       INFO     setup.xml requested by Echo
2020-04-22 11:02:43 fauxmo:103      DEBUG    Fauxmo response to setup request:
HTTP/1.1 200 OK
CONTENT-LENGTH: 950
CONTENT-TYPE: text/xml
DATE: Wed, 22 Apr 2020 09:02:43 GMT
LAST-MODIFIED: Sat, 01 Jan 2000 00:01:15 GMT
SERVER: Unspecified, UPnP/1.0, Unspecified
X-User-Agent: Fauxmo
CONNECTION: close

<?xml version="1.0"?><root><specVersion><major>1</major><minor>0</minor></specVersion><device><deviceType>urn:Belkin:device:controllee:1</deviceType><friendlyName>Wohnzimmer</friendlyName><manufacturer>Belkin International Inc.</manufacturer><modelName>Emulated Socket</modelName><modelNumber>3.1415</modelNumber><UDN>uuid:Socket-1_0-e0ab0cd5-dd7d-3f6c-a768-6013dbf1646a</UDN><serviceList><service><serviceType>urn:Belkin:service:basicevent:1</serviceType><serviceId>urn:Belkin:serviceId:basicevent1</serviceId><controlURL>/upnp/control/basicevent1</controlURL><eventSubURL>/upnp/event/basicevent1</eventSubURL><SCPDURL>/eventservice.xml</SCPDURL></service><service><serviceType>urn:Belkin:service:metainfo:1</serviceType><serviceId>urn:Belkin:serviceId:metainfo1</serviceId><controlURL>/upnp/control/metainfo1</controlURL><eventSubURL>/upnp/event/metainfo1</eventSubURL><SCPDURL>/metainfoservice.xml</SCPDURL></service></serviceList></device></root>
2020-04-22 11:02:44 asyncio:1733     DEBUG    poll 877.914 ms took 212.337 ms: 1 events
2020-04-22 11:02:44 asyncio:159      DEBUG    <Server sockets=[<socket.socket fd=8, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('192.168.2.123', 49916)>]> got a new connection from ('192.168.2.120', 41582): <socket.socket fd=10, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('192.168.2.123', 49916), raddr=('192.168.2.120', 41582)>
2020-04-22 11:02:44 fauxmo:43       DEBUG    Connection made with: ('192.168.2.120', 41582)
2020-04-22 11:02:44 fauxmo:55       DEBUG    Received message:
GET /setup.xml HTTP/1.1
Host: 192.168.2.123:49916
Accept: */*
Content-Type: application/json

2020-04-22 11:02:44 fauxmo:57       INFO     setup.xml requested by Echo
2020-04-22 11:02:44 fauxmo:103      DEBUG    Fauxmo response to setup request:
HTTP/1.1 200 OK
CONTENT-LENGTH: 949
CONTENT-TYPE: text/xml
DATE: Wed, 22 Apr 2020 09:02:44 GMT
LAST-MODIFIED: Sat, 01 Jan 2000 00:01:15 GMT
SERVER: Unspecified, UPnP/1.0, Unspecified
X-User-Agent: Fauxmo
CONNECTION: close

<?xml version="1.0"?><root><specVersion><major>1</major><minor>0</minor></specVersion><device><deviceType>urn:Belkin:device:controllee:1</deviceType><friendlyName>Esszimmer</friendlyName><manufacturer>Belkin International Inc.</manufacturer><modelName>Emulated Socket</modelName><modelNumber>3.1415</modelNumber><UDN>uuid:Socket-1_0-dc59281a-2ad1-3f36-a5df-8c04f3e23f80</UDN><serviceList><service><serviceType>urn:Belkin:service:basicevent:1</serviceType><serviceId>urn:Belkin:serviceId:bas

brooklinman commented 4 years ago

log.txt The same things started happening to my Fauxmo 2 or 3 days ago. I have 3 RPIs and all stopped responding to Echo/Alexa App commands 3 days ago. I Attempted to remove/rediscover the devices from scratch using the Alexa app, but the device cannot be found. Same results as the issue documented by @Silberbart . Has something changed in the WEMO environment ?

n8henrie commented 4 years ago

Thanks for the report. Mine have still been working fine at home, but I'll try to look into it soon. Will probably not have a chance for a few days, will keep you posted.

Tobi-ctrl commented 4 years ago

Same issue for me. Devices defined in config stopped working on saturday and cannot be discovered anymore.

n8henrie commented 4 years ago

I just tested and something required a change in my firewall -- it was not discovering as I had previously configured, but once I disabled my firewall I was able to discover devices again.

Are you guys running a firewall?

If not, I'm not able to reproduce the bug yet, using a combination of Echo / echo dot V1 / echo dot v3. At some point I'll take everything other than the V3 offline to see if I can reproduce on just that device. Could be a firmware update that just hasn't reached me yet.

Tobi-ctrl commented 4 years ago

I fixed the issue by simple restart of the echo dot 🤣

Wouter-Lemoine commented 4 years ago

I have also noted that with an echo dot 2 which was freshly reset, I was able to add new devices until I rebooted it, which took a long time so I assumed it updated. After that I couldn't add more devices, but the ones it knew still worked. If you need testing with a v2 feel free to contact me!

Silberbart commented 4 years ago

Only to clarify, that is the first attempt to use Fauxmo for me. Was never running before. So i don't know if i have everything setup right. Therefore the Question, can you please look into the log again and let me know if there is an indicator for something i did wrong.

I have no Firewall in the Network, or is there anything i have to take care on the raspi regarding ports or Firewall

Thank you again

Tommy-Jack commented 4 years ago

Hallo Silberbart,

vielleicht kann ich dir ja auf deutsch weiterhelfen. Wenn ich das richtig verstehe hast du die Faxmo installiert wie beschrieben und dir die Config.json erstellt. Desweiteren hast du die commandlineplugin.py im Hauptordner (/home/pi). Nun musst du dich in den "virtuellen" von Python begeben (quelle auswählen)source ./.venv/bin/activate und die Anwendung starten " fauxmo -c config.json -v

Geht das bis dahin?

gruß Jack

Tommy-Jack commented 4 years ago

Ach fast vergessen mit dem Befehl kannst du mal schauen ob die Fauxmo die Ports freigegeben hat. netstat -an |grep LISTEN Manchmal wenn man hier zu oft die Ports wechselt werden die vom Raspberry belegt und dadurch gesperrt. Das kann man aber mit einem einfachen Neustart beheben. Gruß Jack

Silberbart commented 4 years ago

Habe einen Neustart ausgefuehrt und es auch mit der virtuellen Umgebung nochmal getestet, allerdings nun direkt wie von dir beschrieben die fauxmo datei ausgefuehrt.

Hier das Ergebnis: irgendetwas stimmt nicht. :) Vielleicht hast du ja eine Idee, danke schon mal

(.venv) pi@raspberrypi:~/plc/Fauxmo $ fauxmo -c config.json -v
2020-04-29 15:17:55 fauxmo:188      WARNING  Unable to complete command for Esszimmer:
POST /upnp/control/basicevent1 HTTP/1.1
Host: 192.168.2.123:49916
Content-Type: text/xml; charset="utf-8"
SOAPACTION: "urn:Belkin:service:basicevent:1#GetBinaryState"
Content-Length: 298

<?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:GetBinaryState xmlns:u="urn:Belkin:service:basicevent:1"><BinaryState>1</BinaryState></u:GetBinaryState></s:Body></s:Envelope>
2020-04-29 15:17:55 fauxmo:188      WARNING  Unable to complete command for Wohnzimmer:
POST /upnp/control/basicevent1 HTTP/1.1
Host: 192.168.2.123:49915
Content-Type: text/xml; charset="utf-8"
SOAPACTION: "urn:Belkin:service:basicevent:1#GetBinaryState"
Content-Length: 298

<?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:GetBinaryState xmlns:u="urn:Belkin:service:basicevent:1"><BinaryState>1</BinaryState></u:GetBinaryState></s:Body></s:Envelope>
2020-04-29 15:17:55 fauxmo:188      WARNING  Unable to complete command for Esszimmer:
POST /upnp/control/basicevent1 HTTP/1.1
Host: 192.168.2.123:49916
Content-Type: text/xml; charset="utf-8"
SOAPACTION: "urn:Belkin:service:basicevent:1#GetBinaryState"
Content-Length: 298

<?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:GetBinaryState xmlns:u="urn:Belkin:service:basicevent:1"><BinaryState>1</BinaryState></u:GetBinaryState></s:Body></s:Envelope>
Silberbart commented 4 years ago

Und hier noch die "commandlineplugin.py"

from functools import partialmethod  # type: ignore
import shlex
import subprocess
from fauxmo.plugins import FauxmoPlugin
class CommandLinePlugin(FauxmoPlugin):
    """Fauxmo Plugin for running commands on the local machine."""
    def __init__(self, name: str, port: int, on_cmd: str, off_cmd: str)-> None:
        """Initialize a CommandLinePlugin instance.
        Args:
            name: Name for this Fauxmo device
            port: Port on which to run a specific CommandLinePlugin instance
            on_cmd: Command to be called when turning device on
            off_cmd: Command to be called when turning device off
       """
        self.on_cmd = on_cmd
        self.off_cmd = off_cmd
        super().__init__(name=name, port=port)
    def run_cmd(self, cmd: str) -> bool:
        """Partialmethod to run command.
        Args:
            cmd: Will be one of `"on_cmd"` or `"off_cmd"`, which `getattr` will
                 use to get the instance attribute.
        """
        command_str = getattr(self, cmd)
        shlexed_cmd = shlex.split(command_str)
        process = subprocess.run(shlexed_cmd)
        return process.returncode == 0

    on = partialmethod(run_cmd, "on_cmd")
    off = partialmethod(run_cmd, "off_cmd")
Tommy-Jack commented 4 years ago

Hi Silberbart,

ich hab eine komplett andere commandlineplugin.py Ich hab dir hier mal die Commandline rein von der aus ich mein zeug entwickelt habe. Es stehen ein paar Erklärungen und sie lässt sich recht gut anpassen. Was möchtest du überhaupt ansteuern? Ein Relaisboard oder eine Erweiterung? (CAN-BUS, LIN-BUS, Funkmodul,...) Hast du eine Fixe IP-Adresse für deinen Raspberry? Ich sehe gerade das zwischen deinen Posts du verschieden IP-Adressen vom Raspberry hast. Ich sehe gerade ich hab noch die Vorgänger Fauxmo...ich mach mal ein Update und teste das mal bei mir.

"""Fauxmo plugin that runs a command on the local machine. Runs ashlexed command usingsubprocess.run, keeping the default of shell=False. This is probaby frought with security concerns, which is why this plugin is not included by default infauxmo.plugins. By installing or using it, you acknowledge that it could run commands from your config.json that could lead to data compromise, corruption, loss, etc. Consider making your config.json read-only. If there are parts of this you don't understand, you should probably not use this plugin. If the command runs with a return code of 0, Alexa should respond prompty "Okay" or something that indicates it seems to have worked. If the command has a return code of anything other than 0, Alexa stalls for several seconds and subsequently reports that there was a problem (which should notify the user that something didn't go as planned). Note thatsubprocess.runas implemented in this plugin doesn't handle complex commands with pipes, redirection, or multiple statements joined by&&,||, ;, etc., so you can't just use e.g."command that sometimes fails || true" to avoid the delay and Alexa's response. If you really want to handle more complex commands, consider using this plugin as a template for another one usingos.systeminstead ofsubprocess.run`, but realize that this comes with substantial security risks that exceed my ability to explain. Example config:

{
  "FAUXMO": {
    "ip_address": "auto"
  },
  "PLUGINS": {
    "CommandLinePlugin": {
      "path": "/path/to/commandlineplugin.py",
      "DEVICES": [
        {
            "name": "output stuff to a file",
            "port": 49915,
            "on_cmd": "touch testfile.txt",
            "off_cmd": "rm testfile.txt",
            "state_cmd": "ls testfile.txt",
        }
      ]
    }
  }
}

""" import shlex import subprocess from fauxmo.plugins import FauxmoPlugin

class CommandLinePlugin(FauxmoPlugin): """Fauxmo Plugin for running commands on the local machine."""

def __init__(
    self,
    name: str,
    port: int,
    on_cmd: str,
    off_cmd: str,
    state_cmd: str = None,
) -> None:
    """Initialize a CommandLinePlugin instance.
    Args:
        name: Name for this Fauxmo device
        port: Port on which to run a specific CommandLinePlugin instance
        on_cmd: Command to be called when turning device on
        off_cmd: Command to be called when turning device off
        state_cmd: Command to check device state (return code 0 == on)
    """
    self.on_cmd = on_cmd
    self.off_cmd = off_cmd
    self.state_cmd = state_cmd

    super().__init__(name=name, port=port)

def run_cmd(self, cmd: str) -> bool:
    """Partialmethod to run command.
    Args:
        cmd: Command to be run
    Returns:
        True if command seems to have run without error
    """
    shlexed_cmd = shlex.split(cmd)
    process = subprocess.run(shlexed_cmd)
    return process.returncode == 0

def on(self) -> bool:
    """Run on command.
    Returns:
        True if command seems to have run without error.
    """

    #return self.run_cmd(self.on_cmd)
    self.run_cmd(self.on_cmd)
    #r = open('/home/pi/Speak_CAN/test1-state2', 'r')
    #self.SwitchState = r.read()
    self.SwitchState = "on"
    return True;
    #r.close()

def off(self) -> bool:
    """Run off command.
    Returns:
        True if command seems to have run without error.
    """

    #return self.run_cmd(self.off_cmd)
    self.run_cmd(self.off_cmd)
    #s = open('/home/pi/Speak_CAN/test1-state2', 'r')
    #self.SwitchState = s.read()
    self.SwitchState = "off"
    return True;
    #s.close()

def get_state(self) -> str:
    """Get device state.
    NB: Return code of `0` (i.e. ran without error) indicates "on" state,
    otherwise will be off. making it easier to have something like `ls
    path/to/pidfile` suggest `on`. Many command line switches may not
    actually have a "state" per se (just an arbitary command you want to
    run), in which case you could just put "false" as the command, which
    should always return "off".
    Returns:
        "on" or "off" if `state_cmd` is defined, "unknown" if undefined
    """

    print ("State of " + self.name + " is " + self.SwitchState + ".")
    return self.SwitchState
    #x.close()
    if self.state_cmd is None:
        return "unknown"
    """
    returned_zero = self.run_cmd(self.state_cmd)
    if returned_zero is True:
        return "on"
    return "off"
    """`
Silberbart commented 4 years ago

Ok Perfect. The connection works now after the help of @Tommy-Jack. The issue was the CommandLinePlugin.py

Thanks for all your help.

Regard Silberbart