[Python] Background script voor domotica projectje

Pagina: 1
Acties:
  • 3.984 views

Acties:
  • 0 Henk 'm!

  • Campo di Casa
  • Registratie: Januari 2010
  • Laatst online: 18:26
Ik ben me een beetje aan het verdiepen in het scripten en dan voornamelijk met Python. Een taal die niet al te ingewikkeld is voor een beginner en daardoor makkelijker te leren. Nou kan ik wel tig verschillende tutorials doorlopen maar ik vind het leuker om na wat basis kennis gewoon verder te leren met behulp van een eigen projectje. Dus tegen problemen aan lopen en Google gebruiken voor oplossingen en die kennis meteen gebruiken.

Ik ben wat aan het pielen met een mijn Raspberry en een RF transmitter die ik via de Weblog van WeeJeWel aan de praat heb gekregen. Kan dus nu via mijn Raspberry de lampen schakelen. En via verschillende bestaande scripts en projecten kan je dit veel gelikter regelen. Denk aan Domoticz of Pilight.

Maar ik wil dus zelf een klein simpel scriptje schrijven...

Het is mij gelukt om via ping te kijken of mijn smartphone op het WIFI is aangemeld en dan de lampen aan te schakelen. Het is ook geen probleem om de lampen op een bepaald tijdstip te schakelen. Ook de combinatie van beide is gelukt. Alleen hoe zorg je er voor dat het scriptje op de achtergrond door blijft lopen?

uiteindelijke bedoeling is:
  • kijk via ping of telefoon aanwezig is.
  • kijk naar huidige tijdstip en of dit voor zonopkomst of na zonondergang is.
  • kijk of slaapstand geactiveerd is (weet hier nog geen oplossing voor)
Ik begrijp inmiddels dat ik moet werken via 'class' en 'def'. Maar hoe is in grote lijnen zo'n script opgebouwd?

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Je laatste zin verwart een beetje. Dat gaat meer over de taal en de syntax daarvan dan over je feitelijke probleem. Als je wilt leren programmeren in Python zul je wel enig idee moeten hebben over wat 'class' en 'def' betekenen.

Los daarvan, als je probleem is dat je een script eindeloos wilt laten draaien (daemonizen noem je dat) dan heeft dat op zich niets met Python te maken en is dat meer een systeemarchitectuur-dingetje wat je op allerlei manieren op kunt lossen.

Ik zou zeggen dat je met een cronjob ook al een heel eind bent. Maar als het echt realtime moet, moet je iets bedenken waarmee het proces dat de dingen "activeert" wakker wordt, dus moet je een of andere trigger hebben waar je met het script naar luistert.

Al met al is het wel handig als je iets concreter maakt wat je nu al hebt, door bijvoorbeeld wat source code te posten.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • Ramon
  • Registratie: Juli 2000
  • Laatst online: 17:23
Om via de commandline een command uit te voeren op de achtergrond kan je er & achter zetten. Dus iets in de zin van:

Bash:
1
python mijndomoticascript.py &


In je python-script moet je dan natuurlijk een loop maken die om de zoveel tijd controleert of aan de door jouw opgegeven condities voldaan wordt om dan de juiste methods aan te roepen.

Check mijn V&A ads: https://tweakers.net/aanbod/user/9258/


Acties:
  • 0 Henk 'm!

  • Campo di Casa
  • Registratie: Januari 2010
  • Laatst online: 18:26
drm schreef op zondag 02 maart 2014 @ 22:58:
Je laatste zin verwart een beetje. Dat gaat meer over de taal en de syntax daarvan dan over je feitelijke probleem. Als je wilt leren programmeren in Python zul je wel enig idee moeten hebben over wat 'class' en 'def' betekenen.

Los daarvan, als je probleem is dat je een script eindeloos wilt laten draaien (daemonizen noem je dat) dan heeft dat op zich niets met Python te maken en is dat meer een systeemarchitectuur-dingetje wat je op allerlei manieren op kunt lossen.

Ik zou zeggen dat je met een cronjob ook al een heel eind bent. Maar als het echt realtime moet, moet je iets bedenken waarmee het proces dat de dingen "activeert" wakker wordt, dus moet je een of andere trigger hebben waar je met het script naar luistert.

Al met al is het wel handig als je iets concreter maakt wat je nu al hebt, door bijvoorbeeld wat source code te posten.
Het verwart mezelf ook een beetje ;) Deels ook omdat ik dus niet weet hoe je een scipt in de achtergrond laat draaien. Los van het feit of dit nu Python, C# etc is. Maar ik begrijp dat ik nu ff moet Googlen naar daemonizen en cronjob.

Onderstaande is het scriptje waar ik mee bezig ben. Op dit moment ben ik nog aan het stoeien met class en def, en doet het script nog niks (wordt nog niks aangeroepen). Ik heb het eerst getest zonder het in een class te gooien en toen werkte het. Bepaalde gegevens worden geprint zodat ik ter controle kan zien wat er gebeurt, of juist niet gebeurt. Dat wil ik straks anders gaan doen. Misschien exporteren naar een log bestand. Er zal ongetwijfeld beginners fouten worden gemaakt, maar ben dan ook een beginner :p

code:
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
44
45
46
47
48
49
#!/usr/bin/env python

# import 
import subprocess
import time
import os

# Algemene waardes
lampstatus = 0


# Check of Device binnen WiFi bereik is.
class pinger:
    def ping(self):
        pingcount = 0
        hostname = "192.168.1.110"
        while pingcount == 0:
            output = subprocess.Popen(["ping", "-c 1", hostname],stdout = subprocess.PIPE).communicate()[0]
            if ('Destination Host Unreachable' in output):
                print output
                pingcount = 0
            else:
                print("Device binnen WiFi bereik gevonden.")
                print output
                pingcount = 1
         
# check datum en tijdstip
class timer:
    def timer(self):
        # Kijk hoelaat het is (local time), en zoek datum op (localdate)
        localtime = time.strftime("%H%M")
        localdate = time.strftime("%d%m%y")

        print ("Localtime= "),localtime
        print ("Localdate= "),localdate

        # deze waarde aanpassen van vast tijdstip naar zon ondergang-opkomst
        scheduledtime = "1715"

        print ("scheduledtime= "),scheduledtime

        while localtime <> scheduledtime:
            localtime = time.strftime("%H%M")
            if localtime == scheduledtime:
                print ("time is the same")
                os.system("./kaku 20 C on")
            else:
                print ("Time is NOT the same")
                time.sleep(10)

In het eerste deel roep ik ping aan via;
code:
1
output = subprocess.Popen(["ping", "-c 1", hostname],stdout = subprocess.PIPE).communicate()[0]

In het tweede deel roep ik de script kaku aan via;
code:
1
os.system("./kaku 20 C on")

Dat ik 2 manieren in deze script gebruik kwam doordat ik eerst wat had gelezen over os.system en pas een dag later info tegen kwam over subprocess.Popen wat 'beter' zou zijn. Moet dat dus nog aanpassen...
Ramon schreef op zondag 02 maart 2014 @ 23:07:
Om via de commandline een command uit te voeren op de achtergrond kan je er & achter zetten. Dus iets in de zin van:

Bash:
1
python mijndomoticascript.py &


In je python-script moet je dan natuurlijk een loop maken die om de zoveel tijd controleert of aan de door jouw opgegeven condities voldaan wordt om dan de juiste methods aan te roepen.
Oke, dat ga ik ook eens uitproberen.

Acties:
  • 0 Henk 'm!

  • Xudonax
  • Registratie: November 2010
  • Laatst online: 02-06 18:07
Mag ik je PEP8 aanraden voor de stijl van je code :) Simpel samengevat, klasses beginnen met een hoofdletter ;)

Verder, het is niet nodig om iedere functie in één klasse te gooien. Wat je bijvoorbeeld kunt doen is zoiets maken:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# alle imports

class LightControl(object):
    def __init__(self, *args, **kwargs):
        # initialiseer alle dingen die je voor de klasse nodig hebt

    def ping(self):
        # Jouw ping() functie

    def timer(self):
        # Jouw timer() functie

if __name__ == "__main__":
    lightcontrol = LightControl()


Op deze manier heb je netjes één klasse die alles van je ding afhandeld. Het enige is dat je je waarschijnlijk even moet inlezen op new-style classes. Heel simpel gezegd is het zichtbare verschil dat ze een kind zijn van de object klasse, en dus een aantal leuke extra's meekrijgen. Er zijn tegenwoordig eigenlijk nog maar héél weinig old-style klassen (zoals jij ze nu hebt gemaakt) in Python.

