1818import json , time
1919import imghdr
2020import warnings
21+ import logging
22+
23+ # Just in case method could change
24+ PYTHON3 = (version_info .major > 2 )
2125
2226# HTTP libraries depends upon Python 2 or 3
23- if version_info . major == 3 :
27+ if PYTHON3 :
2428 import urllib .parse , urllib .request
2529else :
2630 from urllib import urlencode
3842# 1 - Values hard coded in the library
3943# 2 - The .netatmo.credentials file in JSON format in your home directory
4044# 3 - Values defined in environment variables : CLIENT_ID, CLIENT_SECRET, USERNAME, PASSWORD
45+ # Note: The USERNAME environment variable may interfer with the envvar used by Windows for login name
46+ # if you have this issue, do not forget to "unset USERNAME" before running your program
4147
4248# Each level override values defined in the previous level. You could define CLIENT_ID and CLIENT_SECRET hard coded in the library
4349# and username/password in .netatmo.credentials or environment variables
4450
45- cred = { # You can hard code authentication information in the following lines
46- "CLIENT_ID" : "" , # Your client ID from Netatmo app registration at http://dev.netatmo.com/dev/listapps
47- "CLIENT_SECRET" : "" , # Your client app secret ' '
48- "USERNAME" : "" , # Your netatmo account username
49- "PASSWORD" : "" # Your netatmo account password
51+ # 1 : Embedded credentials
52+ cred = { # You can hard code authentication information in the following lines
53+ "CLIENT_ID" : "" , # Your client ID from Netatmo app registration at http://dev.netatmo.com/dev/listapps
54+ "CLIENT_SECRET" : "" , # Your client app secret ' '
55+ "USERNAME" : "" , # Your netatmo account username
56+ "PASSWORD" : "" # Your netatmo account password
5057 }
5158
5259# Other authentication setup management (optionals)
@@ -114,6 +121,10 @@ def getParameter(key, default):
114121#_CAM_FTP_ACTIVE = "/command/ftp_set_config?config=on_off:%s" # "on"|"off"
115122
116123
124+ # Logger context
125+ logger = logging .getLogger ("lnetatmo" )
126+
127+
117128class NoDevice ( Exception ):
118129 pass
119130
@@ -580,7 +591,7 @@ def personSeenByCamera(self, name, home=None, camera=None):
580591 try :
581592 cam_id = self .cameraByName (camera = camera , home = home )['id' ]
582593 except TypeError :
583- print ("personSeenByCamera: Camera name or home is unknown" )
594+ logger . warning ("personSeenByCamera: Camera name or home is unknown" )
584595 return False
585596 #Check in the last event is someone known has been seen
586597 if self .lastEvent [cam_id ]['type' ] == 'person' :
@@ -604,7 +615,7 @@ def someoneKnownSeen(self, home=None, camera=None):
604615 try :
605616 cam_id = self .cameraByName (camera = camera , home = home )['id' ]
606617 except TypeError :
607- print ("personSeenByCamera: Camera name or home is unknown" )
618+ logger . warning ("personSeenByCamera: Camera name or home is unknown" )
608619 return False
609620 #Check in the last event is someone known has been seen
610621 if self .lastEvent [cam_id ]['type' ] == 'person' :
@@ -619,7 +630,7 @@ def someoneUnknownSeen(self, home=None, camera=None):
619630 try :
620631 cam_id = self .cameraByName (camera = camera , home = home )['id' ]
621632 except TypeError :
622- print ("personSeenByCamera: Camera name or home is unknown" )
633+ logger . warning ("personSeenByCamera: Camera name or home is unknown" )
623634 return False
624635 #Check in the last event is someone known has been seen
625636 if self .lastEvent [cam_id ]['type' ] == 'person' :
@@ -634,7 +645,7 @@ def motionDetected(self, home=None, camera=None):
634645 try :
635646 cam_id = self .cameraByName (camera = camera , home = home )['id' ]
636647 except TypeError :
637- print ("personSeenByCamera: Camera name or home is unknown" )
648+ logger . warning ("personSeenByCamera: Camera name or home is unknown" )
638649 return False
639650 if self .lastEvent [cam_id ]['type' ] == 'movement' :
640651 return True
@@ -697,14 +708,15 @@ def cameraCommand(cameraUrl, commande, parameters=None, timeout=3):
697708 return postRequest (url , timeout = timeout )
698709
699710def postRequest (url , params = None , timeout = 10 ):
700- if version_info . major == 3 :
711+ if PYTHON3 :
701712 req = urllib .request .Request (url )
702713 if params :
703714 req .add_header ("Content-Type" ,"application/x-www-form-urlencoded;charset=utf-8" )
704715 params = urllib .parse .urlencode (params ).encode ('utf-8' )
705716 try :
706717 resp = urllib .request .urlopen (req , params , timeout = timeout ) if params else urllib .request .urlopen (req , timeout = timeout )
707- except urllib .error .URLError :
718+ except urllib .error .HTTPError as err :
719+ logger .error ("code=%s, reason=%s" % (err .code , err .reason ))
708720 return None
709721 else :
710722 if params :
@@ -713,12 +725,13 @@ def postRequest(url, params=None, timeout=10):
713725 req = urllib2 .Request (url = url , data = params , headers = headers ) if params else urllib2 .Request (url )
714726 try :
715727 resp = urllib2 .urlopen (req , timeout = timeout )
716- except urllib2 .URLError :
728+ except urllib2 .HTTPError as err :
729+ logger .error ("code=%s, reason=%s" % (err .code , err .reason ))
717730 return None
718731 data = b""
719732 for buff in iter (lambda : resp .read (65535 ), b'' ): data += buff
720733 # Return values in bytes if not json data to handle properly camera images
721- returnedContentType = resp .getheader ("Content-Type" ) if version_info . major == 3 else resp .info ()["Content-Type" ]
734+ returnedContentType = resp .getheader ("Content-Type" ) if PYTHON3 else resp .info ()["Content-Type" ]
722735 return json .loads (data .decode ("utf-8" )) if "application/json" in returnedContentType else data
723736
724737def toTimeString (value ):
@@ -761,6 +774,8 @@ def getStationMinMaxTH(station=None, module=None):
761774if __name__ == "__main__" :
762775
763776 from sys import exit , stdout , stderr
777+
778+ logging .basicConfig (format = '%(name)s - %(levelname)s: %(message)s' , level = logging .INFO )
764779
765780 if not _CLIENT_ID or not _CLIENT_SECRET or not _USERNAME or not _PASSWORD :
766781 stderr .write ("Library source missing identification arguments to check lnetatmo.py (user/password/etc...)" )
@@ -771,28 +786,22 @@ def getStationMinMaxTH(station=None, module=None):
771786 try :
772787 weatherStation = WeatherStationData (authorization ) # Test DEVICELIST
773788 except NoDevice :
774- if stdout .isatty ():
775- print ("lnetatmo.py : warning, no weather station available for testing" )
789+ logger .warning ("No weather station available for testing" )
776790 else :
777791 weatherStation .MinMaxTH () # Test GETMEASUR
778792
779793
780794 try :
781795 homes = HomeData (authorization )
782796 except NoDevice :
783- if stdout .isatty ():
784- print ("lnetatmo.py : warning, no home available for testing" )
797+ logger .warning ("No home available for testing" )
785798
786799 try :
787800 thermostat = ThermostatData (authorization )
788801 except NoDevice :
789- if stdout .isatty ():
790- print ("lnetatmo.py : warning, no thermostat avaible for testing" )
802+ logger .warning ("No thermostat avaible for testing" )
791803
792804 # If we reach this line, all is OK
793-
794- # If launched interactively, display OK message
795- if stdout .isatty ():
796- print ("lnetatmo.py : OK" )
805+ logger .info ("OK" )
797806
798807 exit (0 )
0 commit comments