Closed strunker closed 1 year ago
This may be a useful reference: https://fauxmo.readthedocs.io/en/latest/md/protocol_notes.html
My understanding is that the echo devices will send get request to fauxmo for the config setup.xml once its read the echo device should send a post back to fauxmo and the switch is then added. I never seem to get anything back from the echo device
I think it should be:
setup.xml
after you've asked it to ("alexa find connected devices")With a quick review, everything above looks to be working correctly, I'm not sure why the devices aren't getting added to your Alexa device. I've never used the show or studio, so I don't know if there presence in your network changes anything. Which device are you using to make the "find connected devices" request?
This may be a useful reference: https://fauxmo.readthedocs.io/en/latest/md/protocol_notes.html
My understanding is that the echo devices will send get request to fauxmo for the config setup.xml once its read the echo device should send a post back to fauxmo and the switch is then added. I never seem to get anything back from the echo device
I think it should be:
- echo requests
setup.xml
after you've asked it to ("alexa find connected devices")- fauxmo responds as per above
- (nothing expected back from the echo)
With a quick review, everything above looks to be working correctly, I'm not sure why the devices aren't getting added to your Alexa device. I've never used the show or studio, so I don't know if there presence in your network changes anything. Which device are you using to make the "find connected devices" request?
Thanks for the reference. And I have 4 devices in total, two echo gen 4s, one echo studio, one echo show. When I ask the studio, usually because its closest to me on my work desk, they all seem to go into discovery mode so it isnt just one device. I could try unplugging the others and forcing discovery on only one and see what happens. I dont think there is a way to control discovery from just a specific echo device that I have seen.
From the docs above, there is a POST back that the echo does to getbinarystate. It can serve as an acknowledgement that the device was properly added. Mine never seem to do that, my echo devices never send back that post acknowledging the switch\plug was added properly. I can try to unplug some of the devices and see if that makes a difference.
I can go to a browser from a different computer and reach the port properly in a browser and view the setup xml. Are there any other port requiremnts im maybe not thinking of or understanding?
Thanks much, really hope I can get this working, but in any case this entire project is good work and super cool. I have a lot of use cases for this so really been trying to persist in getting it fixed.
I could try unplugging the others and forcing discovery on only one and see what happens. I dont think there is a way to control discovery from just a specific echo device that I have seen.
That's probably what I would do, I also don't know how to force requests from a device. I don't know if it will make a difference, I don't have those other devices to test, but that's probably what I would try next.
From the docs above, there is a POST back that the echo does to getbinarystate
As it says, this is "when viewing a device" -- since your devices aren't getting added (yet) I would not expect to see this. (Conversely, if you saw this, it would be evidence that your devices had already been added by the echo).
I can go to a browser from a different computer and reach the port properly in a browser and view the setup xml. Are there any other port requiremnts im maybe not thinking of or understanding?
No, it sounds like this is correct.
Thanks much, really hope I can get this working, but in any case this entire project is good work and super cool. I have a lot of use cases for this so really been trying to persist in getting it fixed.
Hopefully we can sort it out, thanks for the kind words!
I have an echo 4 (one of the big round ones) and it seemed to be adding new devices without trouble last week, so I think it should still work for you as well.
I just ran around the apartment, unplugged all but the studio. Sadly, didnt seem to help. Its kind of interesting too because I see discovery requests flying over to fauxmo regularly even when I dont do device discovery its sending those replies. I actually just unplugged the studio, and I am still seeing requests hit fauxmo so there must be something else on my network doing ssdp discovery requests. Perhaps that could be messing with things.
It would be interesting perhaps for me to on the line below "requested by Echo" to understand what the originating IP address is of the requesting device. To try and nail down which requests are coming from where.
2023-01-01 12:02:12 fauxmo:57 INFO setup.xml requested by Echo 2023-01-01 12:02:12 fauxmo:103 DEBUG Fauxmo response to setup request: HTTP/1.1 200 OK CONTENT-LENGTH: 958 CONTENT-TYPE: text/xml DATE: Sun, 01 Jan 2023 17:02:12 GMT LAST-MODIFIED: Sat, 01 Jan 2000 00:01:15 GMT SERVER: Unspecified, UPnP/1.0, Unspecified X-User-Agent: Fauxmo CONNECTION: close
It is responding back to requests from the hue bridge
as well as my printer
Sadly, didnt seem to help
Bummer, was worth a shot
Its kind of interesting too because I see discovery requests flying over to fauxmo regularly even when I dont do device discovery its sending those replies.
Yes this is normal, just less reliable than manually triggering it
I actually just unplugged the studio, and I am still seeing requests hit fauxmo so there must be something else on my network doing ssdp discovery requests. Perhaps that could be messing with things.
Shouldn't be a problem, I think this is normal with UPnP discovery
It would be interesting perhaps for me to on the line below "requested by Echo" to understand what the originating IP address is of the requesting device. To try and nail down which requests are coming from where.
Unfortunately I don't think that data is available; the debug info comes from the data_received
method which only has access to the data it is sent: https://docs.python.org/3.11/library/asyncio-protocol.html#asyncio.Protocol.data_received
Sadly, didnt seem to help
Bummer, was worth a shot
Its kind of interesting too because I see discovery requests flying over to fauxmo regularly even when I dont do device discovery its sending those replies.
Yes this is normal, just less reliable than manually triggering it
I actually just unplugged the studio, and I am still seeing requests hit fauxmo so there must be something else on my network doing ssdp discovery requests. Perhaps that could be messing with things.
Shouldn't be a problem, I think this is normal with UPnP discovery
It would be interesting perhaps for me to on the line below "requested by Echo" to understand what the originating IP address is of the requesting device. To try and nail down which requests are coming from where.
Unfortunately I don't think that data is available; the debug info comes from the
data_received
method which only has access to the data it is sent: https://docs.python.org/3.11/library/asyncio-protocol.html#asyncio.Protocol.data_received
So just for fun. I made a global var in protocols py that only contains the ip addresses that I want to allow for discovery. Is there a reason that the server itself 127 is sending and responding to requests? Seems a bit off to me. 10.1.1.10 is my server ip and the loop back, its sending and responding back to broadcasts from itself. My idea here is that Ill allow it to reply only from the echo ip address so I can kind of limit all these requests that are flying around.
So, kind of intrestingly I dont actually see any ssdp requests coming from my echo device. I only have the one plugged in right now, the studio, and when I ask it to discover devices im not seeing an incoming requests from its address. I only see the ones coming from and then back to the server itself, which is odd and obviously not expected.
Anyway, ill continue to tinker and close this out shortly here. Just opened it to ensure there was nothing I was missing here.
So determined that the ssdp/upnp requests were coming from the fact I have subsonic/plex also running on that server. I killed the processes for that and it cleaned up those requests. Something maybe of some interest, when you have more than one device it looks like literally all of them send out ssdp discovery requests. You can see here 4 distinct ips, 18,20,19,23, which all correlate back to my varing echo devices.
So that is my ultimate issue here, in my scenario. All 4 of my echo devices are sending out ssdp discovery requests, but as you can see in the below image only the printer on .4 and the hue bridge on .6 ever reply. There is no response from fauxmo, and there should be to advertise the buttons.
I give up for now, truly doesnt make sense why I cant get it going on Windows. Thanks for the guidance here.
@strunker I have the same problem. Devices that used to be recognized fine are now gone. I even tried the sample config, and alexa discovered only one of the three devices (the fake Indigo switch
one). Very odd.
@skorokithakis also on windows?
@n8henrie no, on Linux. Oddly, whenever I use set_fake_state
, it discovers the switches. Otherwise, it doesn't find any of them. Very odd.
@skorokithakis ah, I bet you're running into this: https://github.com/n8henrie/fauxmo-plugins/issues/26
What are you using to determine state?
@n8henrie right now, nothing. I never query the state anyway, so I don't really care about it, but suddenly Alexa stopped discovering devices for my previous script, and now the only thing that works is Fauxmo with the default config, but with fake state.
Ideally, I'd like the MQTT plugin to work, but let's see how it goes. I'll try the resolution in the linked issue, thanks!
Yeah, that's probably the issue. At some point it seems like Alexa stopped recognizing devices that don't present a state, and Fauxmo expects devices to determine their own state whenever possible.
I consider use_fake_state
to be a bit of a kludge and potential footgun, but if Alexa now requires state perhaps I should feature it (and an option for initial_state
more prominently).
@n8henrie it looks like it does, I used use_fake_state
and it seems to work perfectly. Thank you!
I would recommend at least not returning "unknown" for initial discovery ever, as debugging "why doesn't it work" is much easier than "why doesn't it discover".
It's tough, my goal is for it to "fail early and fail loudly" if people have a config error, but this change in Alexa behavior may change my mind on things.
Yeah, this isn't so much a config error, I don't think, as a bug that doesn't let devices with fake state ever be discovered.
@skorokithakis ah, I bet you're running into this: n8henrie/fauxmo-plugins#26
What are you using to determine state?
My version has been working fine now for a couple of months. a bit of a work-around but it works. I for MQTT am replacing use_fake_state with the more MQTTish qos. Currently it defaul;ts to qos=0 I will add qos=1 as well as "retain" in the future. I do not think my changes hurt the normal use of state.
here is my current config
{
"FAUXMO": {
"ip_address": "auto"
},
"PLUGINS": {
"MQTTPlugin": {
"path": "mqttplugin.py",
"DEVICES": [
{
"port": 52511,
"name": "hot",
"on_cmd": [ "jhw/button", "pressed" ],
"off_cmd": [ "jhw/button", "pressed" ],
"mqtt_server": "home-broker.local",
"mqtt_port": 1883
},
{
"port": 52011,
"name": "lower heater",
"on_cmd": [ "jed/relay2", "on" ],
"off_cmd": [ "jed/relay2", "off" ],
"mqtt_server": "home-broker.local",
"mqtt_port": 1883
},
{
"port": 52015,
"name": "upper heater",
"on_cmd": [ "jed/relay1", "on" ],
"off_cmd": [ "jed/relay1", "off" ],
"mqtt_server": "home-broker.local",
"mqtt_port": 1883
}
]
}
}
}
@skorokithakis i didn't mean a bug in your config specifically, rather in any config in which the state_cmd was misconfigured and therefore not returning meaningful data, which I would prefer to fail by default (instead of letting a user discover days or weeks later that their device state is out of sync with reality).
Using a proper way to query device state is strongly preferred whenever possible, but I've opened a new issue as this new Alexa behavior makes (at the very least) my existing readme incorrect.
Glad I didn't go 1.0 yet 😛
I'm away from home for a couple weeks, will address this soon.
Oh, I agree, but for when the state command is missing, it should return "on" so the device doesn't fail to pair.
About the stare command being present but not working, I'd maybe think that letting the device pair successfully and fail when turning on/off is better UX. It would be surprising if discovery failed because of the state, but much less surprising if it failed because of the state when turning on or off.
My patch returns a "on" when no status was given. It is pairing nice. Also all ways runs the loop. Some changes are made to make it more MQTT specific in the future.
@skorokithakis
Here is the complete version I am using. I am treating "state" as a option not as a requirement. use_fake_state
is ignored. If you need the state command
it should still work as before. MQTT QoS=0 is the default and I have not implemented QoS=1
or retain
yet. It works fine during device discovery, which was the problem I was originally addressing. In the process of getting that to work I added some stuff to make it a little more fault tolerant. The loop
is fixed and runs all the time now. This is the currently running version, it has been running for over a month. I need to change some of the comments as well as the QoS stuff. Too many irons in the fire at the moment.
"""Fauxmo plugin for simple MQTT requests.
The on and off methods publish a value to the given MQTT queue. The get_status
method subscribes to an MQTT queue to asynchronously receive the status
published from the device. If the device doesn’t publish a status via MQTT then
omit the state_cmd and the plugin will return a status of “unknown”. The status
received from the device is passed back unchanged to fauxmo which is expecting
“on”, “off” or “unknown”.
Behaviour of the plugin is not entirely predictable if mqttserver and mqttport
are omitted, please make sure to set in your config.
Example config:
{ "FAUXMO": { "ip_address": "auto"
},
"PLUGINS": {
"MQTTPlugin": {
"path": "/path/to/mqttplugin.py",
"DEVICES": [
{
"port": 12349,
"on_cmd": [ "Home/Light/Study01", "1" ],
"off_cmd": [ "Home/Light/Study01", "0" ],
"state_cmd": "Home/Light/Study01",
"name":"MQTT Study Light 1",
"mqtt_server": "test.mosquitto.org",
"mqtt_client_id": "study_light_one",
"mqtt_port": 1883
},
{
"port": 12350,
"on_cmd": [ "Home/Light/Study02", "1" ],
"off_cmd": [ "Home/Light/Study02", "0" ],
"state_cmd": "Home/Light/Study02",
"name":"MQTT Study Light 2",
"mqtt_server": "test.mosquitto.org",
"mqtt_port": 1883
},
{
"port": 12351,
"on_cmd": [
"home-assistant/devices/cmnd/sonoff1/POWER",
"ON"
],
"off_cmd": [
"home-assistant/devices/cmnd/sonoff1/POWER",
"OFF"
],
"state_cmd": "home-assistant/devices/stat/sonoff1/POWER",
"name":"Hass MQTT device",
"mqtt_server": "192.168.1.108",
"mqtt_port": 1883,
"mqtt_user": "MyHassUser",
"mqtt_pw": "MySecretP@ssword"
}
]
}
}
}
Dependencies:
paho-mqtt==1.3.1
"""
from typing import List, Sequence
from fauxmo.plugins import FauxmoPlugin
from paho.mqtt.client import Client, MQTTMessage
class MQTTPlugin(FauxmoPlugin):
"""Fauxmo plugin to interact with an MQTT server by way of paho."""
def __init__(
self,
*,
name: str,
port: int,
off_cmd: Sequence[str],
on_cmd: Sequence[str],
mqtt_port: int = 1883,
mqtt_pw: str = None,
mqtt_user: str = None,
mqtt_server: str = "127.0.0.1",
mqtt_client_id: str = "",
state_cmd: str = None,
qos: int = 0,
retain: int = 0,
) -> None:
"""Initialize an MQTTPlugin instance.
Kwargs:
name: device name
port: Port for Fauxmo to make this device avail to Echo
mqttport: MQTT server port
mqttserver: MQTT server address
mqttclientid: MQTT client id
mqttuser: MQTT username
mqttpw: MQTT password
off_cmd: [ MQTT topic, value to be publshed as str ] to turn off
on_cmd: [ MQTT topic, value to be publshed as str ] to turn on
state_cmd: MQTT Message to get state
qos: MQTT Quality of Service
retain: MQTT retain
"""
self.on_cmd, self.on_value = on_cmd[0], on_cmd[1]
self.off_cmd, self.off_value = off_cmd[0], off_cmd[1]
self.state_cmd = state_cmd
self.default_state = "off" # discovery needs a valid state, this gets set with on and off
self.qos = qos
self.retain = retain
self.status = "unknown"
self._subscribed = False
self.client = Client(client_id=mqtt_client_id)
if mqtt_user or mqtt_pw:
self.client.username_pw_set(mqtt_user, mqtt_pw)
self.client.on_connect = self.on_connect
self.client.on_subscribe = self.on_subscribe
self.client.on_message = self.on_message
try:
self.client.connect(mqtt_server, mqtt_port, 60)
except Exception as e:
print("connect failed", e)
# this is not fatal for paho, just a warning
# When broker comes alive it reconnects
# handled in the loop thread
# if it is not trapped it terminates fauxmo
super().__init__(name=name, port=port)
self.client.loop_start()
# this is needed for the on_* routines
# as well as the other tasks like reconnect
# and mqtt handshakes
@property
def subscribed(self) -> bool:
"""Property to return whether the subscription has completed."""
return self._subscribed
def on_subscribe(
self, client: Client, userdata: str, mid: int, granted_qos: List[int]
) -> None:
"""Set attribute to show that initial subscription is complete."""
self._subscribed = True
def on_connect(
self, client: Client, userdata: str, flags: dict, rc: int
) -> None:
"""Subscribe to state command on connect (or reconnect)."""
if self.state_cmd is not None:
self.client.subscribe(self.state_cmd)
def on_message(
self, client: Client, userdata: str, message: MQTTMessage
) -> None:
"""Process an incoming message."""
status = message.payload.decode("utf-8")
if status == self.off_value:
self.status = "off"
elif status == self.on_value:
self.status = "on"
def _publish(self, topic: str, value: str) -> bool:
print("topic", topic, "value", value)
try:
msg = self.client.publish(topic, value)
# msg = self.client.publish(topic, value, qos=0, retain=self.retain)
# qos other than 0 have not been implemented yet -- self.qos
print("published")
try:
msg.wait_for_publish()
print("wait returned")
except ValueError:
return False
except:
return False
return True
def on(self) -> bool:
"""Turn on MQTT device.
Returns:
True if device seems to have been turned on.
"""
self.default_state = "on"
print("turn on")
return self._publish(self.on_cmd, self.on_value)
def off(self) -> bool:
"""Turn off MQTT device.
Returns:
True if device seems to have been turned off.
"""
self.default_state = "off"
return self._publish(self.off_cmd, self.off_value)
def get_state(self) -> str:
"""Return the self.status attribute.
`self.status` is set asynchronously in on_message, so it may not
immediately reflect state changed.
Returns:
State if known, else "unknown".
"""
"""
the following is a hack to handle when
it was crashing when no state needed
and a "Alexa discovery devices" is done
"""
print("getting state")
if self.state_cmd is None:
return self.default_state
return self.status
Thanks @jdodgen, that helps. I made similar changes to get mine to run, glad to hear it's been working well for you!
fauxmo --version
): 0.60My Issue
I cant seem to get the devices to properly discover on the echo device.
WHYT
I have tried using the below config.json and fauxmo start properly, runs on the port I chose, etc. I ensured that port 12340 is open in the firewall inbound and outbound. My understanding is that the echo devices will send get request to fauxmo for the config setup.xml once its read the echo device should send a post back to fauxmo and the switch is then added. I never seem to get anything back from the echo device. I have tried this on different machines here, one of which has the windows firewall completely turned off and I still get no post back. No one else seems to be having these types of problems so it ha to be something I am either doing wrong, or a setting some where on my network or my devices.
Just looking for a little guidance if anyone has any to offer. Thank you.
Please make sure you've taken these steps before submitting a new issue:
-vvv
) and include relevant outputconfig.json