Heel veel succes!

EDIT: Oh, en misschien dat je van ping de returnwaarde kunt pakken. Op bijvoorbeeld Ubuntu is de tekst van vrijwel alle console programma's vertaald |:(

[ Voor 6% gewijzigd door Xudonax op 03-03-2014 07:44 ]


Acties:
  • 0 Henk 'm!

  • 4Real
  • Registratie: Juni 2001
  • Laatst online: 14-09-2024
TS wil precies wat ik nu al bijna een jaar thuis heb draaien :P

Mijn opstelling is alsvolgt:
Arduino heeft een stel knoppen en beheert het lampen. Tevens zit er een LDR op om licht intensiteit te meten. De lampen kunnen met de knoppen worden geregeld in het geval dat ik geen telefoon bij de hand heb. Tevens zijn alle knoppen op één plek en voor het uit doen is dit te makkelijk om iets anders te regelen.

De Raspberry Pi beheert eigenlijk alles, hij leest iedere seconde de Arduino uit om alle waardes op te halen en te checken of wijzigingen hebben plaats gevonden. Bijvoorbeeld ik druk een lamp uit d.m.v. een knop. Tevens heeft hij de LDR waarde nodig om te bepalen of een lamp aan moet of niet.

Dan het systeem. Het systeem houdt bij of ik thuis ben ja of nee. Als ik niet thuis ben dan heb ik een profiel draaien AllOff (spreekt voorzich). Hij pingt mijn telefoon iedere 3 seconde om te kijken of ik thuis ben. Als hij mijn telefoon heeft gevonden kijkt hij of ik thuis ben ja of nee. In het geval van nee dan ben ik thuis gekomen, dus gaat het actieve profiel naar AtHome. Dit profiel heeft drie lamp profielen die dynamisch draaien. Dynamisch houdt in op waarde van zonsondergang en licht intensiteit.

Wanneer de zon ondergaat of een uur eerder en de licht intensiteit onder een bepaald niveau is (per lamp in stelbaar) dan gaat die lamp aan en gaat niet meer uit tot de volgende dag (of anders bepaald). Dit zorgt er voor dat de overgang naar zonsondergang en licht in mijn huis soepel verloopt zonder dat je echt in donker zit. Als ik naar bed ga dan druk ik de knoppen in op mijn Arduino. De Pi ziet dan wijzigingen van buiten af en creeert een custom profiel en bewaard de huidige status, alle lampen uit. Om 12:00 's middags wordt het actieve profiel herberekent aan de hand van of ik thuis ben ja of nee. Dus als ik dan in de namiddag weer thuis kom zal het profiel AtHome worden, kom ik later in de avond thuis dan blijven de lampen uit.

Als laatst heb ik nog aangegeven dat ik ook uit huis kan gaan. Op het moment is dit nog een knop op mijn Arduino aangezien de Pi soms de telefoon niet pingt en dan aanneemt dat ik niet thuis ben. Wanneer ik aangeef dat ik van huis ga heb ik nog twee minuten licht en dan gaat het actieve profiel naar AllOff, de lampen zijn nu allemaal uit.

Zo wat food-for-thought :P mocht je vragen hebben dan hoor ik het graag. Code kan ik ook wel aanleveren, maar dat is speciaal gemaakt voor mijn situatie, dus dat zal wel lastig worden. In ieder geval wil ik wel mee denken, want ik zit zelf ook nog met een aantal punten waar ik mee vast zit. Bijvoorbeeld hoe weet het systeem dat ik slaap.

Voor pingen van een apparaat gebruik ik het volgende:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Ping:
    @staticmethod
    def IsOnline(ipAddress):
        isOnline = False;

        if (platform.system() == "Windows"):
            handler = subprocess.Popen("ping -n 1 " + ipAddress, stdout=subprocess.PIPE);
            result = re.search('Average = (.*)ms', handler.stdout.read());
            isOnline = ( result != None );
            
        else:
            result = subprocess.call(
                "ping -c 1 " + ipAddress, 
                shell=True, 
                stdout=open('/dev/null', 'w'), 
                stderr=subprocess.STDOUT
            );
            isOnline = (result == 0);

        return isOnline;


Static class method die zowel onder Windows als Linux draait (ik bouw eerst alles in VS2012 en kopieer de code als ik tevreden ben). Input is een IP address (string), bv "127.0.0.1" en output is een boolean.

[ Voor 15% gewijzigd door 4Real op 03-03-2014 12:07 ]


Acties:
  • 0 Henk 'm!

  • Campo di Casa
  • Registratie: Januari 2010
  • Laatst online: 18:26
Xudonax schreef op maandag 03 maart 2014 @ 07:42:
Mag ik je PEP8 aanraden voor de stijl van je code :) Simpel samengevat, klasses beginnen met een hoofdletter ;)

Verder, het is niet nodig om iedere functie in één klasse te gooien. Wat je bijvoorbeeld kunt doen is zoiets maken:

Op deze manier heb je netjes één klasse die alles van je ding afhandeld. Het enige is dat je je waarschijnlijk even moet inlezen op new-style classes. Heel simpel gezegd is het zichtbare verschil dat ze een kind zijn van de object klasse, en dus een aantal leuke extra's meekrijgen. Er zijn tegenwoordig eigenlijk nog maar héél weinig old-style klassen (zoals jij ze nu hebt gemaakt) in Python.

Heel veel succes!

EDIT: Oh, en misschien dat je van ping de returnwaarde kunt pakken. Op bijvoorbeeld Ubuntu is de tekst van vrijwel alle console programma's vertaald |:(
leesvoer :*) Dat wordt dus beide artikelen doorlezen en er wat van leren.
De reden dat ik old-style klassen gebruikte was omdat ik dit eens had gezien in een script. En eigenlijk dat als voorbeeld heb gebruikt. Niet altijd even handig dus...
4Real schreef op maandag 03 maart 2014 @ 12:02:
TS wil precies wat ik nu al bijna een jaar thuis heb draaien :P

Zo wat food-for-thought :P mocht je vragen hebben dan hoor ik het graag. Code kan ik ook wel aanleveren, maar dat is speciaal gemaakt voor mijn situatie, dus dat zal wel lastig worden. In ieder geval wil ik wel mee denken, want ik zit zelf ook nog met een aantal punten waar ik mee vast zit. Bijvoorbeeld hoe weet het systeem dat ik slaap.
Dan ga ik zeker zo af en toe wat vragen ;) Maar waarom heb je een Raspberry en Arduino gebruikt? Had je hier een speciale reden voor?

Ik zag wel op Adafruit een LCD met keypad om eventueel te zien in welke status de script zit. En eventueel handmatig wat settings te veranderen.

Maar eerst zorgen dat ik de boel aan de praat krijg. Want schijnbaar heb jij het al draaien precies zoals ik het voor ogen heb. En wat dat slapen betreft; daar liep ik ook al over na te denken, maar kan nog niks bedenken. Het simpelste is om fysiek op een button te drukken en zo de slaapmodus te activeren. Maar eigenlijk zou het mooier zijn als er een aantal waarde zijn die, wanneer ze allemaal true zijn, de slaapmodus wordt geactiveerd.

Acties:
  • 0 Henk 'm!

  • 4Real
  • Registratie: Juni 2001
  • Laatst online: 14-09-2024
housekamp schreef op maandag 03 maart 2014 @ 19:04:

