Ik zie in ieder geval dat je tegen dezelfde problemen aanloopt als dat ik doe, dus dat is.. goed?

Dat je telefoon in slaapstand raakt en daarom niet pingbaar is. Met dit in het achterhoofd heb ik de volgende keuze gemaakt, wanneer de telefoon pingbaar is dan ben ik thuis. Als de waarde van isAtHome = false is, dus systeem behandeld mij dat ik niet thuis ben en mij thuis ziet komen dan veranderd het huidige actieve profiel. Daarna pingt het systeem nog wel, maar heeft niet echt waarde. Als de telefoon niet pingbaar is betekent het inderdaad dat ik niet thuis ben, maar met het slaapstand verhaal kan dit best vervelend worden. Met dat gezegd wil ik wat van mijn opzet tonen, want de manier hoe je het op het moment hebt geprogrammeerd is vaag. Volgens mij gaf je al aan dat je een beginner bent, dus het is niet erg, maar kijken of we het naar een hoger niveau kunnen krijgen.
In Python maak ik gebruik van Events vergelijkbaar met die in c# en andere talen. Bijvoorbeeld als een telefoon wordt gepingt en de status van IsOnline veranderd van false naar true (je bent thuis gekomen), dan wordt er een bepaalde functie aangeroepen (of meerdere ligt er aan hoeveel functies je aan de event hangt. Om de events in Python te implementeren heb ik deze website gevolgd:
http://code.activestate.c...c-style-events-in-python/
Als eerste de class die ik gebruik per telefoon:
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| class Device(object):
def __init__(self, address):
self.IpAddress = address;
self.LastSeenOnline = None;
self.__IsOnline = False;
# define events
self.events = DeviceEvents();
def __repr__(self):
return "Device: ({0});".format(self.IpAddress);
# properties
@property
def IsOnline(self):
return self.__IsOnline;
@IsOnline.setter
def IsOnline(self, value):
if (self.__IsOnline == value):
return;
self.__IsOnline = value;
# trigger event
self.events.StateChanged(self);
def Update(self):
isOnline = Net.Ping.IsOnline(self.IpAddress);
if (isOnline == True):
self.LastSeenOnline = datetime.now();
self.IsOnline = isOnline;
class DeviceEvents(Event.Events):
__events__ = ('StateChanged'); |
Python:
1
2
3
4
5
6
7
8
9
10
11
12
| phone = DeviceDevice("10.0.0.10");
# eerste keer update om de eerste waarde te zetten.
phone.Update();
# nu kun je de StateChanged event aan een functie koppelen waarin je kan bepalen wat er gebeurd als de status veranderd.
# eerst de functie
def deviceStateChangedEvent(self, device):
# zal de IsOnline status van de telefoon weergeven. Nu kun je tegen systeem zeggen dat het AtHomeProfiel moet worden geladen.
print("Device status is veranderd naar: {0}".format(device.IsOnline));
# koppel de event aan de functie hierboven.
phone.events.StateChanged += deviceStateChangedEvent; |
Wat je nu kunt doen is RepeatedTimers (Bv:
http://stackoverflow.com/a/13151299/3165164) gebruiken om iedere minuut je iPhone te pingen. Wanneer de status veranderd dan kun je actie ondernemen. Je ziet zelf ook al dat de status vaak veranderd, dus aan te raden is om alleen te kijken naar wanneer de status van False naar True veranderd en jouw AtHome status False is. Dit houdt dus in dat je thuis bent gekomen.
Hopelijk zet ik het nog een beetje duidelijk op, want vanaf dit punt gaat het complex worden. Heb al moeite om stukje code uit mijn project te krijgen om het behapbaar te houden, maar we gaan er voor

Als eerste de lampprofielen. Als eerste de lampclass, genaamd ElectricalSocket want het maakt niet uit of er nou persee een lamp achterzit, kan ook een koffieautomaat zijn.
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| class ElectricalSocket(object):
#constructor
def __init__(self, name, status):
# init vars
self.Name = name;
self.Status = status;
def TurnOn(self):
# hier kan je code komen om de schakelaar aan te zetten.
pass;
def TurnOff(self):
# hier kan je code komen om de schakelaar uit te zetten.
pass;
# je maken meerdere instanties aanmaken, één per lamp en deze opslaan in een lijst.
electricalSocketList = [];
electricalSocketList.append(ElectricalSocket("boekenkast", False));
electricalSocketList.append(ElectricalSocket("televisie", False)); |
Wat je nu in je systeem kunt doen is het volgende:
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| isAtHome = False;
phone = DeviceDevice("10.0.0.10");
# needed functions
def deviceStateChangedEvent(device):
if (isAtHome == False and device.IsOnline == True):
# je bent thuis gekomen.
isAtHome = True;
# init
phone.Update();
if (phone.IsOnline == True):
isAtHome = True;
# koppel de event handler
phone.events.StateChanged += deviceStateChangedEvent;
# nu de main loop starten, wat deze doet is om de minuut je telefoon pingen
def phoneUpdater():
phone.Update();
tmrPhone = RepeatedTimer(60, phoneUpdater);
# eigenlijk zou het programma nu afsluiten, maar we moeten hem in leven houden.
while(True):
try:
# ik merk dat zonder sleep het programma veel cpu kracht vraagt, daarom 5sec slapen
time.sleep(5);
except:
# stop de phone timer
tmrPhone.Stop(); |
Je hebt nu een programma die blijft draaien en om de minuut kijkt of hij je telefoon ziet en daar jou atHome status op veranderd. Nu hebben we daar opzich nog weinig aan, maar je systeem heeft in ieder geval een idee van je aanwezigheid. Wanneer je het huis uitgaat zat dit nog steeds een probleem vormen. Je kunt ergens een check inbouwen dat wanneer je telefoon offline is en je atHome status zou veranderen naar False je op tijd gaat controlleren. Bijvoorbeeld wanneer dit 15minuten geleden is gebeurd en de telefoon is in de tussentijd nog niet online gezien dan kun je aannemen dat je weg bent. Echter, mijn Note2 gaat soms een half uur in slaapstand...
Dan nu de lampen beheren, als eerste het ophalen van de zonsondergang tijd aangezien die per dag veranderd.
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| class Yahoo:
def __init__(self, loc):
#
self.Astronomy = None;
self.Location = loc;
self.UpdateTime = None;
def Update(self):
requestUrl = "http://weather.yahooapis.com/forecastrss?w={0}&u=c".format(self.Location);
req = urllib2.Request(requestUrl);
try:
response = urllib2.urlopen(req);
except:
raise Exception("Failed to connect with the Yahoo weather service.");
doc = xml.dom.minidom.parse(response);
# Part: "Astronomy"
nodeList = doc.getElementsByTagName("yweather:astronomy");
# create understandable strings
sunRiseString = "{0} {1}".format(
datetime.now().strftime("%Y-%m-%d"),
nodeList[0].getAttribute("sunrise")
);
sunSetString = "{0} {1}".format(
datetime.now().strftime("%Y-%m-%d"),
nodeList[0].getAttribute("sunset")
);
# parse strings
sunRise = datetime.strptime(sunRiseString, "%Y-%m-%d %I:%M %p");
sunSet = datetime.strptime(sunSetString, "%Y-%m-%d %I:%M %p");
# fill object
self.Astronomy = Astronomy(sunRise, sunSet);
self.UpdateTime = datetime.now();
class Astronomy:
def __init__(self, sunrise, sunset):
self.SunRise = sunrise;
self.SunSet = sunset; |
Deze code is nog een hel, maar het werkt en daar gaat het voor mij nu om. Je kunt het alsvolgt implementeren:
Python:
1
2
3
| weather = Yahoo("729991");
# zal de datetime van de zonsondergang aangeven, nodig om iedere dag te updaten
print weather.Astronomy.SunSet; |
Om achter je ID te komen kun je naar:
http://weather.yahoo.com/ gaan en daar je stad in vullen. In de URL kun je het ID nummer plukken. Ik update deze informatie iedere dag om 12:00, zodat ik voor 's avonds weer de goede tijden heb.
Als we nu zaken gaan combineren kunnen we de volgende controle slag maken:
Python:
1
2
3
4
5
6
7
8
9
| def homeController():
if (isAtHome == True and datetime.now() > weather.Astronomy.SunSet):
for es in electricalSocketList:
if ( es.Status == False):
# opgesomd, persoon is thuis, tijd is na zonsondergang en de lamp is uit.
es.TurnOn();
# zet de timer op, zodat iedere minuut je huis status wordt gechecked.
rtController = RepeatedTimer(60, homeController); |
Wat je nu hebt is een systeem die kijkt of je thuis komt, wanneer dat geval is kan de homeController de controle over je lampen overnemen. Enige problemen waar je nog mee zit is. Het systeem ziet niet dat je van huis weggaat en wanneer je draadloos je lampen uitzet. Je systeem heeft geen terugkoppel signaal, daarom gebruik ik een Arduino om dat daar te regelen. Dan maar beetje omslachtige opzet, maar wel één die precies bijhoudt hoe het hele systeem in elkaar zit. Tevens, bij draadloos moet je er ook maar vanuit gaan dat het signaal is overgekomen, het systeem zit de storing niet.
Hier laat ik het voor nu even bij

of euhm just-my-50-cents

Zal aardig verhaal zijn om te begrijpen vooral met de leercurve, maar succes er mee en als je vragen hebt dan hoor ik dat graag.