From a340d1d228a18ef7265d9d034df6ee3463a40854 Mon Sep 17 00:00:00 2001 From: Sasha MOREL Date: Sun, 22 May 2016 22:57:39 +0200 Subject: [PATCH] Gerenal: - Changed structure to allow other languages - Added Python2's file to ignore in .gitignore - Changed README with a language-free text Python2: - Added initial file with top Python3: - Added Sensor class for better reading of values - Changed return of HomeSFR.get_sensor () method --- .gitignore | 5 +- README.md | 10 +-- python2/homesfr.py | 30 +++++++ pyhomesfr.py => python3/homesfr.py | 123 ++++++++++++++++++++++++++--- 4 files changed, 149 insertions(+), 19 deletions(-) create mode 100644 python2/homesfr.py rename pyhomesfr.py => python3/homesfr.py (71%) diff --git a/.gitignore b/.gitignore index fc79902..e156e60 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ \ No newline at end of file +# Byte-compiled Python +__pycache__/ +*.pyc \ No newline at end of file diff --git a/README.md b/README.md index 4c6a5ab..dc908e7 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ # What's this? -This is a pure Python 3 library to control your Home by SFR account. -The library is currently not complete and not totally tested, use it with caution. +This is a set of libraries to control your Home by SFR account. +They all work around the website. # What's Home by SFR? -Home by SFR is a security and automation service provided by the French Internet provider SFR (owned by Vodafone). -The library was only tested for the French version. +Home by SFR is a security and automation service provided by the French Internet provider SFR. +The library was only tested for the French version because I don't know if it exists elsewhere # Licence -This library is under GNU GPL v3, the licence might be included in the project. \ No newline at end of file +These libraries are under GNU GPL v3. \ No newline at end of file diff --git a/python2/homesfr.py b/python2/homesfr.py new file mode 100644 index 0000000..033c18e --- /dev/null +++ b/python2/homesfr.py @@ -0,0 +1,30 @@ +# -*- coding: utf8 -*- +''' +Home by SFR wrapping class +Plain use of your Home by SFR device from a Python 3 library + +Warning: +This is a wrap aroud website, this could stop working without prior notice +''' + +# TODO: +## Write the library + +authors = ( + ) +name = 'homesfr for Python 2' +version = '0.8-20160521' + +# Settable modes +MODE_OFF = 0 +MODE_CUSTOM = 1 +MODE_ON = 2 + +# Sensors names +PRESENCE_DETECTOR = 'PIR_DETECTOR' +MAGNETIC_OPENNING_DETECTOR = 'MAGNETIC' +SMOKE_DETECTOR = 'SMOKE' +SIREN = 'SIREN' +REMOTE_CONTROLER = 'REMOTE' +KEYPAD_CONTROLER = 'KEYPAD' +PRESENCE_CAMERA_DETECTOR = 'PIR_CAMERA' \ No newline at end of file diff --git a/pyhomesfr.py b/python3/homesfr.py similarity index 71% rename from pyhomesfr.py rename to python3/homesfr.py index f7b3132..0f2a6b0 100644 --- a/pyhomesfr.py +++ b/python3/homesfr.py @@ -1,21 +1,12 @@ -#!/usr/bin/python3 ''' Home by SFR wrapping class -Plain use of your Home by SFR device from a Python library +Plain use of your Home by SFR device from a Python 3 library Warning: This is a wrap aroud website, this could stop working without prior notice - -Note about version naming: -The version are formed like .- -Since the major 1, the method's names, paramters and their default value will never change inside the same major. -So, if a program using a major does not work anymore with another version from the same major, it's a bug from the library. - -The major 0 is a testing one ''' # TODO: -## Return sensors in a class ## Manage cameras ### Get image ### Get video @@ -33,11 +24,21 @@ MODE_OFF = 0 MODE_CUSTOM = 1 MODE_ON = 2 +# Sensors names +PRESENCE_DETECTOR = 'PIR_DETECTOR' +MAGNETIC_OPENNING_DETECTOR = 'MAGNETIC' +SMOKE_DETECTOR = 'SMOKE' +SIREN = 'SIREN' +REMOTE_CONTROLER = 'REMOTE' +KEYPAD_CONTROLER = 'KEYPAD' +PRESENCE_CAMERA_DETECTOR = 'PIR_CAMERA' + from urllib import request from http.cookiejar import CookieJar from urllib.parse import urlencode from xml.etree import ElementTree as ET from urllib.error import HTTPError +from datetime import datetime, timezone def bytes2file (b): ''' @@ -253,7 +254,7 @@ class HomeSFR (): if (i.get (self.sensors_label_id) == id): r = build_tree (i) break - return (r) + return (Sensor (r)) def get_all_sensors (self): ''' @@ -262,4 +263,102 @@ class HomeSFR (): r = [] for i in self.list_sensors (): r.append (self.get_sensor (i)) - return (list (r)) \ No newline at end of file + return (list (r)) + +class Sensor: + ''' + Class used to read easily the sensors + ''' + def __init__ (self, sensor_dict): + ''' + Initialize the class with the dict producted by HomeSFR.get_sensors () + ''' + + 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 + + def get_raw (self): + ''' + Returns the raw dict, as presented in the original XML file + ''' + return (self.sensor_dict) + + def get_type (self): + ''' + Returns the sensor's type + ''' + return (self.sensor_dict [self.type_field]) + + def get_model (self): + ''' + Returns the sensor's model, if any, None either + ''' + return (self.sensor_dict [self.model_field]) + + def get_version (self): + ''' + Returns the sensor's version + ''' + return (self.sensor_dict [self.version_field]) + + def get_name (self): + ''' + Returns the sensor's name + ''' + return (self.sensor_dict [self.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]) + + 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]) + + 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])) + + def get_signal (self): + ''' + Returns the sensor's signal quality, out of 10 + ''' + return (int (self.sensor_dict [self.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] + b = datetime.strptime (a, self.lasttrigger_dateformat) + 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) \ No newline at end of file