Dan ga ik zeker zo af en toe wat vragen ;) Maar waarom heb je een Raspberry en Arduino gebruikt? Had je hier een speciale reden voor?
Mijn avontuur met elektronica begon met een Arduino en een klikaanuitsysteem. Met een 433mhz zender wilde ik die dingen schakelen, maar kwam er al snel achter dat ze niet echt betrouwbaar zijn en ik geen feedback signaal krijg of ze daadwerkelijk aan of uit zijn. Toen kwam mijn vader aan met Solid State Relays. Hiermee kan ik mijn 5V en 220V circuits uit elkaar houden en als nog lampen schakelen en dit was een groot succes. Met de Arduino heb ik echt heel veel geprobeerd om te kijken of ik het zo kan krijgen als ik het wil, maar kom er achter dat het apparaatje niet de kracht heeft die ik zoek. Dus toen heb ik een Pi aangeschaft, ook met de GPIO poorten gespeeld, maar dit was niet echt wat ik precies zocht, want hij heeft echt significant minder poorten dan een Arduino Uno en zeker een Mega, maar de mogelijkheden met het apparaat zijn eindeloos. Ik ben aardig tevreden dat een Arduino de echte status van de lampen bijhoudt en dat de Pi hierop gaat handelen.
Ik zag wel op Adafruit een LCD met keypad om eventueel te zien in welke status de script zit. En eventueel handmatig wat settings te veranderen.
Uiteindelijk wil ik ook wel een keer een touchscreen er aanhangen, zodat ik daar meer informatie op kan uitlezen, maar op het moment draait het programma een Socket server die ik uitlees met PHP dus alle info kan tonen op mijn mobiel en ook commando's naar toe kan sturen.
Maar eerst zorgen dat ik de boel aan de praat krijg. Want schijnbaar heb jij het al draaien precies zoals ik het voor ogen heb. En wat dat slapen betreft; daar liep ik ook al over na te denken, maar kan nog niks bedenken. Het simpelste is om fysiek op een button te drukken en zo de slaapmodus te activeren. Maar eigenlijk zou het mooier zijn als er een aantal waarde zijn die, wanneer ze allemaal true zijn, de slaapmodus wordt geactiveerd.
Het mooiste is als je systeem kan zien waar je je in bevindt coördinaten thuis dus, want dan hoef je volgens mij nooit meer een knop in te drukken. Maar ik kan zo niets vinden wat mij daar mee kan helpen. Dus tot die tijd blijf ik gebruik maken van mijn thuis-knop die ik alleen nog maar in hoef te drukken wanneer ik wegga, want het pingen van mijn mobiel werkt goed zat. Laatst kwam ik aan fietsen en zag de lampen in mijn huis aan gaan, dat was wel erg tof.

Acties:
  • 0 Henk 'm!

  • Campo di Casa
  • Registratie: Januari 2010
  • Laatst online: 18:26
Dat is zeker relaxt :)
Ben nu bezig om gegevens te lezen uit een ini bestand. Zodat ik hier diverse instellingen kan aanpassen etc zonder de hele script te hoeven doorzoeken.

Als ik dat werkende heb is het de beurt aan het exporteren van loggegevens naar een log bestand. Had al wat info gevonden maar moet dit nog uitzoeken.

Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

housekamp schreef op zondag 02 maart 2014 @ 19:16:
Ik begrijp inmiddels dat ik moet werken via 'class' en 'def'. Maar hoe is in grote lijnen zo'n script opgebouwd?
Je eerste code ziet er helemaal nog zo erg niet uit voor een beginner.

De belangrijkste les qua codestructuur is die van het "single-responsibility" principe.
Elke method/class/... heeft 1 en juist 1 functie/doel.
Daarenboven probeer je elke methode zo klein mogelijk te houden.

Die 2 doelstellingen hebben een hoop gevolgen:
- herbruikbare stukjes code splits je af in aparte functies met een duidelijke naam
- ingewikkeldere functies zijn meestal niet meer als composities van andere functie met wat logica
- als je op de vraag "wat doet deze functie/class" een "en" tegenkomt dan moet je splitsen

Eigenlijk komt het neer op het eeuwenoude principe "divide et impera". Splits je code op in kleine begrijpbare stukjes code (divide) en gebruik die bouwstenen om je programma logisch en structureel op te bouwen (impera).

Door al stukken functionaliteit in "pinger" en "timer" op te splitsen ben je al op de goede weg.
Er zijn nog enkele zaken die je kan doen om je code herbruikbaarder te maken (dit blijft heus niet je enige project, toch?):
methode ping:
- wat gebeurt er als je je netwerk gaat hernummeren? Of als je een ander device wil pingen?
- remember dat elk proces ook een return code heeft (zie sys.exit(exitcode)) - wat is de return code van het 'ping' proces? Wat is de return code van os.system() ? Extra les: output parsen van iets is zelden een goed idee en moet altijd de allerlaatste keuze zijn. Wat als de auteur de output verandert tijdens een system update? Wat als jij een typo hebt? Wat als de output localized wordt (plots in het nederlands, bvb)?

methode timer:
- wat doet deze functie? Spot je de 'en' in het antwoord?
- timing is een veel voorkomend probleem. Er moet dus wel wat beschikbaar zijn om je te helpen...
Zie bijvoorbeeld: http://docs.python.org/2/library/sched.html, http://docs.python.org/2....eading.html#timer-objects, https://www.google.be/#q=python+repeating+timers
Maar heb je dit echt wel nodig?
- time.localtime() retourneert een http://docs.python.org/2/library/time.html#time.struct_time. Is de string conversie echt nodig (behalve om te printen)

Wat doet je code?
"pollt elke 10s en als ... dan ..."
Welk stuk van de code zal dus welk ander stuk moeten aanroepen?
Aangezien je begint met "pollt elke 10s", heb je dan een timer class nodig of kun je gewoon met iets als het volgende overweg:
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
start = datetime.time(17, 15)
stop = datetime.time(7, 30)
host = "..."

def main(args):
  ping = pinger()
  while true:
    now = datetime.now().time()
    athome = ping.ping(host)
    if now < start && athome:
      # ...
    elif now > start:
      # ...
    sleep(10)

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • Campo di Casa
  • Registratie: Januari 2010
  • Laatst online: 18:26
lol, is het een schande als ik zeg dat het ff zwart voor de ogen wordt na het lezen van je reply? ;)
Veel info!
De belangrijkste les qua codestructuur is die van het "single-responsibility" principe.
Elke method/class/... heeft 1 en juist 1 functie/doel.
Daarenboven probeer je elke methode zo klein mogelijk te houden.

Die 2 doelstellingen hebben een hoop gevolgen:
- herbruikbare stukjes code splits je af in aparte functies met een duidelijke naam
- ingewikkeldere functies zijn meestal niet meer als composities van andere functie met wat logica
- als je op de vraag "wat doet deze functie/class" een "en" tegenkomt dan moet je splitsen

Eigenlijk komt het neer op het eeuwenoude principe "divide et impera". Splits je code op in kleine begrijpbare stukjes code (divide) en gebruik die bouwstenen om je programma logisch en structureel op te bouwen (impera).
Daar ben ik inmiddels achter gekomen. Ik begin nu het principe van class en def te snappen en in te zien dat je hierdoor niet alleen meer inzicht krijgt in je eigen code, maar ook een hoop werk uit handen neemt door telkens opnieuw een bepaalde stuk code te moeten schrijven. En zoals je aangeeft zal het niet blijven bij enkel dit projectje. Door de code zo te schrijven dat het modules worden kan ik dit vaker gebruiken. Maar makkelijk is het nog niet.
methode ping:
- wat gebeurt er als je je netwerk gaat hernummeren? Of als je een ander device wil pingen?
- remember dat elk proces ook een return code heeft (zie sys.exit(exitcode)) - wat is de return code van het 'ping' proces? Wat is de return code van os.system() ? Extra les: output parsen van iets is zelden een goed idee en moet altijd de allerlaatste keuze zijn. Wat als de auteur de output verandert tijdens een system update? Wat als jij een typo hebt? Wat als de output localized wordt (plots in het nederlands, bvb)?
Dat was ook zeker een probleem. Hiervoor mag ik dan ook 4Real bedanken en heb 'schaamteloos' zijn stukje code hiervoor gebruikt. Mijn stukje code bleek onbetrouwbaar en gaf vaak verkeerde resultaten. Precies om de reden zoals hierboven en door andere zijn aangegeven.

Het stukje over mijn timer methode zal ik nog moeten doorlezen. Ik merk wel vaker dat ik een beetje omslachtig bezig ben. Gebruik van teveel code om iets te bereiken wat veel beknopter beschreven kan worden.

Ik ben nu ook op een punt gekomen dat mijn code onoverzichtelijk wordt. Ik ga nu ook mijn code eens goed doorlezen en opnieuw schrijven met de stukken die echt nodig zijn. Dit komt ook voor een deel doordat ik bezig ben om parser te gebruiken om gegevens uit een ini bestand te importeren. En doordat ik 'ff tussendoor' een log scriptje wil toevoegen zodat bepaalde gegevens worden weggeschreven naar een logbestand. Wil dus nu iets teveel.

Het loggedeelte zal ik dus voorlopig schrappen. Dat komt wel wanneer de basis staat.

Dit is mijn code tot nu toe...
code:
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/env python

# import 
import subprocess
import time
import os
import platform
import logging
import sys
from ConfigParser import SafeConfigParser

# Vastleggen van standaard data
pingcount = False
timerset = False

