-
-
Notifications
You must be signed in to change notification settings - Fork 33.8k
Iperf3 not working: unable to send cookie #22163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Seeing the same issue. Home Assistant release with the issue: python3.5 --version Last working Home Assistant release (if known): Operating environment (Hass.io/Docker/Windows/etc.): Problem-relevant configuration.yaml entries and (fill out even if it seems unimportant): Looks like my local iPerf server (networkstatic/iperf3 latest docker image) is receiving the request from Home Assistant's iPerf client but iperf3 entity states remain unknown and running the service throws the "unable to send cookie" error.
|
Are you able to use I'm not. $ iperf3 -c bouygues.iperf.fr
iperf3: error - unable to connect to server: Connection refused |
I'm totally able to use iperf3 from the commandline :
I don't know if it's a noticeable point but Bouygues is my ISP |
Yes, I can run iperf3 from the command line:
|
Got a little more output after 90.2 update.
|
I have the exact same issue after upgrading from 88.2 to 90.2: Also, the iperf3 command works just fine when executed "standalone":
|
I have the same issue. Maybe @rohankapoorcom has more information, since this problem has appeared once the component was split up? |
same issue here. HA on RPi3B, python 3.5. It broke a few HA releases ago; it worked before the split up of the component. I run several RPis around the house and use iperf3 to test the home network throughput. Relevant config: iperf3: Sometimes the manual test will work - I think the first time after an HA restart, but not again until another restart. The sensor values never update. I thought it might be related to using python3.5 vs 3.6 but I have not tested that. iperf3 works fine from the command line as well. I have seen both the "unable to send cookie" and the Keyerror: timestamp error. It seems like HA cannot start the iperf3 binary. |
I've been looking through the code again and trying to reproduce this but I am unable to do so. I took another look at #21138 (where the component was split up) and do not see anything different in how the library is called (and the same version of the library is used) before and after the split. As far as I can tell, all of the syntax should be python 3.5 compliant (though the iperf3 lib specifies it's tested again 2.7 and 3.6 only). Can you check what version of iperf3 you have installed and whether they are on this list? I'm running iperf 3.0.11 on Ubuntu 16.04 (python 3.6.8). |
I have the issue on a Hassbian with Python 3.5.3 and iperf3 3.1.3. |
I'm running iperf3 3.1.3 also with Python 3.5.3 in a Debian Stretch LXC Container. It works perfectly when running from command line, also when using the python3 lib as described in the quickstart part here https://github.com/thiezn/iperf3-python#quickstart
Can we somehow output the command line or the way the python lib is called? |
I did some more testing. I installed python3.6 as per http://www.knight-of-pi.org/installing-python3-6-on-a-raspberry-pi/. I installed home assistant and dependencies ( I use ansible to push the home assistant config and dependencies). I then started hass. No difference with 3.6. Same kind of behaviour. Like @magenbrot said above, can we see if the iperf3 binary is being spawned correctly? |
Tested with a brand new Hassio install, 0.92.2, on a Debian 9 server and unfortunately the issue is still there. |
Having this issue as well on 0.95.4 using the docker container. |
also with lxc here, same issue python 3.6.4 |
HA installs the python wrapper and you must manually install iperf3. any idea how to debug?
|
Looks like this is a known issue with a pending pull request in the source repository for iperf3: |
I'm not a software developer, and I feel like Richard Hendricks in his early days at Hooli using brute force programming, but instantiating a second client for the second iperf3 test plus a 2 second delay fixed this bug for me. Hopefully someone can come up with a more elegant solution. Some additional context here: And my crappy fix of init.py_: """Support for Iperf3 network measurement tool."""
from datetime import timedelta
from time import time, sleep # need a delay between tests
import logging
import iperf3
import voluptuous as vol
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.const import (
CONF_HOST,
CONF_HOSTS,
CONF_MONITORED_CONDITIONS,
CONF_PORT,
CONF_PROTOCOL,
CONF_SCAN_INTERVAL,
)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.discovery import async_load_platform
from homeassistant.helpers.dispatcher import dispatcher_send
from homeassistant.helpers.event import async_track_time_interval
DOMAIN = "iperf3"
DATA_UPDATED = f"{DOMAIN}_data_updated"
_LOGGER = logging.getLogger(__name__)
CONF_DURATION = "duration"
CONF_PARALLEL = "parallel"
CONF_MANUAL = "manual"
DEFAULT_DURATION = 10
DEFAULT_PORT = 5201
DEFAULT_PARALLEL = 1
DEFAULT_PROTOCOL = "tcp"
DEFAULT_INTERVAL = timedelta(minutes=60)
ATTR_DOWNLOAD = "download"
ATTR_UPLOAD = "upload"
ATTR_VERSION = "Version"
ATTR_HOST = "host"
UNIT_OF_MEASUREMENT = "Mbit/s"
SENSOR_TYPES = {
ATTR_DOWNLOAD: [ATTR_DOWNLOAD.capitalize(), UNIT_OF_MEASUREMENT],
ATTR_UPLOAD: [ATTR_UPLOAD.capitalize(), UNIT_OF_MEASUREMENT],
}
PROTOCOLS = ["tcp", "udp"]
HOST_CONFIG_SCHEMA = vol.Schema(
{
vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_DURATION, default=DEFAULT_DURATION): vol.Range(5, 10),
vol.Optional(CONF_PARALLEL, default=DEFAULT_PARALLEL): vol.Range(1, 20),
vol.Optional(CONF_PROTOCOL, default=DEFAULT_PROTOCOL): vol.In(PROTOCOLS),
}
)
CONFIG_SCHEMA = vol.Schema(
{
DOMAIN: vol.Schema(
{
vol.Required(CONF_HOSTS): vol.All(cv.ensure_list, [HOST_CONFIG_SCHEMA]),
vol.Optional(
CONF_MONITORED_CONDITIONS, default=list(SENSOR_TYPES)
): vol.All(cv.ensure_list, [vol.In(list(SENSOR_TYPES))]),
vol.Optional(CONF_SCAN_INTERVAL, default=DEFAULT_INTERVAL): vol.All(
cv.time_period, cv.positive_timedelta
),
vol.Optional(CONF_MANUAL, default=False): cv.boolean,
}
)
},
extra=vol.ALLOW_EXTRA,
)
SERVICE_SCHEMA = vol.Schema({vol.Optional(ATTR_HOST, default=None): cv.string})
async def async_setup(hass, config):
"""Set up the iperf3 component."""
hass.data[DOMAIN] = {}
conf = config[DOMAIN]
for host in conf[CONF_HOSTS]:
host_name = host[CONF_HOST]
client = iperf3.Client()
client.duration = host[CONF_DURATION]
client.server_hostname = host_name
client.port = host[CONF_PORT]
client.num_streams = host[CONF_PARALLEL]
client.protocol = host[CONF_PROTOCOL]
client.verbose = False
# dumb instantiation of second client
client2 = iperf3.Client()
client2.duration = host[CONF_DURATION]
client2.server_hostname = host_name
client2.port = host[CONF_PORT]
client2.num_streams = host[CONF_PARALLEL]
client2.protocol = host[CONF_PROTOCOL]
client2.verbose = False
data = hass.data[DOMAIN][host_name] = Iperf3Data(hass, client, client2)
if not conf[CONF_MANUAL]:
async_track_time_interval(hass, data.update, conf[CONF_SCAN_INTERVAL])
def update(call):
"""Service call to manually update the data."""
called_host = call.data[ATTR_HOST]
if called_host in hass.data[DOMAIN]:
hass.data[DOMAIN][called_host].update()
else:
for iperf3_host in hass.data[DOMAIN].values():
iperf3_host.update()
hass.services.async_register(DOMAIN, "speedtest", update, schema=SERVICE_SCHEMA)
hass.async_create_task(
async_load_platform(
hass, SENSOR_DOMAIN, DOMAIN, conf[CONF_MONITORED_CONDITIONS], config
)
)
return True
class Iperf3Data:
"""Get the latest data from iperf3."""
def __init__(self, hass, client, client2):
"""Initialize the data object."""
self._hass = hass
self._client = client
self._client2 = client2
self.data = {ATTR_DOWNLOAD: None, ATTR_UPLOAD: None, ATTR_VERSION: None}
@property
def protocol(self):
"""Return the protocol used for this connection."""
return self._client.protocol
@property
def host(self):
"""Return the host connected to."""
return self._client.server_hostname
@property
def port(self):
"""Return the port on the host connected to."""
return self._client.port
def update(self, now=None):
"""Get the latest data from iperf3."""
if self.protocol == "udp":
# UDP only have 1 way attribute
result = self._run_test(ATTR_DOWNLOAD)
self.data[ATTR_DOWNLOAD] = self.data[ATTR_UPLOAD] = getattr(
result, "Mbps", None
)
self.data[ATTR_VERSION] = getattr(result, "version", None)
else:
result = self._run_test(ATTR_DOWNLOAD)
self.data[ATTR_DOWNLOAD] = getattr(result, "received_Mbps", None)
self.data[ATTR_VERSION] = getattr(result, "version", None)
self.data[ATTR_UPLOAD] = getattr(
self._run_test(ATTR_UPLOAD), "sent_Mbps", None
)
dispatcher_send(self._hass, DATA_UPDATED, self.host)
def _run_test(self, test_type):
"""Run and return the iperf3 data."""
self._client.reverse = test_type == ATTR_DOWNLOAD
try:
if self._client.reverse:
result = self._client.run()
sleep(2)
else:
result = self._client2.run()
except (AttributeError, OSError, ValueError) as error:
_LOGGER.error("Iperf3 error: %s", error)
return None
if result is not None and hasattr(result, "error") and result.error is not None:
_LOGGER.error("Iperf3 error: %s", result.error)
return None
return result |
Thanks for finding the problem @dooz127. I'll make a PR with the requisite changes this evening. Currently debating between storing 2 clients or just regenerating a client every time it's needed. |
Having thought about it a bit, I think it's cleaner to regenerate the client every time that it's needed - that means that we can avoid any of the sleeping. |
Uh oh!
There was an error while loading. Please reload this page.
Home Assistant release with the issue:
hass --version
0.89.2
python3.5 --version
python 3.5.3
Last working Home Assistant release (if known):
Operating environment (Hass.io/Docker/Windows/etc.):
hassbian installation on a Raspberry Pi 2B
Component/platform:
iperf3 => https://www.home-assistant.io/components/iperf3/
Description of problem:
Unable to use iperf3 in home assistant, not data retrieved from the server.
Problem-relevant configuration.yaml entries and (fill out even if it seems unimportant):
Traceback (if applicable):
== log file from /home/homeassistant/.homeassistant/home-assistant.log
Additional information:
I configure logger to have more information on iperf3 components but no more details
The text was updated successfully, but these errors were encountered: