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
This commit is contained in:
parent
a511314e9a
commit
a340d1d228
|
@ -1,2 +1,3 @@
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled Python
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
*.pyc
|
10
README.md
10
README.md
|
@ -1,13 +1,13 @@
|
||||||
# What's this?
|
# What's this?
|
||||||
|
|
||||||
This is a pure Python 3 library to control your Home by SFR account.
|
This is a set of libraries to control your Home by SFR account.
|
||||||
The library is currently not complete and not totally tested, use it with caution.
|
They all work around the website.
|
||||||
|
|
||||||
# What's Home by SFR?
|
# What's Home by SFR?
|
||||||
|
|
||||||
Home by SFR is a security and automation service provided by the French Internet provider SFR (owned by Vodafone).
|
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.
|
The library was only tested for the French version because I don't know if it exists elsewhere
|
||||||
|
|
||||||
# Licence
|
# Licence
|
||||||
|
|
||||||
This library is under GNU GPL v3, the licence might be included in the project.
|
These libraries are under GNU GPL v3.
|
|
@ -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'
|
|
@ -1,21 +1,12 @@
|
||||||
#!/usr/bin/python3
|
|
||||||
'''
|
'''
|
||||||
Home by SFR wrapping class
|
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:
|
Warning:
|
||||||
This is a wrap aroud website, this could stop working without prior notice
|
This is a wrap aroud website, this could stop working without prior notice
|
||||||
|
|
||||||
Note about version naming:
|
|
||||||
The version are formed like <major>.<minor>-<date>
|
|
||||||
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:
|
# TODO:
|
||||||
## Return sensors in a class
|
|
||||||
## Manage cameras
|
## Manage cameras
|
||||||
### Get image
|
### Get image
|
||||||
### Get video
|
### Get video
|
||||||
|
@ -33,11 +24,21 @@ MODE_OFF = 0
|
||||||
MODE_CUSTOM = 1
|
MODE_CUSTOM = 1
|
||||||
MODE_ON = 2
|
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 urllib import request
|
||||||
from http.cookiejar import CookieJar
|
from http.cookiejar import CookieJar
|
||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode
|
||||||
from xml.etree import ElementTree as ET
|
from xml.etree import ElementTree as ET
|
||||||
from urllib.error import HTTPError
|
from urllib.error import HTTPError
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
def bytes2file (b):
|
def bytes2file (b):
|
||||||
'''
|
'''
|
||||||
|
@ -253,7 +254,7 @@ class HomeSFR ():
|
||||||
if (i.get (self.sensors_label_id) == id):
|
if (i.get (self.sensors_label_id) == id):
|
||||||
r = build_tree (i)
|
r = build_tree (i)
|
||||||
break
|
break
|
||||||
return (r)
|
return (Sensor (r))
|
||||||
|
|
||||||
def get_all_sensors (self):
|
def get_all_sensors (self):
|
||||||
'''
|
'''
|
||||||
|
@ -262,4 +263,102 @@ class HomeSFR ():
|
||||||
r = []
|
r = []
|
||||||
for i in self.list_sensors ():
|
for i in self.list_sensors ():
|
||||||
r.append (self.get_sensor (i))
|
r.append (self.get_sensor (i))
|
||||||
return (list (r))
|
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)
|
Loading…
Reference in New Issue