class LightControl():
    @staticmethod
    def pinger(hostname):
        isOnline = False;
        if (platform.system() == "Windows"):
            handler = subprocess.Popen("ping -n 1 " + hostname, stdout=subprocess.PIPE);
            result = re.search('Average = (.*)ms', handler.stdout.read());
            isOnline = ( result != None );
            
        else:
            result = subprocess.call(
                "ping -c 1 " + hostname, 
                shell=True, 
                stdout=open('/dev/null', 'w'), 
                stderr=subprocess.STDOUT
            );
            isOnline = (result == 0);

        return isOnline;

    @staticmethod
    def timer(timerset):
        # Kijk hoelaat het is (local time), en zoek datum op (localdate)
        localtime = time.strftime("%H%M")
        localdate = time.strftime("%d%m%y")
        print("Local time: "),localtime
        print("Local date: "),localdate

        # dit aanpassen van vast tijdstip naar zon ondergang-opkomst
        daylight_begin = parser.get('profiel_1', 'daylight_begin')
        daylight_end = parser.get('profiel_1', 'daylight_end')
        sleep_begin = parser.get('profiel_1', 'sleep_begin')
        print("Start time daylight: "),daylight_begin
        print("End time daylight: "),daylight_end
        print("Start sleep time: "),sleep_begin

        localtime = time.strftime("%H%M")

        if localtime <= daylight_begin or localtime >= daylight_end:
            print ("Switching lights ON.")
            subprocess.Popen("./kaku " + lights3_code)
        else:
            time.sleep(10)
            timerset = False
        return timerset

    @staticmethod
    def logger(reportinfo):
        LOG_FILENAME = 'tinylog.log'
        logging.basicConfig(filename=LOG_FILENAME,
                            level=logging.DEBUG,
                            )

        timestamp = time.strftime("%d-%m-%y %H:%M:%S")
        logging.info(timestamp + ' ' + reportinfo)
        f = open(LOG_FILENAME, 'rt')
        try:
            body = f.read()
        finally:
            f.close()


# START SCRIPT
Action = LightControl()

# Controleer voor aanwezigheid van ini file
inifile = 'tinyconfig.ini'
parser = SafeConfigParser()
parser.read(inifile)
candidates = [inifile]
found = (parser.read(candidates))
found_test = bool(parser.read(candidates))

if found_test == True:
    reportinfo = "Found " + inifile
    print reportinfo
    Action.logger(reportinfo)
else:
    reportinfo = "Missing ini file... please see DOC for creating ini file"
    print reportinfo
    Action.logger(reportinfo)
    sys.exit()

hostname = parser.get('global_settings', 'device_ip')
lights3_code = parser.get('global_settings', 'lights3_code')

reportinfo = "Starting tinydomo..."
print reportinfo
Action.logger(reportinfo)

while pingcount == False:
    Action.pinger(hostname)
    pingcount = Action.pinger(hostname)
    print reportinfo
    Action.logger(reportinfo)
    if pingcount == True:
        reportinfo = "Device found... " + str(pingcount)
        Action.timer()
        print("Localtime did match scheduled profile: "), timerset

ini file...
code:
1
2
3
4
5
6
7
8
9
10
11
12
[global_settings]
lights1_code = 18 C
lights2_code = 19 C
lights3_code = 20 C
device_ip = 192.168.1.110


[profiel_1]
profiel_name = Werkweek
daylight_begin = 0700
daylight_end = 1800
sleep_begin = 2230


Nog een vraagje...
Ik zag dat 4Real in zijn ping scriptje @staticmethod gebruikte.
Ik kreeg vage meldingen over teveel of te weinig gegevens. Snapte er niks van. Heb toen maar voor elke def @staticmethod gezet en vervolgens kreeg ik geen foutmelding meer. 8)7

Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Daarvoor zou ik je eerst doorverwijzen naar een goeie uitleg over classes en objects.
http://openbookproject.ne...lasses_and_objects_I.html
http://docs.oracle.com/ja.../java/concepts/index.html

Als je die hebt doorgenomen dan kan ik je zeggen dat static methods, functies zijn die 'horen bij' een class, maar die geen specifiek object nodig hebben om uitgevoerd te worden.

Python:
1
2
3
4
5
6
7
8
9
10
11
class Settings:
  def __init__(self, options=dict()):
    self.options = options

  @staticmethod
  def fromfile(self, path):
    settings = dict()
    with open(path, 'r') as f:
       for line in f:
          # handle line, put in settings
    return Settings(settings)


Het hoort duidelijk bij de Settings class. Maar je weet bijvoorbeeld niet op voorhand of de file geldig is of niet. Bijvoorbeeld:
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
try:
  mySettings = Settings.FromFile("/blah")
except:
  print "File /blah does not contain valid settings"
# op dit moment in de code heb je geen mySettings variabele
# dus je kan er ook geen foute dingen mee doen

# tegenover:

mySettings = Settings()
try:
  mySettings.read("/blah")
except:
  print "..."
# op dit moment is mySettings een object in een soort
# ongeldige toestand. 


Zonder het nog moeilijker te willen maken, python kent naast static methods ook nog class methods, een onderscheid die andere talen niet zo hebben. De details daarvan zijn op dit moment absoluut niet relevant.

Eigenlijk zou ik je ook moeten vertellen dat in python code net iets anders wordt gestructureerd (eerder met modules), maar daar is het misschien nog iets te vroeg voor ;) Daar kom je later vanzelf nog wel achter wanneer je projecten wat groter worden en je nog meer hergebruik tussen verschillende brouwsels wil.

[ Voor 17% gewijzigd door H!GHGuY op 08-03-2014 12:46 ]

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • Campo di Casa
  • Registratie: Januari 2010
  • Laatst online: 18:26
Ben langzaam aan wat verder met het scriptje...
Alleen nog niet helemaal tevreden over het pingen van de iphones. Moet nog een controle hebben wanneer de iPhone wel thuis is maar geen verbinding maakt met wifi. Want schijnbaar als het toestel slaapt is dit onbetrouwbaar met pingen...

onderstaande is de code tot nu toe :)
code:
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#!/usr/bin/env python

# import 
import subprocess
import time
import os
import platform
import logging
import sys
from ConfigParser import SafeConfigParser


# Vastleggen van standaard data
pingcheck = False
timerset = False
timenow = time.strftime("%H%M")
# timenow = "0100"

# Class voor het uitlezen en controleren van data uit het ini bestand.
class IniControl():
    def iniread(self):
        parser = SafeConfigParser()
        parser.read('tinyconfig.ini')
        return parser

    def inicheck(self, parser):
        found = bool(parser.read('tinyconfig.ini'))
        if found == True:
            print("Found ini file...")
        else:
            print("Missing ini file... please see DOC for creating ini file")
            sys.exit()

    def inivalue(self, parser):
        device_ip = parser.get('global_settings', 'device_ip')
        lights1_code = parser.get('global_settings', 'lights1_code')
        lights2_code = parser.get('global_settings', 'lights2_code')
        lights3_code = parser.get('global_settings', 'lights3_code')
        profile_name = parser.get('profile_1', 'profile_name')
        daylight_begin = parser.get('profile_1', 'daylight_begin')
        daylight_end = parser.get('profile_1', 'daylight_end')
        sleep_begin = parser.get('profile_1', 'sleep_begin')
        return {'device_ip':device_ip, 'lights1_code':lights1_code,
                'lights2_code':lights2_code, 'lights3_code':lights3_code,
                'profile_name':profile_name, 'daylight_begin':daylight_begin,
                'daylight_end':daylight_end, 'sleep_begin':sleep_begin}


# Class voor het controleren en aansturen van verlichting.
class LightControl():
    @staticmethod
    def pinger(device_ip):
        isOnline = False;
        if (platform.system() == "Windows"):
            handler = subprocess.Popen("ping -n 1 " + device_ip, stdout=subprocess.PIPE);
            result = re.search('Average = (.*)ms', handler.stdout.read());
            isOnline = ( result != None );
        else:
            result = subprocess.call(
                "ping -c 1 " + device_ip, 
                shell=True, 
                stdout=open('/dev/null', 'w'), 
                stderr=subprocess.STDOUT
            );
            isOnline = (result == 0);
        return isOnline;

    def daylightchecker(self, timenow, begin, end):
        if timenow < begin or timenow > end:
            dayLight = False
        if timenow > begin and timenow < end:
            dayLight = True
        else:
            print("error. iets gaat er niet goed... timenow = ",timenow)
            sys.exit()
        return dayLight

    def lightswitch(self, pingcheck, dayLight):
        if pingcheck == True and dayLight == False:
            print("Device gevonden. En volgens de test is het donker..")
            print("./kaku " + inivalue['lights1_code'])
        elif pingcheck == True and dayLight == True:
            print("Device gevonden. Maar volgens de test is het NIET donker...")
        elif pingcheck == False:
            print("Device is NIET gevonden...")
        else:
            print("...uhhh...")
        
