philippelt / netatmo-api-python

Netatmo connect API python client (for Netatmo information, see https://dev.netatmo.com)
GNU General Public License v3.0
186 stars 118 forks source link

No camera reports as No home in standalone application #68

Closed RichieB2B closed 8 months ago

RichieB2B commented 8 months ago

When I test the application stand alone I get:

$ python3 lnetatmo.py 
lnetatmo - WARNING: No home available for testing
lnetatmo - WARNING: No thermostat avaible for testing
lnetatmo - INFO: OK

This is incorrect because I do have a home, just no camera. The error is raised here: https://github.com/philippelt/netatmo-api-python/blob/9f87b575e8bfba08af4e414b5fcf844eb0fba242/lnetatmo.py#L549

and it is misinterpreted here: https://github.com/philippelt/netatmo-api-python/blob/9f87b575e8bfba08af4e414b5fcf844eb0fba242/lnetatmo.py#L916-L917

JurgenLB commented 8 months ago

I believe Netatmo has made a change in the API

I think this can be a solution;

try:
   homes = HomeData(authorization)
   #
   for k, v in homes.homes.items():
       #print (v.keys())
       C = v.pop('cameras')
       P = v.pop('persons')
       S = v.pop('smokedetectors')
       #
       if C == [] and P == [] and S == [] :
           logger.info("No Cameras, Persons, Smokedetectors found")
           #
       else:
           homeid = k

except NoDevice :
        logger.warning("No home available for testing")

the keys in homedata for me are; dict_keys(['id', 'name', 'persons', 'place', 'cameras', 'smokedetectors', 'events'])

RichieB2B commented 8 months ago

For me the keys in homedata are:

dict_keys(['id', 'name', 'place', 'cameras', 'smokedetectors'])

cameras and smokedetectors are indeed empty lists.

JurgenLB commented 8 months ago

Then I think we must do;

C = v.pop('cameras', None)
P = v.pop('persons', None)
S = v.pop('smokedetectors', None)   
#
if C == [] and P == [] and S == []:
    logger.info("No Cameras, Persons, Smokedetectors found")
    #
elif C == [] and S == []:
     logger.info("No Cameras or Smokedetectors found")
     #
else:
     homeid = k
RichieB2B commented 8 months ago

When you pop with None as a default you need to change the if statements:

C = v.pop('cameras', None)
P = v.pop('persons', None)
S = v.pop('smokedetectors', None)
if not C and not P and not S:
    logger.info("No Cameras, Persons, Smokedetectors found")
elif not C and not S:
    logger.info("No Cameras and Smokedetectors found")
else:
    homeid = k

I think this makes more sense:

C = v.pop('cameras', None)
P = v.pop('persons', None)
S = v.pop('smokedetectors', None)
if not C:
    logger.info("No Cameras found")
if not P:
    logger.info("No Persons found")
if not S:
    logger.info("No Smokedetectors found")
homeid = k
JurgenLB commented 8 months ago

Your first suggestion is also good for me.

and with your last suggestion there is always a return; homeid = k since there are no Cameras, Persons or Smokedetectors found, I think there is no need to return homeid = k

But if there is no 'homeid' the auto-test of class HomesData will also fail .

JurgenLB commented 8 months ago

My solution is for the moment in #66 The maintainer is currently overloaded, He will try to find some free time in the coming weeks.

RichieB2B commented 8 months ago

I see your point. How about this?

C = v.pop('cameras', None)
P = v.pop('persons', None)
S = v.pop('smokedetectors', None)
if not C:
    logger.info("No Cameras found")
if not P:
    logger.info("No Persons found")
if not S:
    logger.info("No Smokedetectors found")
if C or P or S:
    homeid = k
JurgenLB commented 8 months ago

After some more testing, I have found that that this code is good for the auto-test but not as you use it as a module. Then the code still fails on No camera available in default home I have this also tested with a different home from family (They only have 1 thermostat), sinds I have camera's.

I found another solution for this;

self.homes = { d['id'] : d for d in self.rawData['homes'] }
#
for k, v in self.homes.items():
    self.homeid = k
    C = v.get('cameras')
    P = v.get('persons')
    S = v.get('smokedetectors')
    E = v.get('events')
    if not S:
        logger.warning('No Smokedetectors found')
#        raise NoDevice("No Devices available")
    if not C:
        logger.warning('No Cameras found')
#       raise NoDevice("No Cameras available")
    if not P:
        logger.warning('No Persons found')
#        raise NoDevice("No Persons available")
    if not E:
        logger.warning('No events found')
#        raise NoDevice("No Events available")
    if S or C or P or E:
        self.default_home = home or list(self.homes.values())[0]['name']

        # Split homes data by category
        self.persons = dict()
        self.events = dict()
        self.cameras = dict()
        self.lastEvent = dict()
        for i in range(len(self.rawData['homes'])):
            curHome = self.rawData['homes'][i]
            nameHome = curHome['name']
            if nameHome not in self.cameras:
                self.cameras[nameHome] = dict()
            if 'persons' in curHome:
                for p in curHome['persons']:
                    self.persons[ p['id'] ] = p
            if 'events' in curHome:
                for e in curHome['events']:
                    if e['camera_id'] not in self.events:
                        self.events[ e['camera_id'] ] = dict()
                        self.events[ e['camera_id'] ][ e['time'] ] = e
            if 'cameras' in curHome:
                for c in curHome['cameras']:
                    self.cameras[nameHome][ c['id'] ] = c
                    c["home_id"] = curHome['id']
            for camera in self.events:
                self.lastEvent[camera] = self.events[camera][sorted(self.events[camera])[-1]]
            if not self.cameras[self.default_home] : raise NoDevice("No camera available in default home")
            self.default_camera = list(self.cameras[self.default_home].values())[0]
else:
    pass

and in the self-test;

homes = HomeData(authorization)
homeid = homes.homeid

When someone uses this and don't have 'Smokesensor' or 'Cameras' or 'Persons' or 'Events' in their home, this result in the message on their console;

No Smokedetectors found
No Cameras found
No Persons found
No events found

This is possible unwanted. But I believe in this case it can be useful. For my home and family home this is working now (With some changes on the thermostat, but that is another Issue)

JurgenLB commented 8 months ago

This is adopted in #71

RichieB2B commented 8 months ago

Thanks!