18
18
import json , time
19
19
import imghdr
20
20
import warnings
21
+ import logging
22
+
23
+ # Just in case method could change
24
+ PYTHON3 = (version_info .major > 2 )
21
25
22
26
# HTTP libraries depends upon Python 2 or 3
23
- if version_info . major == 3 :
27
+ if PYTHON3 :
24
28
import urllib .parse , urllib .request
25
29
else :
26
30
from urllib import urlencode
38
42
# 1 - Values hard coded in the library
39
43
# 2 - The .netatmo.credentials file in JSON format in your home directory
40
44
# 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
41
47
42
48
# Each level override values defined in the previous level. You could define CLIENT_ID and CLIENT_SECRET hard coded in the library
43
49
# and username/password in .netatmo.credentials or environment variables
44
50
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
50
57
}
51
58
52
59
# Other authentication setup management (optionals)
@@ -114,6 +121,10 @@ def getParameter(key, default):
114
121
#_CAM_FTP_ACTIVE = "/command/ftp_set_config?config=on_off:%s" # "on"|"off"
115
122
116
123
124
+ # Logger context
125
+ logger = logging .getLogger ("lnetatmo" )
126
+
127
+
117
128
class NoDevice ( Exception ):
118
129
pass
119
130
@@ -580,7 +591,7 @@ def personSeenByCamera(self, name, home=None, camera=None):
580
591
try :
581
592
cam_id = self .cameraByName (camera = camera , home = home )['id' ]
582
593
except TypeError :
583
- print ("personSeenByCamera: Camera name or home is unknown" )
594
+ logger . warning ("personSeenByCamera: Camera name or home is unknown" )
584
595
return False
585
596
#Check in the last event is someone known has been seen
586
597
if self .lastEvent [cam_id ]['type' ] == 'person' :
@@ -604,7 +615,7 @@ def someoneKnownSeen(self, home=None, camera=None):
604
615
try :
605
616
cam_id = self .cameraByName (camera = camera , home = home )['id' ]
606
617
except TypeError :
607
- print ("personSeenByCamera: Camera name or home is unknown" )
618
+ logger . warning ("personSeenByCamera: Camera name or home is unknown" )
608
619
return False
609
620
#Check in the last event is someone known has been seen
610
621
if self .lastEvent [cam_id ]['type' ] == 'person' :
@@ -619,7 +630,7 @@ def someoneUnknownSeen(self, home=None, camera=None):
619
630
try :
620
631
cam_id = self .cameraByName (camera = camera , home = home )['id' ]
621
632
except TypeError :
622
- print ("personSeenByCamera: Camera name or home is unknown" )
633
+ logger . warning ("personSeenByCamera: Camera name or home is unknown" )
623
634
return False
624
635
#Check in the last event is someone known has been seen
625
636
if self .lastEvent [cam_id ]['type' ] == 'person' :
@@ -634,7 +645,7 @@ def motionDetected(self, home=None, camera=None):
634
645
try :
635
646
cam_id = self .cameraByName (camera = camera , home = home )['id' ]
636
647
except TypeError :
637
- print ("personSeenByCamera: Camera name or home is unknown" )
648
+ logger . warning ("personSeenByCamera: Camera name or home is unknown" )
638
649
return False
639
650
if self .lastEvent [cam_id ]['type' ] == 'movement' :
640
651
return True
@@ -697,14 +708,15 @@ def cameraCommand(cameraUrl, commande, parameters=None, timeout=3):
697
708
return postRequest (url , timeout = timeout )
698
709
699
710
def postRequest (url , params = None , timeout = 10 ):
700
- if version_info . major == 3 :
711
+ if PYTHON3 :
701
712
req = urllib .request .Request (url )
702
713
if params :
703
714
req .add_header ("Content-Type" ,"application/x-www-form-urlencoded;charset=utf-8" )
704
715
params = urllib .parse .urlencode (params ).encode ('utf-8' )
705
716
try :
706
717
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 ))
708
720
return None
709
721
else :
710
722
if params :
@@ -713,12 +725,13 @@ def postRequest(url, params=None, timeout=10):
713
725
req = urllib2 .Request (url = url , data = params , headers = headers ) if params else urllib2 .Request (url )
714
726
try :
715
727
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 ))
717
730
return None
718
731
data = b""
719
732
for buff in iter (lambda : resp .read (65535 ), b'' ): data += buff
720
733
# 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" ]
722
735
return json .loads (data .decode ("utf-8" )) if "application/json" in returnedContentType else data
723
736
724
737
def toTimeString (value ):
@@ -761,6 +774,8 @@ def getStationMinMaxTH(station=None, module=None):
761
774
if __name__ == "__main__" :
762
775
763
776
from sys import exit , stdout , stderr
777
+
778
+ logging .basicConfig (format = '%(name)s - %(levelname)s: %(message)s' , level = logging .INFO )
764
779
765
780
if not _CLIENT_ID or not _CLIENT_SECRET or not _USERNAME or not _PASSWORD :
766
781
stderr .write ("Library source missing identification arguments to check lnetatmo.py (user/password/etc...)" )
@@ -771,28 +786,22 @@ def getStationMinMaxTH(station=None, module=None):
771
786
try :
772
787
weatherStation = WeatherStationData (authorization ) # Test DEVICELIST
773
788
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" )
776
790
else :
777
791
weatherStation .MinMaxTH () # Test GETMEASUR
778
792
779
793
780
794
try :
781
795
homes = HomeData (authorization )
782
796
except NoDevice :
783
- if stdout .isatty ():
784
- print ("lnetatmo.py : warning, no home available for testing" )
797
+ logger .warning ("No home available for testing" )
785
798
786
799
try :
787
800
thermostat = ThermostatData (authorization )
788
801
except NoDevice :
789
- if stdout .isatty ():
790
- print ("lnetatmo.py : warning, no thermostat avaible for testing" )
802
+ logger .warning ("No thermostat avaible for testing" )
791
803
792
804
# 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" )
797
806
798
807
exit (0 )
0 commit comments