# Vastleggen van waarde voor aanroepen class en def.
Ini = IniControl()
Action = LightControl()
parser = Ini.iniread()
inivalue = Ini.inivalue(parser)

Ini.inicheck(parser) # Controleer voor aanwezigheid inifile

Action.pinger(inivalue['device_ip']) # start ping naar device
pingcheck = Action.pinger(inivalue['device_ip']) # Heeft ping wat gevonden?
dayLight = Action.daylightchecker(timenow, inivalue['daylight_begin'], inivalue['daylight_end'])

Action.lightswitch(pingcheck, dayLight) # Controleer waarde en schakel lampen

Acties:
  • 0 Henk 'm!

  • 4Real
  • Registratie: Juni 2001
  • Laatst online: 14-09-2024
Ik zie in ieder geval dat je tegen dezelfde problemen aanloopt als dat ik doe, dus dat is.. goed? :P 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 :P of euhm just-my-50-cents :P 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.

Acties:
  • 0 Henk 'm!

  • Campo di Casa
  • Registratie: Januari 2010
  • Laatst online: 18:26
thanx voor de lap tekst en stukken code. Lees de code nu meerdere keren door maar het dringt nog niet helemaal door. Maar zoals je al aangaf is de leercurve behoorlijk stijl! Dus dat zal er zeker mee te maken hebben :p

Eigenlijk moet ik me alleen maar bezig houden met puur dit python scriptje, maar doe alles tegelijk, en dan ben ik ondertussen ook nog eens bezig met het prutsen aan het LCD schermpje...
Afbeeldingslocatie: http://farm8.staticflickr.com/7460/13147998883_93b4fbfa90_n.jpg

Maar ik zat vanmorgen alle reply's nog eens door te lezen en ik weet niet meer door welk stukje tekst ik op het idee kwam, maar misschien benadeer ik het een tikkeltje verkeerd. Zou het niet makkelijker zijn eerst te kijken d.m.v. tijd of de lampen aan moeten en dan pas kijken of er iemand thuis is d.m.v. pingen?

Een groot deel van de dag is het licht en heb je geen verlichting nodig. De uren dat je wel verlichting wenst is in de avond en ochtend uren. snachts slaap je en heb je ook geen verlichting nodig. dus waarom zou je dan gaan pingen tussen 07:00uur en 18:00uur en tussen 00:00 en 05:00uur? Is het dan niet beter om pas een half uur voor zon-ondergang en een half uur voordat je smorgens opstaat te gaan pingen? Want vaak zal je toch een verkeerde waarde krijgen i.v.m. een device die in slaap stand is.

Je gaf aan dat mijn manier van programmeren vaag was. Kan je ook aangeven op welke manier? Ben totaal niet beledigd, maar misschien doe ik iets qua denkwijze totaal verkeerd. Kan het beter nu afleren dan wanneer het eigen is geworden... ;)

Acties:
  • 0 Henk 'm!

  • 4Real
  • Registratie: Juni 2001
  • Laatst online: 14-09-2024
housekamp schreef op vrijdag 14 maart 2014 @ 16:13:
thanx voor de lap tekst en stukken code. Lees de code nu meerdere keren door maar het dringt nog niet helemaal door. Maar zoals je al aangaf is de leercurve behoorlijk stijl! Dus dat zal er zeker mee te maken hebben :p

Eigenlijk moet ik me alleen maar bezig houden met puur dit python scriptje, maar doe alles tegelijk, en dan ben ik ondertussen ook nog eens bezig met het prutsen aan het LCD schermpje...
[afbeelding]

Maar ik zat vanmorgen alle reply's nog eens door te lezen en ik weet niet meer door welk stukje tekst ik op het idee kwam, maar misschien benadeer ik het een tikkeltje verkeerd. Zou het niet makkelijker zijn eerst te kijken d.m.v. tijd of de lampen aan moeten en dan pas kijken of er iemand thuis is d.m.v. pingen?

Een groot deel van de dag is het licht en heb je geen verlichting nodig. De uren dat je wel verlichting wenst is in de avond en ochtend uren. snachts slaap je en heb je ook geen verlichting nodig. dus waarom zou je dan gaan pingen tussen 07:00uur en 18:00uur en tussen 00:00 en 05:00uur? Is het dan niet beter om pas een half uur voor zon-ondergang en een half uur voordat je smorgens opstaat te gaan pingen? Want vaak zal je toch een verkeerde waarde krijgen i.v.m. een device die in slaap stand is.
Opzich een grappige manier om er naar toe te kijken, want zo had ik hem nog niet bedacht. Het kan inderdaad. Het bespaard misschien een x-aantal keer dat je hoeft te pingen, maar het kost bijna niets om een ping-actie uit te voeren.
Je gaf aan dat mijn manier van programmeren vaag was. Kan je ook aangeven op welke manier? Ben totaal niet beledigd, maar misschien doe ik iets qua denkwijze totaal verkeerd. Kan het beter nu afleren dan wanneer het eigen is geworden... ;)
Wat mij zo opvalt is hoe je classes en functies in classes gebruikt.

Een class is soort template van een bepaald object, dit kan echt van alles zijn. Bijvoorbeeld een class van auto kan de variabelen: nummer van wielen, nummer van deuren, lengte, breedte, hoogte, kleur. Functies kunnen zijn, aan/uit, schakelen, gas geven, remmen etc. In de class voeg je alles wat met het object te maken heeft. Als ik naar jouw class kijk dan zie ik een functie pinger en die hoort daar niet echt thuis.

Dan instanties maken van classes, zoals ik al aangaf is een class een template, dus wanneer je een instantie maakt van een class kun je het object echt vorm geven. Bijvoorbeeld:
Python:
1
2
carA = Car("blue");
carB = Car("yellow");

Zo heb je dus twee auto's één die blauw is en één die geel is. Bij lampen is die niet anders, elke lamp in je huis instantie van de class lamp, [url=]http://www.ikea.com/nl/nl/catalog/products/60190827/ook[/url] al zien die lampen er anders uit, want de template blijft voor een groot deel hetzelfde. Wat hebben deze lampen allemaal gemeen? Ze kunnen aan en uit (functie), er zit een lichtbron in (led-lamp, spaar-lamp, halogeen), en dan nog andere attributen zoals snoer en fitting etc. Met iedere instantie die je aanmaakt kun je één lamp mee aan en uit zetten.

In een eerdere reactie kun je wel zien hoe ik mijn classes heb vorm gegeven, door middel van de volgende code regel kan ik hem identificeren en standaard waarde geven.
Python:
1
objA = ElectricalSocket("boekenkast", False);

Ik heb dus nu een object die gekoppeld is met de lamp van de boekenkast. Wanneer ik de volgende regel code uitvoer dan zal die lamp aangaan: objA.TurnOn();. In de functie TurnOn zal de naam van de naam worden gebruikt om precies die lamp aan te zetten.

Acties:
  • 0 Henk 'm!

  • Campo di Casa
  • Registratie: Januari 2010
  • Laatst online: 18:26
Ik loop al vanaf het begin te klooien met classes etc. Elke keer denk ik dat het kwartje is gevallen, maar blijkt dit nog niet zo te zijn. De afgelopen dagen weinig tijd gehad. Maar zal kijken of ik vanavond wat meer kan verdiepen in classes etc...

Is onderstaande dan wel juist opgezet?
code:
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
class IniControl():
    def iniread(self):
        parser = SafeConfigParser()
        parser.read('tinyconfig.ini')
        return parser

    def inicheck(self, parser):
        found = bool(parser.read('tinyconfig.ini'))
        if found == True:
            print("Found ini file...")
        else:
            print("Missing ini file... please see DOC for creating ini file")
            sys.exit()

    def inivalue(self, parser):
        device_ip = parser.get('global_settings', 'device_ip')
        lights1_code = parser.get('global_settings', 'lights1_code')
        lights2_code = parser.get('global_settings', 'lights2_code')
        lights3_code = parser.get('global_settings', 'lights3_code')
        profile_name = parser.get('profile_1', 'profile_name')
        daylight_begin = parser.get('profile_1', 'daylight_begin')
        daylight_end = parser.get('profile_1', 'daylight_end')
        sleep_begin = parser.get('profile_1', 'sleep_begin')
        return {'device_ip':device_ip, 'lights1_code':lights1_code,
                'lights2_code':lights2_code, 'lights3_code':lights3_code,
                'profile_name':profile_name, 'daylight_begin':daylight_begin,
                'daylight_end':daylight_end, 'sleep_begin':sleep_begin}

