etheralm / libpurecool

Python library for dyson devices.
Other
68 stars 30 forks source link

mqtt_connection empty queue error #3

Closed LauraFlem closed 5 years ago

LauraFlem commented 5 years ago

I'm getting an error when I try to collect data from the environmental sensors, using the following code in a loop: devices = dyson_account.devices() connected = devices[0].connect("192.168.0.76") env_state=devices[0].environmental_state current_voc = env_state.volatile_organic_compounds devices[0].disconnect()

It works for 4 iterations of my loop and then crashes with the following error:

File "dyson.py", line 39, in <module> connected = devices[0].connect("192.168.0.76") File "/home/lfleming/anaconda3/lib/python3.6/site-packages/libpurecool/dyson_pure_cool_link.py", line 148, in connect return self._mqtt_connect() File "/home/lfleming/anaconda3/lib/python3.6/site-packages/libpurecool/dyson_pure_cool_link.py", line 159, in _mqtt_connect self._connected = self._connection_queue.get(timeout=10) File "/home/lfleming/anaconda3/lib/python3.6/queue.py", line 172, in get raise Empty queue.Empty

If anyone has come across this issue or has any ideas how to fix it please let me know!

etheralm commented 5 years ago

I'm not exactly sure why this is happening, but the connect and disconnect methods are not meant to be used in rapid succession.

What I can suggest is that you connect to the fan only once, then pass a function that does something with the state to the add_message_listener method of the fan. This way you will read the state only when a new message arrives from the fan which should also be more efficient, since you are not connecting and disconnecting all the time.

Something like this :

devices = dyson_account.devices() 
fan = devices[0]
connected = devices[0].connect("192.168.0.76")

def update_state(message):
    # do something with the state here
    print(fan.environmental_state)
    print(fan.state)

fan.add_message_listener(update_state)

Hope that helps.

LauraFlem commented 5 years ago

Hi etheralm,

Thank you so much for the quick reply. Oh I didn't realise that connecting and disconnecting so much would cause me issues, thank you for clearing this up. I am new to object oriented programming and using message listeners so I am finding difficulty implementing them. I have tried to implement the above code and get no output.

` from libpurecool.dyson import DysonAccount import libpurecool from libpurecool.dyson_pure_cool_link import DysonPureCoolLink from libpurecool.const import FanSpeed, FanMode, NightMode, Oscillation, \ FanState, StandbyMonitoring, QualityTarget, ResetFilter, HeatMode, \ FocusMode, HeatTarget

def update_state(message):

do something with the state here

print(fan.environmental_state)
print(fan.state)

dyson_account = DysonAccount(email,password,"IE") logged = dyson_account.login()

if not logged: print('Unable to login to Dyson account') exit(1)

devices = dyson_account.devices() fan = devices[0]

connected = fan.connect("192.168.0.76")

fan.add_message_listener(update_state)

fan.disconnect() `

I'm trying to access the sensor data to feed its values into controller I have designed for a project, so any advice on how to collect this data would be greatly appreciated.

etheralm commented 5 years ago

I just tested the code you posted and it works for me, I'm getting the following output:

DysonEnvironmentalSensorV2State(temperature=297.3,humidity=36,particulate_matter_25=8,particulate_matter_10=6,volatile_organic_compounds=5,nitrogen_dioxide=1,p25r=9,p10r=10,sleep_timer=0)
DysonPureCoolV2State(fan_power=ON,front_direction=ON,auto_mode=OFF,oscillation_status=ON,oscillation=ON,night_mode=OFF,continuous_monitoring=ON,fan_state=FAN,night_mode_speed=0004,speed=0008,carbon_filter_state=0068,hepa_filter_state=0068,sleep_timer=OFF,oscillation_angle_low=0092,oscillation_angle_high=0272)

Perhaps you are not connecting to the right ip? If the ip is wrong or you can't reach the fan for some other reason, it will look like you are not getting any output because the program hangs on:

connected = fan.connect("192.168.0.76")

while trying to connect to the fan until it times out.

Another suggestion would be to try the autoconnect method of the fan, which should pick the right ip if it is not blocked by some firewall. Try to replace :

connected = fan.connect("192.168.0.76")

with:

connected = fan.auto_connect()

EDIT: btw I've noticed that my fan tends to request a new ip from the dhcp server every 24 or so hours(this shouldn't normally happen), so I had to configure a static ip lease for the fan's mac address on my router. Otherwise I had to reconnect to the fan using the new ip each time that happened.