Addind Common class for common ressources

Python2:
- Adding Common class for common ressources
- Inheritance from Common to HomeSFR and Sensors (and it's inherited class Camera)
- Adding the Sensors.get_mac () method
- Adding the Camera.get_snapshot () method
- Addind str2bytes () function for Python3 code compatibility (this library and the Python3 ones are quite identical)

Python3:
- Adding Common class for common ressources
- Inheritance from Common to HomeSFR and Sensors (and it's inherited class Camera)
- Adding the Sensors.get_mac () method
- Adding the Camera.get_snapshot () method
- Addind str2bytes () function for Python2 code compatibility (this library and the Python2 ones are quite identical)
- Changing all "readall" to "read", the method "readall" does not seem to exist in Python2, from what I tested, there's no problem with it
This commit is contained in:
Gilles MOREL 2016-05-25 17:19:16 +02:00
parent beae1f2b97
commit 9dd904b4ea
2 changed files with 380 additions and 226 deletions

View File

@ -34,6 +34,7 @@ REMOTE_CONTROLER = 'REMOTE'
KEYPAD_CONTROLER = 'KEYPAD'
PRESENCE_CAMERA_DETECTOR = 'PIR_CAMERA'
# This part of code must be the one to adapt to make work the underneath part
from cookielib import CookieJar
import urllib2 as request
from urllib2 import HTTPError
@ -41,28 +42,119 @@ from urllib import urlencode
from xml.etree import ElementTree as ET
from datetime import datetime
def bytes2file (b):
# Python2 and 3 adaptations
# BEGIN
def str2bytes (s):
'''
Gives a file-like class from a Bytes
Bind to the bytes build-in function
'''
from io import BytesIO
r = BytesIO ()
r.write (b)
r.seek (0)
return (r)
return (bytes (s))
# END
def bytes2image (b):
'''
Gives a Image object from bytes
Uses the bytes2file function
'''
from PIL import Image
f = bytes2file (b)
r = Image ()
r.open (f)
return (r)
# The next must stay a copy from the python3 library, starting from class Common
class HomeSFR ():
class Common ():
'''
Common ressources to the library's classes
'''
def __init__ (self):
# Specific configuration
self.base_url = 'https://home.sfr.fr'
# path to login test
self.auth_path = '/mysensors'
self.auth_ok = '/accueil' # if logged
self.auth_post_url = 'https://boutique.home.sfr.fr/authentification'
self.auth_referer = 'https://boutique.home.sfr.fr/authentification?back=service'
self.auth_user_field = 'email'
self.auth_pass_field = 'passwd'
self.auth_extra_fields = {'back': 'service', 'token_sso': '', 'error_sso': '', 'SubmitLogin': 'OK'}
self.auth_logout_path = '/deconnexion'
# Path to sensors and mode
self.sensors_list = '/mysensors'
# Path to list of alerts
self.alerts_path = '/listalert'
# Path to get and set modes
self.mode_get_path = '/mysensors'
self.mode_get_label = 'alarm_mode'
self.mode_set_path = '/alarmmode'
self.mode_set_field = 'action' # Name for GET field
self.mode_off = 'OFF' # Value for off
self.mode_custom = 'CUSTOM' # Value for custom
self.mode_on = 'ON' # Value for on
# Cameras
self.cameras_list = '/homescope/mycams'
self.camera_snapshot = '/homescope/snapshot'
self.camera_snapshot_mac = 'mac'
self.camera_video = '/homescope/flv'
self.camera_vide_mac = 'mac'
self.camera_recordings_list = '/listenr'
self.camera_recordings_delete = '/delenr'
self.camera_recordings_start = '/homescope/record'
self.camera_recordings_stop = '/homescope/stoprecord'
self.camera_recordings_mac = 'mac'
self.camera_get_config_path = '/homescope/camsettings'
self.camera_get_config_mac = 'mac'
self.camera_get_config_flip = 'FLIP'
self.camera_get_config_leds = 'LEDMODE' # set to 0 to turn the leds on
self.camera_get_config_detectionsensibility = 'DP' # from 1 to 4
self.camera_get_config_recording = 'REC24'
self.camera_get_config_name = 'NAME'
self.camera_set_config_path = '/homescope/camsettings'
self.camera_set_config_mac = 'mac'
self.camera_set_config_flip = 'flip'
self.camera_set_config_leds = 'led_mode' # set to 0 to turn the leds on
self.camera_set_config_detectionsensibility = 'dp' # from 1 to 4
self.camera_set_config_recording = 'rec24'
self.camera_set_config_name = 'name'
# Sensors
self.sensors_list = '/mysensors'
self.sensors_label = 'Sensor'
self.sensors_label_id = 'id'
self.sensors_mac_field = 'deviceMac'
self.sensors_type_field = 'deviceType'
self.sensors_model_field = 'deviceModel'
self.sensors_version_field = 'deviceVersion'
self.sensors_name_field = 'name'
self.sensors_longname_field = 'long_name'
self.sensors_namegender_field = 'name_gender' # Only usefull for French for the moment
self.sensors_batterylevel_field = 'batteryLevel'
self.sensors_signal_field = 'signalLevel'
self.sensors_lasttrigger_field = 'lastTriggerTime'
self.sensors_lasttrigger_dateformat = '%Y-%m-%d %H:%M:%S'
self.sensors_status_field = 'status'
self.sensors_status_value_ok = 'OK'
# I don't have any other value for the moment
def bytes2file (self, b):
'''
Gives a file-like class from a Bytes
'''
from io import BytesIO
r = BytesIO ()
r.write (b)
r.seek (0)
return (r)
def bytes2image (self, b):
'''
Gives a Image object from bytes
Uses the bytes2file function
'''
from PIL import Image
f = self.bytes2file (b)
r = Image.open (f)
return (r)
class HomeSFR (Common):
def __init__ (self, username = None, password = None, cookies = None, debug = False, autologin = True):
'''
Sets the class with username and password couple, or cookies
@ -71,6 +163,7 @@ class HomeSFR ():
The autologin parameter defines if the class will manage the login by itself, if False, the user must call login () to login and test_login () to check the login
The autologin paramater will always be False if no username and password are defined, and the login () method will always return False
'''
Common.__init__ (self)
self.DEBUG = debug
if self.DEBUG:
print (name + ' ' + version)
@ -97,49 +190,7 @@ class HomeSFR ():
else:
self.cookies = cookies
self.opener = request.build_opener (request.HTTPCookieProcessor (self.cookies))
# Specific configuration
self.base_url = 'https://home.sfr.fr'
# path to login test
self.auth_path = '/mysensors'
self.auth_ok = '/accueil' # if logged
self.auth_post_url = 'https://boutique.home.sfr.fr/authentification'
self.auth_referer = 'https://boutique.home.sfr.fr/authentification?back=service'
self.auth_user_field = 'email'
self.auth_pass_field = 'passwd'
self.auth_extra_fields = {'back': 'service', 'token_sso': '', 'error_sso': '', 'SubmitLogin': 'OK'}
self.auth_logout_path = '/deconnexion'
# Path to sensors and mode
self.sensors_list = '/mysensors'
self.sensors_label = 'Sensor'
self.sensors_label_id = 'id'
# Path to list of alerts
self.alerts_path = '/listalert'
# Path to get and set modes
self.mode_get_path = '/mysensors'
self.mode_get_label = 'alarm_mode'
self.mode_set_path = '/alarmmode'
self.mode_set_field = 'action' # Name for GET field
self.mode_off = 'OFF' # Value for off
self.mode_custom = 'CUSTOM' # Value for custom
self.mode_on = 'ON' # Value for on
# Cameras
# mac=00:0e:8f:c9:59:44&flip=0&led_mode=0&alert_pan=1&rec24=0&da=1&dp=4&name=Salon
self.cameras_list = '/homescope/mycams'
self.camera_snapshot = '/homescope/snapshot'
self.camera_video = '/homescope/flv'
self.camera_get_config_path = '/homescope/camsettings'
self.camera_set_config_path = '/homescope/camsettings'
self.camera_set_config_mac = 'mac'
self.camera_set_config_flip = 'flip'
self.camera_set_config_leds = 'led_mode' # set to 0 to turn the leds on
self.camera_set_config_detectionsensibility = 'dp' # from 1 to 4,
def __str__ (self):
'''
Shows name, version, defined user and debug state
@ -178,7 +229,7 @@ class HomeSFR ():
data = self.auth_extra_fields
data [self.auth_user_field] = self.username
data [self.auth_pass_field] = self.password
data = bytes (urlencode (data))
data = str2bytes (urlencode (data))
if self.DEBUG:
print ('Cookies ' + str( len(self.cookies)))
print ('Sending data ' + str (data))
@ -243,7 +294,7 @@ class HomeSFR ():
r = self.base_url + self.mode_get_path
if self.DEBUG:
print ('Getting ' + r)
a = bytes2file (self.opener.open (r).read ())
a = self.bytes2file (self.opener.open (r).read ())
b = ET.parse (a).getroot ()
c = b.get (self.mode_get_label)
if self.DEBUG:
@ -263,7 +314,7 @@ class HomeSFR ():
if (self.autologin and self.test_login () == False):
self.login ()
r = self.base_url + self.sensors_list
a = bytes2file (self.opener.open (r).read ())
a = self.bytes2file (self.opener.open (r).read ())
b = ET.parse (a)
r = []
for i in b.findall (self.sensors_label):
@ -275,29 +326,11 @@ class HomeSFR ():
Returns a Sensor object for the sensor id or None if sensor is not found
The available ids can be got from the list_sensors method
'''
def build_tree (element):
r = {}
if self.DEBUG:
print ('Diving in the element ' + element.tag)
for i in element.getchildren ():
if i.getchildren () == []:
r.update ({i.tag: i.text})
else:
r.update ({i.tag: build_tree (i)})
return (r)
if (self.autologin and self.test_login () == False):
self.login ()
r = self.base_url + self.sensors_list
a = bytes2file (self.opener.open (r).read ())
b = ET.parse (a)
r = None
for i in b.findall (self.sensors_label):
if self.DEBUG:
print ('Testing sensors ' + i.get (self.sensors_label_id))
if (i.get (self.sensors_label_id) == id):
r = build_tree (i)
break
return (Sensor (r))
r = Sensor (id, self.opener)
r.refresh ()
return (r)
def get_all_sensors (self):
'''
@ -307,32 +340,52 @@ class HomeSFR ():
for i in self.list_sensors ():
r.append (self.get_sensor (i))
return (tuple (r))
def get_camera (self, id):
'''
Get a Camera object from the sensor's id
'''
if (self.autologin and self.test_login () == False):
self.login ()
r = Camera (id, self.opener)
r.refresh ()
return (r)
class Sensor:
class Sensor (Common):
'''
Class used to read easily the sensors
'''
def __init__ (self, sensor_dict):
def __init__ (self, id, opener):
'''
Initialize the class with the dict producted by HomeSFR.get_sensors ()
'''
Common.__init__ (self)
self.sensor_dict = sensor_dict
# Field names
self.type_field = 'deviceType'
self.model_field = 'deviceModel'
self.version_field = 'deviceVersion'
self.name_field = 'name'
self.longname_field = 'long_name'
self.namegender_field = 'name_gender' # Only usefull for French for the moment
self.batterylevel_field = 'batteryLevel'
self.signal_field = 'signalLevel'
self.lasttrigger_field = 'lastTriggerTime'
self.lasttrigger_dateformat = '%Y-%m-%d %H:%M:%S'
self.status_field = 'status'
self.status_value_ok = 'OK'
# I don't have any other value for the moment
self.id = id
self.sensor_dict = None
self.opener = opener
def refresh (self):
'''
Gets or refresh the data for the sensor
'''
def build_tree (element):
r = {}
for i in element.getchildren ():
if i.getchildren () == []:
r.update ({i.tag: i.text})
else:
r.update ({i.tag: build_tree (i)})
return (r)
r = self.base_url + self.sensors_list
a = self.bytes2file (self.opener.open (r).read ())
a.seek (0)
b = ET.parse (a)
self.sensor_dict = None
for i in b.findall (self.sensors_label):
if (i.get (self.sensors_label_id) == self.id):
self.sensor_dict = build_tree (i)
break
def get_raw (self):
'''
@ -340,72 +393,97 @@ class Sensor:
'''
return (self.sensor_dict)
def get_mac (self):
'''
Returns the sensor's model, if any, None either
'''
return (self.sensor_dict [self.sensors_mac_field])
def get_type (self):
'''
Returns the sensor's type
'''
return (self.sensor_dict [self.type_field])
return (self.sensor_dict [self.sensors_type_field])
def get_model (self):
'''
Returns the sensor's model, if any, None either
'''
return (self.sensor_dict [self.model_field])
return (self.sensor_dict [self.sensors_model_field])
def get_version (self):
'''
Returns the sensor's version
'''
return (self.sensor_dict [self.version_field])
return (self.sensor_dict [self.sensors_version_field])
def get_name (self):
'''
Returns the sensor's name
'''
return (self.sensor_dict [self.name_field])
return (self.sensor_dict [self.sensors_name_field])
def get_longname (self):
'''
Returns the sensor's type name in system's language and the sensor's name
'''
return (self.sensor_dict [self.longname_field])
return (self.sensor_dict [self.sensors_longname_field])
def get_namegender (self):
'''
Return M for male and F for female.
Only usefull for languages with gender on nouns
'''
return (self.sensor_dict [self.namegender_field])
return (self.sensor_dict [self.sensors_namegender_field])
def get_batterylevel (self):
'''
Returns the sensor's battery level, out of 10
It seems that batteryless sensors return 255
'''
return (int (self.sensor_dict [self.batterylevel_field]))
return (int (self.sensor_dict [self.sensors_batterylevel_field]))
def get_signal (self):
'''
Returns the sensor's signal quality, out of 10
'''
return (int (self.sensor_dict [self.signal_field]))
return (int (self.sensor_dict [self.sensors_signal_field]))
def get_lasttrigger (self):
'''
Return the timestamp of the sensor's last triger
The sensors always trigger, even when the alarm's mode is off
'''
a = self.sensor_dict [self.lasttrigger_field]
a = self.sensor_dict [self.sensors_lasttrigger_field]
# Try because camera return the date '0000-00-00 00:00:00' that is ununderstandable
try:
b = datetime.strptime (a, self.lasttrigger_dateformat)
b = datetime.strptime (a, self.sensors_lasttrigger_dateformat)
except ValueError:
return (0)
r = int (b.strftime ('%s'))
r = int (b.timestamp ())
return (r)
def get_status (self):
'''
Returns True is the sensor is OK, False either
'''
return (self.sensor_dict [self.status_field] == self.status_value_ok)
return (self.sensor_dict [self.sensors_status_field] == self.sensors_status_value_ok)
class Camera (Sensor):
'''
Class used to manipulate easily cameras
'''
def __init__ (self, sensor_dict, opener):
'''
Initialize the class with the dict producted by HomeSFR.get_camera ()
'''
Sensor.__init__ (self, sensor_dict, opener)
def get_snapshot (self):
'''
Get a snapshot from the camera
Return a PIL.Image object
'''
r = self.base_url + self.camera_snapshot + '?' + self.camera_snapshot_mac + '=' + self.get_mac ()
a = self.bytes2image (self.opener.open (r).read ())
return (a)

View File

@ -7,6 +7,7 @@ This is a wrap aroud website, this could stop working without prior notice
'''
# TODO:
## Put common ressources in the Common class
## Manage cameras
### Get image
### Get video
@ -39,28 +40,117 @@ from xml.etree import ElementTree as ET
from urllib.error import HTTPError
from datetime import datetime
def bytes2file (b):
# Python2 and 3 adaptations
# BEGIN
def str2bytes (s):
'''
Gives a file-like class from a Bytes
Bind to the bytes build-in function
'''
from io import BytesIO
r = BytesIO ()
r.write (b)
r.seek (0)
return (r)
return (bytes (s, 'UTF8'))
# END
def bytes2image (b):
class Common ():
'''
Gives a Image object from bytes
Uses the bytes2file function
Common ressources to the library's classes
'''
from PIL import Image
f = bytes2file (b)
r = Image ()
r.open (f)
return (r)
def __init__ (self):
# Specific configuration
self.base_url = 'https://home.sfr.fr'
# path to login test
self.auth_path = '/mysensors'
self.auth_ok = '/accueil' # if logged
self.auth_post_url = 'https://boutique.home.sfr.fr/authentification'
self.auth_referer = 'https://boutique.home.sfr.fr/authentification?back=service'
self.auth_user_field = 'email'
self.auth_pass_field = 'passwd'
self.auth_extra_fields = {'back': 'service', 'token_sso': '', 'error_sso': '', 'SubmitLogin': 'OK'}
self.auth_logout_path = '/deconnexion'
# Path to sensors and mode
self.sensors_list = '/mysensors'
# Path to list of alerts
self.alerts_path = '/listalert'
# Path to get and set modes
self.mode_get_path = '/mysensors'
self.mode_get_label = 'alarm_mode'
self.mode_set_path = '/alarmmode'
self.mode_set_field = 'action' # Name for GET field
self.mode_off = 'OFF' # Value for off
self.mode_custom = 'CUSTOM' # Value for custom
self.mode_on = 'ON' # Value for on
# Cameras
self.cameras_list = '/homescope/mycams'
self.camera_snapshot = '/homescope/snapshot'
self.camera_snapshot_mac = 'mac'
self.camera_video = '/homescope/flv'
self.camera_vide_mac = 'mac'
self.camera_recordings_list = '/listenr'
self.camera_recordings_delete = '/delenr'
self.camera_recordings_start = '/homescope/record'
self.camera_recordings_stop = '/homescope/stoprecord'
self.camera_recordings_mac = 'mac'
self.camera_get_config_path = '/homescope/camsettings'
self.camera_get_config_mac = 'mac'
self.camera_get_config_flip = 'FLIP'
self.camera_get_config_leds = 'LEDMODE' # set to 0 to turn the leds on
self.camera_get_config_detectionsensibility = 'DP' # from 1 to 4
self.camera_get_config_recording = 'REC24'
self.camera_get_config_name = 'NAME'
self.camera_set_config_path = '/homescope/camsettings'
self.camera_set_config_mac = 'mac'
self.camera_set_config_flip = 'flip'
self.camera_set_config_leds = 'led_mode' # set to 0 to turn the leds on
self.camera_set_config_detectionsensibility = 'dp' # from 1 to 4
self.camera_set_config_recording = 'rec24'
self.camera_set_config_name = 'name'
# Sensors
self.sensors_list = '/mysensors'
self.sensors_label = 'Sensor'
self.sensors_label_id = 'id'
self.sensors_mac_field = 'deviceMac'
self.sensors_type_field = 'deviceType'
self.sensors_model_field = 'deviceModel'
self.sensors_version_field = 'deviceVersion'
self.sensors_name_field = 'name'
self.sensors_longname_field = 'long_name'
self.sensors_namegender_field = 'name_gender' # Only usefull for French for the moment
self.sensors_batterylevel_field = 'batteryLevel'
self.sensors_signal_field = 'signalLevel'
self.sensors_lasttrigger_field = 'lastTriggerTime'
self.sensors_lasttrigger_dateformat = '%Y-%m-%d %H:%M:%S'
self.sensors_status_field = 'status'
self.sensors_status_value_ok = 'OK'
# I don't have any other value for the moment
class HomeSFR ():
def bytes2file (self, b):
'''
Gives a file-like class from a Bytes
'''
from io import BytesIO
r = BytesIO ()
r.write (b)
r.seek (0)
return (r)
def bytes2image (self, b):
'''
Gives a Image object from bytes
Uses the bytes2file function
'''
from PIL import Image
f = self.bytes2file (b)
r = Image.open (f)
return (r)
class HomeSFR (Common):
def __init__ (self, username = None, password = None, cookies = None, debug = False, autologin = True):
'''
Sets the class with username and password couple, or cookies
@ -69,6 +159,7 @@ class HomeSFR ():
The autologin parameter defines if the class will manage the login by itself, if False, the user must call login () to login and test_login () to check the login
The autologin paramater will always be False if no username and password are defined, and the login () method will always return False
'''
Common.__init__ (self)
self.DEBUG = debug
if self.DEBUG:
print (name + ' ' + version)
@ -95,48 +186,6 @@ class HomeSFR ():
else:
self.cookies = cookies
self.opener = request.build_opener (request.HTTPCookieProcessor (self.cookies))
# Specific configuration
self.base_url = 'https://home.sfr.fr'
# path to login test
self.auth_path = '/mysensors'
self.auth_ok = '/accueil' # if logged
self.auth_post_url = 'https://boutique.home.sfr.fr/authentification'
self.auth_referer = 'https://boutique.home.sfr.fr/authentification?back=service'
self.auth_user_field = 'email'
self.auth_pass_field = 'passwd'
self.auth_extra_fields = {'back': 'service', 'token_sso': '', 'error_sso': '', 'SubmitLogin': 'OK'}
self.auth_logout_path = '/deconnexion'
# Path to sensors and mode
self.sensors_list = '/mysensors'
self.sensors_label = 'Sensor'
self.sensors_label_id = 'id'
# Path to list of alerts
self.alerts_path = '/listalert'
# Path to get and set modes
self.mode_get_path = '/mysensors'
self.mode_get_label = 'alarm_mode'
self.mode_set_path = '/alarmmode'
self.mode_set_field = 'action' # Name for GET field
self.mode_off = 'OFF' # Value for off
self.mode_custom = 'CUSTOM' # Value for custom
self.mode_on = 'ON' # Value for on
# Cameras
# mac=00:0e:8f:c9:59:44&flip=0&led_mode=0&alert_pan=1&rec24=0&da=1&dp=4&name=Salon
self.cameras_list = '/homescope/mycams'
self.camera_snapshot = '/homescope/snapshot'
self.camera_video = '/homescope/flv'
self.camera_get_config_path = '/homescope/camsettings'
self.camera_set_config_path = '/homescope/camsettings'
self.camera_set_config_mac = 'mac'
self.camera_set_config_flip = 'flip'
self.camera_set_config_leds = 'led_mode' # set to 0 to turn the leds on
self.camera_set_config_detectionsensibility = 'dp' # from 1 to 4,
def __str__ (self):
'''
@ -176,7 +225,7 @@ class HomeSFR ():
data = self.auth_extra_fields
data [self.auth_user_field] = self.username
data [self.auth_pass_field] = self.password
data = bytes (urlencode (data), 'UTF8')
data = str2bytes (urlencode (data))
if self.DEBUG:
print ('Cookies ' + str( len(self.cookies)))
print ('Sending data ' + str (data))
@ -241,7 +290,7 @@ class HomeSFR ():
r = self.base_url + self.mode_get_path
if self.DEBUG:
print ('Getting ' + r)
a = bytes2file (self.opener.open (r).readall ())
a = self.bytes2file (self.opener.open (r).read ())
b = ET.parse (a).getroot ()
c = b.get (self.mode_get_label)
if self.DEBUG:
@ -261,7 +310,7 @@ class HomeSFR ():
if (self.autologin and self.test_login () == False):
self.login ()
r = self.base_url + self.sensors_list
a = bytes2file (self.opener.open (r).readall ())
a = self.bytes2file (self.opener.open (r).read ())
b = ET.parse (a)
r = []
for i in b.findall (self.sensors_label):
@ -273,29 +322,11 @@ class HomeSFR ():
Returns a Sensor object for the sensor id or None if sensor is not found
The available ids can be got from the list_sensors method
'''
def build_tree (element):
r = {}
if self.DEBUG:
print ('Diving in the element ' + element.tag)
for i in element.getchildren ():
if i.getchildren () == []:
r.update ({i.tag: i.text})
else:
r.update ({i.tag: build_tree (i)})
return (r)
if (self.autologin and self.test_login () == False):
self.login ()
r = self.base_url + self.sensors_list
a = bytes2file (self.opener.open (r).readall ())
b = ET.parse (a)
r = None
for i in b.findall (self.sensors_label):
if self.DEBUG:
print ('Testing sensors ' + i.get (self.sensors_label_id))
if (i.get (self.sensors_label_id) == id):
r = build_tree (i)
break
return (Sensor (r))
r = Sensor (id, self.opener)
r.refresh ()
return (r)
def get_all_sensors (self):
'''
@ -305,32 +336,52 @@ class HomeSFR ():
for i in self.list_sensors ():
r.append (self.get_sensor (i))
return (tuple (r))
def get_camera (self, id):
'''
Get a Camera object from the sensor's id
'''
if (self.autologin and self.test_login () == False):
self.login ()
r = Camera (id, self.opener)
r.refresh ()
return (r)
class Sensor:
class Sensor (Common):
'''
Class used to read easily the sensors
'''
def __init__ (self, sensor_dict):
def __init__ (self, id, opener):
'''
Initialize the class with the dict producted by HomeSFR.get_sensors ()
'''
Common.__init__ (self)
self.sensor_dict = sensor_dict
# Field names
self.type_field = 'deviceType'
self.model_field = 'deviceModel'
self.version_field = 'deviceVersion'
self.name_field = 'name'
self.longname_field = 'long_name'
self.namegender_field = 'name_gender' # Only usefull for French for the moment
self.batterylevel_field = 'batteryLevel'
self.signal_field = 'signalLevel'
self.lasttrigger_field = 'lastTriggerTime'
self.lasttrigger_dateformat = '%Y-%m-%d %H:%M:%S'
self.status_field = 'status'
self.status_value_ok = 'OK'
# I don't have any other value for the moment
self.id = id
self.sensor_dict = None
self.opener = opener
def refresh (self):
'''
Gets or refresh the data for the sensor
'''
def build_tree (element):
r = {}
for i in element.getchildren ():
if i.getchildren () == []:
r.update ({i.tag: i.text})
else:
r.update ({i.tag: build_tree (i)})
return (r)
r = self.base_url + self.sensors_list
a = self.bytes2file (self.opener.open (r).read ())
a.seek (0)
b = ET.parse (a)
self.sensor_dict = None
for i in b.findall (self.sensors_label):
if (i.get (self.sensors_label_id) == self.id):
self.sensor_dict = build_tree (i)
break
def get_raw (self):
'''
@ -338,65 +389,71 @@ class Sensor:
'''
return (self.sensor_dict)
def get_mac (self):
'''
Returns the sensor's model, if any, None either
'''
return (self.sensor_dict [self.sensors_mac_field])
def get_type (self):
'''
Returns the sensor's type
'''
return (self.sensor_dict [self.type_field])
return (self.sensor_dict [self.sensors_type_field])
def get_model (self):
'''
Returns the sensor's model, if any, None either
'''
return (self.sensor_dict [self.model_field])
return (self.sensor_dict [self.sensors_model_field])
def get_version (self):
'''
Returns the sensor's version
'''
return (self.sensor_dict [self.version_field])
return (self.sensor_dict [self.sensors_version_field])
def get_name (self):
'''
Returns the sensor's name
'''
return (self.sensor_dict [self.name_field])
return (self.sensor_dict [self.sensors_name_field])
def get_longname (self):
'''
Returns the sensor's type name in system's language and the sensor's name
'''
return (self.sensor_dict [self.longname_field])
return (self.sensor_dict [self.sensors_longname_field])
def get_namegender (self):
'''
Return M for male and F for female.
Only usefull for languages with gender on nouns
'''
return (self.sensor_dict [self.namegender_field])
return (self.sensor_dict [self.sensors_namegender_field])
def get_batterylevel (self):
'''
Returns the sensor's battery level, out of 10
It seems that batteryless sensors return 255
'''
return (int (self.sensor_dict [self.batterylevel_field]))
return (int (self.sensor_dict [self.sensors_batterylevel_field]))
def get_signal (self):
'''
Returns the sensor's signal quality, out of 10
'''
return (int (self.sensor_dict [self.signal_field]))
return (int (self.sensor_dict [self.sensors_signal_field]))
def get_lasttrigger (self):
'''
Return the timestamp of the sensor's last triger
The sensors always trigger, even when the alarm's mode is off
'''
a = self.sensor_dict [self.lasttrigger_field]
a = self.sensor_dict [self.sensors_lasttrigger_field]
# Try because camera return the date '0000-00-00 00:00:00' that is ununderstandable
try:
b = datetime.strptime (a, self.lasttrigger_dateformat)
b = datetime.strptime (a, self.sensors_lasttrigger_dateformat)
except ValueError:
return (0)
r = int (b.timestamp ())
@ -406,4 +463,23 @@ class Sensor:
'''
Returns True is the sensor is OK, False either
'''
return (self.sensor_dict [self.status_field] == self.status_value_ok)
return (self.sensor_dict [self.sensors_status_field] == self.sensors_status_value_ok)
class Camera (Sensor):
'''
Class used to manipulate easily cameras
'''
def __init__ (self, sensor_dict, opener):
'''
Initialize the class with the dict producted by HomeSFR.get_camera ()
'''
Sensor.__init__ (self, sensor_dict, opener)
def get_snapshot (self):
'''
Get a snapshot from the camera
Return a PIL.Image object
'''
r = self.base_url + self.camera_snapshot + '?' + self.camera_snapshot_mac + '=' + self.get_mac ()
a = self.bytes2image (self.opener.open (r).read ())
return (a)