Ini = IniControl()
parser = Ini.iniread()
inivalue = Ini.inivalue(parser)

Ini.inicheck(parser) # Controleer voor aanwezigheid inifile

Acties:
  • 0 Henk 'm!

  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 08-06 02:21
Een instantie van een class kan zijn eigen state bijhouden. Dus ipv die parser overal als argument mee te geven, kun je die beter in de class zelf opslaan. Dan weet je zeker dat die parser hetzelfde blijft, en niet per ongeluk iets anders wordt meegegeven. Vergelijk de auto-analogie, als er een blauwe auto is gemaakt, dan blijft die blauw, dat hoeft de eigenaar van de auto niet te onthouden.

Je kunt ook nog van __init__() gebruik maken, die maakt een instantie van een class klaar voor gebruik.

Als je bijvoorbeeld in __init__ de aanroep naar iniread() zet, en de parser in de class opslaat, wordt het aanroepen een stuk simpeler. Eventueel ook de check al in de __init__ aanroepen, die heb je toch altijd een keer nodig. Kan je hem ook niet vergeten.

iniread() en inicheck() lijken wel wat op elkaar, zou je misschien delen kunnen samenvoegen in 1 van de functies of naar een derde functie? Want als je iets moet veranderen aan hoe het werkt, wil je niet twee keer hetzelfde veranderen, of nog erger, maar 1 veranderen en de andere vergeten.

Qua naamgeving zou je kunnen overwegen niet overal ini voor te zetten, je weet al dat het een class is die een ini leest.

Als je dat hebt gedaan wordt het gebruik van de class een stuk simpeler:
Python:
1
2
3
ini = IniControl()
ini.check() # als die nog nodig is
ini.value()

Acties:
  • 0 Henk 'm!

  • Campo di Casa
  • Registratie: Januari 2010
  • Laatst online: 18:26
oke, het was ff puzzelen maar is gelukt. Heb het nu terug gebracht tot het volgende stukje code...
code:
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
class IniControl():
    def __init__(self):
        self.inifile = 'tinyconfig.ini'
        self.parser = self.read()

    def read(self):
        parser = SafeConfigParser()
        parser.read(self.inifile)
        found = bool(parser.read(self.inifile))
        if found == True:
            print("Found ini file...")
            return parser
        else:
            print("Missing ini file... please see DOC for creating ini file")
            sys.exit()        

    def value(self):
        hostname = self.parser.get('global_settings', 'device_ip')
        lights1_code = self.parser.get('global_settings', 'lights1_code')
        lights2_code = self.parser.get('global_settings', 'lights2_code')
        lights3_code = self.parser.get('global_settings', 'lights3_code')
        profile_name = self.parser.get('profile_1', 'profile_name')
        return {'hostname':hostname, 'lights1_code':lights1_code,
                'lights2_code':lights2_code, 'lights3_code':lights3_code,
                'profile_name':profile_name}

Ini = IniControl()
b = Ini.value()


Ik had voornamelijk moeite met het aanroepen van de parser. In eerste instantie deed ik het door...
code:
1
parser = Ini.read()

tot ik er achter kwam dat ik gebruik moest maken van 'self' en Ini moest weglaten ;)
Daarnaast riep ik 2x read aan. De eerste keer doordat ik dit al deed via __init__, en vervolgens door Ini.read() onderaan de code. Maar dat zag ik gelukkig wat sneller...

Het is nu idd makkelijker om zo de class te gebruiken. En door het aanpassen van de namen ini.value naar value leest het ook wat beter. Misschien valt dit nog wel wat te verbeteren, maar denk dat ik het zo laat. Dan kan ik me weer bezig houden met de andere classes en deze verbeteren...

Acties:
  • 0 Henk 'm!

  • Eärendil
  • Registratie: Februari 2002
  • Laatst online: 19:14
Om de code wat flexibeler te maken zou je de naam van de inifile als argument kunnen meegeven aan __init__():
Python:
2
3
4
    def __init__(self, inifile):
        self.inifile = inifile
        self.parser = self.read()


  • In de read-methode roep je nu zonder reden twee keer de methode parser.read() aan (regel 8 en 9)
  • De functie bool() is niet nodig, je kan het resultaat van parser.read() ook direct als expressie gebruiken in de if
  • 'if a == True' is hetzelfde als 'if a'
Python:
6
7
8
9
10
11
12
13
    def read(self):
        parser = SafeConfigParser()
        if parser.read(self.inifile):
            print("Found ini file...")
            return parser
        else:
            print("Missing ini file... please see DOC for creating ini file")
            sys.exit()



Jouw methode value() herschrijft nu je hele ini-file naar andere namen van de opties. Is het niet makkelijker om de namen in de ini-file te veranderen? :P
Dan kan je de ook de methodes 'sections' en 'items' van SafeConfigParser gebruiken.
In een one-liner:
code:
1
2
3
4
5
6
7
8
9
10
>>> {section:dict(config.items(section)) for section in config.sections()}
{'global_settings': {'device_ip': '192.168.1.110', 
                     'lights1_code': '18 C', 
                     'lights2_code': '19 C', 
                     'lights3_code': '20 C'},
 'profiel_1': {'sleep_begin': '2230', 
               'profiel_name': 'Werkweek', 
               'daylight_begin': '0700', 
               'daylight_end': '1800'}
}

Acties:
  • 0 Henk 'm!

  • Campo di Casa
  • Registratie: Januari 2010
  • Laatst online: 18:26
Eärendil schreef op woensdag 26 maart 2014 @ 10:58:
Om de code wat flexibeler te maken zou je de naam van de inifile als argument kunnen meegeven aan __init__():


  • In de read-methode roep je nu zonder reden twee keer de methode parser.read() aan (regel 8 en 9)
  • De functie bool() is niet nodig, je kan het resultaat van parser.read() ook direct als expressie gebruiken in de if
  • 'if a == True' is hetzelfde als 'if a'


Jouw methode value() herschrijft nu je hele ini-file naar andere namen van de opties. Is het niet makkelijker om de namen in de ini-file te veranderen? :P
Dan kan je de ook de methodes 'sections' en 'items' van SafeConfigParser gebruiken.
In een one-liner:
code:
1
2
3
4
5
6
7
8
9
10
>>> {section:dict(config.items(section)) for section in config.sections()}
{'global_settings': {'device_ip': '192.168.1.110', 
                     'lights1_code': '18 C', 
                     'lights2_code': '19 C', 
                     'lights3_code': '20 C'},
 'profiel_1': {'sleep_begin': '2230', 
               'profiel_name': 'Werkweek', 
               'daylight_begin': '0700', 
               'daylight_end': '1800'}
}
De inifile als argument meegeven had ik wel in het eerste stukje code. Maar toen ik alles in een class stopte heb ik dit veranderd. Maar heb het weer aangepast.

En dat ik de functie bool() in dit voorbeeld niet nodig had wist ik niet. Ik heb dit min of meer overgenomen uit een andere stukje code waar ik eerder mee bezig was. Schijnbaar was het toen dus ook niet nodig...

Het laatste wat je aangaf is mij nog niet gelukt. Ben daar gisteravond ff mee bezig geweest maar kom daar nog niet helemaal uit. Ik heb dit er als voorbeeld maar bij gepakt maar het is me nog niet helemaal duidelijk. Vanavond maar verdere documentatie opzoeken...

Acties:
  • 0 Henk 'm!

  • Eärendil
  • Registratie: Februari 2002
  • Laatst online: 19:14
De method sections() geeft je alle secties uit de config (global_settings en profiel_1).
code:
1
2
>>> parser.sections()
['global_settings', 'profiel_1']


Daar kan je over itereren, en dan voor elke sectie de items opvragen die daar bij horen. De method items() geeft je een list van tuples (option,value). Met dict() kan je dat omzetten in in een dictionary.
code:
1
2
3
4
5
6
7
8
9
10
11
>>> parser.items('profiel_1')
[('profiel_name', 'Werkweek'),
 ('daylight_begin', '0700'),
 ('daylight_end', '1800'),
 ('sleep_begin', '2230')]

>>> dict(parser.items('profiel_1'))
{'daylight_begin': '0700',
 'daylight_end': '1800',
 'profiel_name': 'Werkweek',
 'sleep_begin': '2230'}


Als je dat samenvoegt krijg je:
Python:
1
2
3
c = dict()
for section in parser.sections():
    c[section] = dict(parser.items(section))


Dat is hetzelfde als de volgende dictionary comprehension:
code:
1
c = {section:dict(parser.items(section)) for section in parser.sections()}

Acties:
  • 0 Henk 'm!

  • Campo di Casa
  • Registratie: Januari 2010
  • Laatst online: 18:26
Waarschijnlijk zie ik iets simpels over het hoofd...
Maar in het volgende voorbeeld moet de waarde van 'sw' veranderd worden van 'False' naar 'True'.
Alleen de waarde wordt niet terug gegeven.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python

sw = False

class A():
    def b(self, sw):
        if sw == False:
            print("False naar True")
            sw = True
        else:
            print("True blijft True")
        print sw
        return sw

Switch = A()

Switch.b(sw)
print("Status sw"), sw


ik krijg dan dit resultaat...
code:
1
2
3
4
5
housekamp@debian:~/Documenten/tinydomo/testfiles$ python test.py
False naar True
True
Status sw False
housekamp@debian:~/Documenten/tinydomo/testfiles$

Acties:
  • 0 Henk 'm!

  • Ramon
  • Registratie: Juli 2000
  • Laatst online: 17:23
Je vangt de return waarde niet op, zoiets zou moeten werken (regel 17):

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python

sw = False

class A():
    def b(self, sw):
        if sw == False:
            print("False naar True")
            sw = True
        else:
            print("True blijft True")
        print sw
        return sw

Switch = A()

sw = Switch.b(sw)
print("Status sw"), sw


In dit voorbeeld is het ook handiger om de sw binnen je class anders te noemen, want ze zijn niet aan elkaar gerelateerd, en dat maakt het allemaal iets duidelijker.

Check mijn V&A ads: https://tweakers.net/aanbod/user/9258/


Acties:
  • 0 Henk 'm!

  • Campo di Casa
  • Registratie: Januari 2010
  • Laatst online: 18:26
thanx :)
Zal kijken of ik dit kan aanpassen naar het echte script.

Acties:
  • 0 Henk 'm!

  • Campo di Casa
  • Registratie: Januari 2010
  • Laatst online: 18:26
De laatste 2 weken mijn scriptje laten test draaien. Haalt nu netjes de zon-opkomst-ondergang van Yahoo, en zet de lampen aan indien nodig. Het pingen van mijn iPhone via wifi bleek geen succes. Zodra de iPhone in standby zit wordt de verbinding met wifi verbroken en is de iPhone niet meer te pingen. Het principe om dus dat te gebruiken om het script te laten weten of ik thuis ben werkt niet.

Ben daarom verder gaan kijken en uitgekomen op Blutooth. Heb daar een testje mee gedaan en via Blutooth laat ik scannen naar het opgegeven adres van mijn iPhone. Ik gebruik het opvragen naar device-name als een Boolean en dit lijkt te werken. Zolang Blutooth aanstaat krijg ik netjes response. Zelfs als de iPhone in standby zit. ;) Nu nog testen of ik nog steeds response krijg als de iPhone een paar uur in standby staat...

Mocht dit lukken, gebruik ik de Blutooth ook meteen als switch wanneer ik naar bed ga. Alleen nu nog een manier bedenken wanneer dit gekoppeld is aan 2 iPhone's...

ondertussen ook mijn code wat opschonen. Veel doe ik nog omslachtig door gebrek aan kennis. Maar het is een leuk projectje om zo meer te verdiepen in Python!

[ Voor 7% gewijzigd door Campo di Casa op 29-05-2014 09:53 ]


Acties:
  • 0 Henk 'm!

  • 4Real
  • Registratie: Juni 2001
  • Laatst online: 14-09-2024
Ik heb ook problemen met het pingen van mijn telefoon, daarom is het bij mij alleen mogelijk om te zien of ik thuis ben gekomen. Als mijn status van thuis zijn false is (dus ik ben niet thuis), maar hij kan mijn telefoon toch pingen, dan kan hij aannemen dat ik thuis ben gekomen. Er zitten hier nog een stel maar aan, toch werkt dit systeem best goed. Als ik het huis uit ga, dan is deze methode van thuis komen voor 15minuten uitgeschakeld, zodat hij mij niet direct weer ziet en de status van thuis zijn registreerd.

Acties:
  • 0 Henk 'm!

  • Campo di Casa
  • Registratie: Januari 2010
  • Laatst online: 18:26
Projectje draait alweer een tijdje. Heb langzaam een paar dingen verbeterd en ben nu op een punt dat ik het script opnieuw wil schrijven. Er zitten nog vrij veel beginners foutjes in, en sommige dingen gebeuren nu vrij omslachtig. Iets wat ik als eerste ga veranderen is het omslachtig uitlezen van het ini bestand. Dit scheelt me veel werk en zorgt voor minder fouten doordat ik meer overzicht heb.
Eärendil schreef op donderdag 27 maart 2014 @ 10:11:
De method sections() geeft je alle secties uit de config (global_settings en profiel_1).
code:
1
2
>>> parser.sections()
['global_settings', 'profiel_1']


Daar kan je over itereren, en dan voor elke sectie de items opvragen die daar bij horen. De method items() geeft je een list van tuples (option,value). Met dict() kan je dat omzetten in in een dictionary.
code:
1
2
3
4
5
6
7
8
9
10
11
>>> parser.items('profiel_1')
[('profiel_name', 'Werkweek'),
 ('daylight_begin', '0700'),
 ('daylight_end', '1800'),
 ('sleep_begin', '2230')]

>>> dict(parser.items('profiel_1'))
{'daylight_begin': '0700',
 'daylight_end': '1800',
 'profiel_name': 'Werkweek',
 'sleep_begin': '2230'}


Als je dat samenvoegt krijg je:
Python:
1
2
3
c = dict()
for section in parser.sections():
    c[section] = dict(parser.items(section))


Dat is hetzelfde als de volgende dictionary comprehension:
code:
1
c = {section:dict(parser.items(section)) for section in parser.sections()}
Alleen loop ik nu vast bij 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
from ConfigParser import SafeConfigParser
inifile = 'tinyconfig.ini'

class Ini():
    def __init__(self, inifile):
        self.inifile = inifile
        self.parser = self.read()

    def read(self):
        parser = SafeConfigParser()
        if parser.read(self.inifile):
            for section in parser.sections():
                inidict = dict(parser.items(section))
            return inidict
        else:
            print("<ERROR> Missing ini file...")
            sys.exit()        

class Test():
    def testikel(self, aa):
        print aa


Ini = Ini(inifile)
inidict = Ini.read()
aa = inidict['zoekwaarde']
Test = Test()
Test.testikel(aa)


Op dit moment moet ik nog steeds aa verwijzen naar de dictionary omdat het volgende niet is toegestaan...
Python:
1
def testikel(self, inidict['dlb'])


Het lijkt mij dat dit toch moet kunnen. Heb het al geprobeerd om tussen () te zetten, maar geen resultaat.

[ Voor 6% gewijzigd door Campo di Casa op 09-08-2014 09:54 ]


Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

housekamp schreef op zaterdag 09 augustus 2014 @ 08:28:
Op dit moment moet ik nog steeds aa verwijzen naar de dictionary omdat het volgende niet is toegestaan...
Python:
1
def testikel(self, inidict['dlb'])


Het lijkt mij dat dit toch moet kunnen. Heb het al geprobeerd om tussen () te zetten, maar geen resultaat.
Elke variabele/member heeft een scope:
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
// file test.py
a=10
def B():
  b=11
class Class():
  def __init__(self):
     self.c=12
  def C(self):
     d=12
     self.c=13
     global a
     a = 14
     # b=15 kan niet


a heeft module scope en is dus in de hele module gekend (deze is global).
b heeft function-local scope en is enkel in de functie gekend.
c heeft object scope en is enkel op dat object gekend
d heeft function-local scope en is enkel in de functie gekend.
Er bestaan in python ook nog class-scoped variabelen (en misschien mis ik er nog wel wat?)

In python staan alle variabelen in een dictionary op verschillende niveau's:
global dictionary: hierin zou a zitten (i.e. alles met module scope)
object dictionary: hierin zou c zitten (alles met object scope)
elke functie heeft ook een lokale dictionary, hierin zouden b en d zitten, maar ook 'self' en andere argumenten die gepassed worden. (Merk op dat in python namen zoals a, b, c, d verwijzen naar de echte waarde en dat die waarde pas verdwijnt als niemand nog verwijst - term: garbage collection) Dus als de functie eindigt verdwijnt 1 referentie naar self, die van de function-local dictionary.

Argumenten van een functie moet je zien als het op voorhand vullen van de dictionary met enkele variabelen van elders; met andere woorden: de naam van het argument is de key van de dictionary - i.e. de linkerkant van een assignment (lvalue):
Python:
1
2
3
def test(aa):
  print aa
test(10)

Dus in bovenstaand voorbeeld wordt de functie dictionary van test gevuld met: { aa:10 } op het moment dat test(10) aangeroepen wordt. (aa is hier een lvalue, 10 is de rvalue - voor de technischere termen).

Wat jij wil is dus vanuit 1 functie een variabele van een andere functie (die niet eens aan het draaien is en dus geen dictionary heeft) aanspreken... Bovendien probeer je dit op een manier waarbij je een rvalue (inidict['dlb']) gebruikt waar een lvalue (aa) verwacht wordt.

Uit je voorbeeld is ook niet duidelijk wat je probeert te doen:
- wil je dat aa een default waarde heeft:
Python:
1
2
3
4
def test(aa=10):
  print aa
test() # print 10
test(20) # print 20

- wil je dat je inidict["dlb"] ter beschikking hebt in de functie?
dan zou ik aanraden van inidict (via __init__?) in de object dictionary te krijgen
Python:
1
2
3
4
5
class C:
  def __init__(self, settings):
    self.settings = settings
  def test(self):
     print self.settings['dlb']

- nog iets anders?

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • Campo di Casa
  • Registratie: Januari 2010
  • Laatst online: 18:26
Thanx.
Ik ben geen programmeur en zal het ook nooit worden ;)

De bedoeling is dat, in dit geval, de waarde voor dlb uit een bestand wordt gehaald. En dat deze waarde als basis dient om veranderd te worden. In eerste instantie haalde ik de waarde op uit het bestand en koppelde ik dit weer aan een andere waarde zodat ik er mee kon werken. Earendil kwam toen met het idee om alle data uit het bestand in een Dictionary te stoppen. Dat werkt prima, alleen heb ik dus nu moeite om een waarde die ik uit een Dictionary haal, weer te kunnen doorgeven aan een def.

Nu moest ik dus het volgende doen om toch een waarde te kunnen gebruiken in een def.
Python:
1
2
dlb = inidict['dlb']
Test.testikel(self, dlb)

Terwijl ik liever meteen de waarde vanuit de Dictionary doorgeef.
(wat ik dus probeerde...)
Python:
1
Test.testikel(self, (inidict['dlb']))


Ik ga zometeen je uitleg nog eens goed doorlezen. En ben blij dat ik dit puur voor de fun doe. Krijg deze stof er nog amper in. Getting too old for this shit :P

Hieronder een Class waar ik dus de waarde uit het bestand in wil gebruiken. In regel7 heb ik dus de waarde dlb en dle nodig die ik in eerste instantie uit een bestand haal. Deze waarde gaat eerst nog door een class Yahoo waar de definitieve waarde wordt bepaald. En wordt dan pas doorgegeven aan onderstaande def. Misschien is het zo wat duidelijker wat ik probeer te doen. Ondanks dat deze Class nog niet helemaal af is.

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
class Lights():
    def __init__(self): # verzamel data
        self.tn = int(time.strftime("%H%M"))
         
        # controleer daglicht
        if self.tn > int(inidict['dlb']) and self.tn < int(inidict['dle']):
            self.dl = True
        else:
            self.dl = False

        # controleer of het weekend is en zet nachtstand
        self.wkd = datetime.date.weekday(datetime.datetime.today())
        if self.wkd in range(5,7): # 1=maandag, 7=zondag
            wke = True
            self.b = int(inidict['wslb'])
            self.e = int(inidict['wsle'])
        else:
            wke = False
            self.b = int(inidict['slb'])
            self.e = int(inidict['sle'])

        if self.tn > self.e and self.tn < self.b:
            self.sl = False
        else:
            self.sl = True

    def check(self, path, pc, sw): # Switch lights on/off
        if pc == True: # er is iemand thuis
            if self.dl == False: # er is geen daglicht
                if self.sl == False: # het is nog geen nacht
                    if sw == False:
                        logdata = "Evening. Turning lights on."
                        print("<INFO>  %s") % logdata
                        Log.logger(logfile, logdata)
                        os.system(path+"./kaku 18 C on")
                        sw = True
                    else:
                        print("<INFO>  Evening. Lights stay on.")
                else: # het is nacht
                    if sw == False:
                        print("<INFO>  Sleepmode. Lights stay off.")
                    else:
                        logdata = "Sleepmode. Turning lights off."
                        print("<INFO>  %s") % logdata
                        Log.logger(logfile, logdata)
                        os.system(path+"./kaku 18 C off")
                        sw = False
            else: # er is daglicht
                if sw == False:
                    print("<INFO>  Daytime. Lights stay off.")
                else:
                    logdata = "Daytime. Turning lights off."
                    print("<INFO> %s") % logdata
                    Log.logger(logfile, logdata)
                    os.system(path+"./kaku 18 C off")
                    sw = False
        else: # niemand is thuis
            logdata = "No ping returned. Nobody home?"
            print("<INFO>  %s") % logdata
            Log.logger(logfile, logdata)
            sw = False

n.b.
Op dit moment heb ik nog niet de kennis om tijden direct met elkaar te kunnen vergelijken etc. Vandaar dat ik dit met een omweg doe en ruw omzet naar integer. Ik weet dat het niet zo hoort, maar op dit moment werkt het. En kan dit later vrij gemakkelijk aanpassen.

Acties:
  • 0 Henk 'm!

  • Campo di Casa
  • Registratie: Januari 2010
  • Laatst online: 18:26
Ik heb het eindelijk voor elkaar met het pingen naar mijn iPhone. Via WiFi bleek onbetrouwbaar te zijn, helemaal omdat de iPhone geen verbinding maakt als de telefoon vergrendeld is. Pingen was daardoor dus zinloos.

Ben nu aan het testen geweest met Bluetooth en met resultaat!
Eerst wordt mijn iPhone gepinged op aanwezigheid. bij True wordt het verlichting ingeschakeld indien gewenst. bij False wordt er gepinged naar de iPhone van mijn vriendin. Mocht dat wel True zijn wordt indien gewenst de verlichting ingeschakeld. Als de lampen aan zijn en het blijkt dat er geen verbinding is met beide iPhone's wordt er nog niet meteen wat gedaan. Pas als er 10x achtereen geen verbinding wordt gemaakt (er wordt om de 10sec op dit moment gepinged) wordt het verlichting uitgeschakeld.

n.b. True en False in het script lijkt omgedraaid te staan. Maar dat is het niet. Dat heeft echt te maken met de output van l2ping ;)


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
class Ping():
    def __init__(self):
        self.dbt1 = inidict['dbt1']
        self.dbt2 = inidict['dbt2']
        self.pingfailure = 0

    def pinger(self, pc):
        print ("ping naar device 1...")
        if os.system("l2ping -c 1 "+self.dbt1) == False:
            print ("device 1 gevonden.")
            self.pingfailure = 0 # Device gevonden. Zet teller op 0
            pc = True
        else:
            print ("ping naar device 2...")
        if os.system("l2ping -c 1 "+self.dbt2) == False:
            print ("device 2 gevonden.")
            self.pingfailure = 0 # Device gevonden. Zet teller op 0
            pc = True
        else:
            self.pingfailure = self.pingfailure + 1
            print ("pingfailure = %s")% self.pingfailure
        if self.pingfailure == 10: # Meerdere keren geen Device gevonden. Niemand thuis.
            pc = False
            self.pingfailure = 0

    return pc



Het enigste nadeel is dat het ping opdracht ook zichtbaar is inclusief output. Nu wil ik dat het pingen niet zichtbaar is. Ik doe dit nu via os.system maar hoe kan ik ervoor zorgen dat dit niet zichtbaar is?

[ Voor 3% gewijzigd door Campo di Casa op 02-10-2014 07:14 ]


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 17:38

Creepy

Tactical Espionage Splatterer

Zoeken op "python os.system no output" levert me direct resulten op in google. Waarom werkten al die oplossingen niet voor je?

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • Campo di Casa
  • Registratie: Januari 2010
  • Laatst online: 18:26
Ik heb wel eens domme vragen gesteld, maar dit is toch wel mijn meesterwerk. 7(8)7

Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 17:38

Creepy

Tactical Espionage Splatterer

Dan sluiten we daar het topic ook maar mee ;)

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney

Pagina: 1

Dit topic is gesloten.