Intelligent House Control System



Relaterede dokumenter
Ugeseddel 4 1. marts - 8. marts

Assignment #5 Toolbox Contract

AAU, Programmering i Java Intern skriftlig prøve 18. maj 2007

DANMARKS TEKNISKE UNIVERSITET

Kursus i OOP og Java. Kursus i Objektorienteret programmering i Java

University of Southern Denmark Syddansk Universitet. DM503 Forelæsning 11

Singleton pattern i Java

Software Construction 1 semester (SWC) Spørgsmål 1

Videregående programmering i Java

b) Udvid din implementation af forme til at understøtte.equals. To objekter af samme form er ens hvis de har samme værdier i felterne.

Jacob Nordfalk. Ingeniørhøjskolen i København. Nykøbing F itvisioncenter 24. februar 2004

Videregående Programmering Obligatorisk opgave - 3. semester, efterår 2004

class Time { int hours, min; } } Time t1; // Erklær variabel af type Time class Time1 { public static void main(string[] args) { Time t1; t1.

Tree klassen fra sidste forelæsning

METODER ARV KLASSER. Grundlæggende programmering Lektion 5

//Udskriver System.out.println("Hej " + ditfornavn + " " + ditefternavn + "."); System.out.println("Du er " + dinalder + " aar gammel!

Hvad er Objekter - Programmering

UML til kravspecificering

RMI introduktion. Denne artikel beskriver Java RMI (Remtote Method Invocation).

Kursusgang 11. Oversigt: Sidste kursusgang Værktøjer til udvikling og implementering af HCI-design Oversigt over Java Swing

Eksempel: Skat i år 2000

SWC eksamens-spørgsmål. Oversigt

Grundlæggende Programmering ITU, Efterår Skriftlig eksamen i Grundlæggende Programmering

Datalogi OB, Efterår 2002 OH er, forelæsning 10/ Klasser og nedarvning

Singleton pattern i C#

Forelæsning Uge 3 Mandag

Abstrakte datatyper C#-version

Automatisk Vandingssystem

Forelæsning Uge 2 Torsdag

Planlægningssystem til autoværksted.

import java.awt.event.*; import java.awt.*; Container <- Panel <- Applet Component <- Button <- Checkbox <- ScrollPane <- Label

FitLight Trainer brugsvejledning. Tablet controller. version 1.7

I profil-feltet kan imastra-kunder vælge om upload skal ske ligesom filerne var indsendt til mailboksen eller

Indholdsfortegnelse for kapitel 2

Objektorienteret Programmering

Indhold. Side 2 af 26

Online billede filtrering

Opgaven fortsat. Opfølgning på Opgave 2 og Use Cases. Opgaven. Trin 1: Væsentlige begreber. Resultatliste: 100 bryst, herrer

Dag 10 Flertrådet programmering

Test af It-komponent

class subklasse-navn extends superklasse-navn { } NorwaySpruce har superklassen Spruce, som igen har superklassen Tree.

Lektion 3. Grundlæggende programmering i VR

Klasser og objekter. (Afsnit i manualen)

University of Southern Denmark Syddansk Universitet. DM502 Forelæsning 2

Databaseadgang fra Java

DKAL Snitflader REST Register

Sektornet VPN Installationsvejledning Windows Vista/7

DM01 DM Obl. Afl. Jacob Christiansen, , D12, Elias 13/ Side 1 af 7

Brugers vejledning til indtastning af Naturdata på eksisterende 3- områder

Kom godt igang med Inventar registrering

DM507 Algoritmer og datastrukturer

Løsningsforslag til Camp Let. Case Beskrivelse: Camp Let

Threads i Java. Denne artikel giver en introduktion til threads i Java. Den beskriver hvad tråde er og forklarer hvordan de bruges i Java

Hvordan organiseres et programs grafik-elementer? OOP e uge kursusgang. Advarsel! Component-objekter

A Profile for Safety Critical Java

Vejledning. Opsætning af Trio Web Vers 2.0 feb. 2010

DM507 Algoritmer og datastrukturer

Software Dokumentation

PID2000 Archive Service

Skriftlig eksamen i Datalogi

Vejledning Flex-Control:

Objektorienterede metoder

DMX styring med USB-interface

SigmaT.

Introduktion til ActionScript, fortsat

Videregående programmering i Java

DM507 Algoritmer og datastrukturer

Vejledning INSTALLATION AF ZHC5010 BETJENINGSTRYK MED VERA SMART HOME CONTROLLER.

Kursusarbejde 3 Grundlæggende Programmering

Kvik start opsætning af kamera det første du skal gøre:

Skriftlig eksamen i Datalogi

INTELLIGENT BOLIGSTYRING

Installation af Oracle 10g Release 2 database

Martin Olsen. DM507 Projekt Del I. 19. marts 2012 FOTO: Colourbox

FORCE Inspect Online Manual v FORCE Inspect Online Manual. 1 af 18

Systemair Connect. Opsætning

Programmering C RTG

DM01 DM Obl. Afl. Jacob Christiansen, , D12, Elias 18/ Side 1 af 11

Programmering 1999 KVL Side 5-4. Klassen Time: metoder. Metoder i objektet giver mulighed for at ændre tilstanden, eller kigge på tilstanden.

Klasser og Objekter i Python. Uge 46 Learning Python: kap 15-16,

Vejledning INSTALLATION AF ZHC5010 BETJENINGSTRYK MED VERA SMART HOME CONTROLLER. ZHC5010 Firmware Version: 0.14

Miniprojekt2011. Formålet er at lære og indlære god objektorienteret programudvikling og programmering med Java, samt undervejs at opfylde studiekrav.

Obligatorisk opgave i objektorienteret analyse og design

DM507 Algoritmer og datastrukturer

OPC Access 3.0 opdatering via Stored Procedure

Automatisk Vandingssystem

Plugin-arkitektur med.net

Manual til AVG Antivirus

dmasark Aflevering - Uge 50

Database. Pr jekt. Hold CLmul-a14e Gruppe 3 3. semester Vejledere: Tue Becher Ivan R. Frederiksen

Rapport generator til Microsoft C5

Forelæsning Uge 2 Torsdag

Vejledning INSTALLATION AF ZHC5010 BETJENINGSTRYK MED FIBARO HOME CENTER. ZHC5010 Firmware Version: 1.0

Hassansalem.dk/delpin User: admin Pass: admin BACKEND

09/ Version 1.4 Side 1 af 37

Introduction til.net remoting i C#

Civilingeniøreksamen januar Skriftelig prøve den 12. januar 2001 Kursusnummer 49104

DK-Unit Point version 2.xx til PWE 37

DRFLive - dynamisk visning af resultater fra DRF Stævnesystem

Transkript:

OOPJ-E-1 F2003 Side 1 af 38 Intelligent House Control System udført af Kim Damgaard Indholdsfortegnelse Intelligent House Control System... 1 Indholdsfortegnelse... 1 Indledning... 2 Problemformulering... 2 Vision (formålet med programmet)... 2 Inception-fasen... 2 Krav til systemet (hvordan programmet skal virke)... 2 Definition af system grænse... 3 Primære aktører... 3 Primære aktørers mål... 3 Definer Use Cases... 4 Go - No go?... 5 Elaboration-fasen... 5 Testovervejelser... 8 Hvordan opgaven tænkes løst... 8 Domain Model... 8 Detaljeret design... 10 Beskrivelse af hvordan programmet virker... 10 Lever programmet op til forventningerne... 14 Bilag... 15 Bilag 1: SystemTester.java... 15 Bilag 2: Output ved kørsel af klassen SystemTester... 19 Bilag 3: Kildetekst til selve programmet... 21 Bilag 4: Klassediagram... 38

OOPJ-E-1 F2003 Side 2 af 38 Indledning Dette projekt er udarbejdet ved anvendelse af den proces, der officielt benævnes Unified Process (UP). UP kombinerer "best practices", iterativ- og risikodreven udvikling og anvendes ofte ved udvikling af objekt-orienterede systemer. UP består af fire faser, men grundet denne opgaves tidsmæssige begrænsninger når vi kun at arbejde i de to første, nemlig Inception-fasen og Elaboration-fasen. Endvidere er det iterative forløb ikke afspejlet i denne rapport og det vil kun være en lille delmængde af det endelige system, som kan nå at blive implementeret. Intelligent House Control System benævnes herefter som IHCS. Problemformulering Langt de fleste huse i dag indeholder ingen intelligent styring. Deres ejere må således leve med større risiko for skader ved indbrud, strømsvigt, gasudslip, brand- og vandskader osv. De går også glip af besparelser i udgifterne til bl.a. varme og lys, som en intelligent styring beviseligt medfører. Endvidere er der ikke mulighed for at fjernstyre/overvåge husets funktioner f.eks. via internettet. Vision (formålet med programmet) Intelligent House Control System er et bud på, hvordan styringen af fremtidens bolig skal fungere. Med dette system installeret kan husejeren styre husets funktioner efter sine behov. Systemet fødes med oplysninger i henhold til de fysiske forhold så som rum-fordeling, sensorer, tænd/sluk kontakter, lukke/åbne mekanismer. Endvidere angives ønskede temperaturer, tidsintervaller, koder/fingeraftryk for adgangskontrol, hvilke funktioner der skal kunne fjernstyres etc. Herefter slår systemet eksempelvis alarm ved indbrud, lukker for vandet ved opståede utætheder, lukker for gassen i tilfælde af udslip, tænder for lyset i indkørsel og entre når man kommer hjem om aftenen. Mulighederne er mange. Ændringer i systemets opsætning kan simuleres grafisk. Via Internet kan man logge sig på husets styresystem og f.eks. følge med i hvad der foregår i huset, tænde for varmen, kontrollere om vinduer er lukket og hvis ikke lukke dem (kræver selvfølgelig motor). Inception-fasen I denne fase undersøges det om, der skal investeres i en mere dybdegående analyse af problem-domænet. Med andre ord: Skal vi efter denne fase starte på Elaboration-fasen? Endvidere er det vigtigt at få afklaret om projektets interessenter er enige om visionen for projektet. Krav til systemet (hvordan programmet skal virke) Man kan med fordel kategorisere kravene efter FURPS+ modellen, for bl.a. at minimere risikoen for at glemme krav til systemet. For at finde samt dokumentere de funktionelle krav (F'et i FURPS+) benyttes Use-Case modellen, hvor ideen er at fokusere på hvorledes brugeren/aktøren, ved at bruge systemet, kan få sine mål opfyldt. Fremgangsmåden er at vælge system-grænse, identificere primære aktører; identificere primære aktørers mål og slutteligt definere Use Cases, der opfylder aktørernes mål.

OOPJ-E-1 F2003 Side 3 af 38 Definition af system grænse Systemet består af selve applikationen samt hardwaren og kan tilgås vha. et lokalt brugerinterface eller via Internettet. Uden for system grænsen er aktører samt en eventuel alarm-central. Primære aktører Følgende primære aktører er identificeret: Husejeren (systemadministrator) Personer med adgang til huset Bevægelse (beboere, gæster, rengøringspersonale, indbrudstyv, husdyr etc.) Tiden Temperaturen (ude og inde) Lys/mørke Gas, røg, vand og strøm Overvågningsproces Primære aktørers mål Aktør Husejeren (systemadministrator) Personer med adgang til huset Bevægelse Tiden Temperaturen (ude og inde) Lys/mørke Gas, røg, vand og strøm Overvågningsproces Mål Minimere risiko for skader. Minimere udgifterne til bl.a. varme og lys. Fjernstyre/overvåge husets funktioner f.eks. via internettet. Øge komforten. Sætte systemet op i henhold til de fysiske forhold så som rum-fordeling, vinduer, døre, sensorer, tænd/sluk kontakter, lukke/åbne mekanismer. Indtaste temperaturer, tidsintervaller. Angive personoplysninger så som adgangskoder/fingeraftryk, mobil.nr., e-mail-adresser. Angive hvilke funktioner der skal kunne fjernstyres etc. Simulere ændringer i systemets opsætning grafisk. Start systemet. Sætte alarm til/slå alarm fra. Tænde for lys. Give alarm. Regulere rum- og varmtvandstemperaturer. Forhindre/tillade adgang for givne personer i angivne tidsrum. Slukke for lyset efter en periode uden bevægelse. Regulere fremløbstemperatur i varmesystemet. Undgå at tænde for lys ved bevægelse, hvis der i forvejen er lyst nok. Give alarm. Slukke for gas elller vand. Genstarte system-processer, der er gået ned. Meddele systemadministrator vedr. system-fejl.

OOPJ-E-1 F2003 Side 4 af 38 Definer Use Cases En Use Case ifbm. kravanalyse for en software applikation bør, som en tommelfingerregel, omhandle forretningsprocesser på et niveau defineret som følger: En handling (som respons på en forretningsbegivenhed) udført af én person på ét sted på én gang, der tilfører målbar værdi til virksomheden og efterlader data på et konsistent stade. Ved at gennemgå listen over de primære aktørers mål og med ovenstående definition in mente, har jeg på nuværende tidspunkt identificeret følgende Use Cases: UC1: UC2: UC3: UC4: UC5: UC6: UC7: UC8: UC9: UC10: UC11: UC12: UC13: UC14: UC15: UC16: UC17: UC18: UC19: UC20: UC21: UC22: UC23: UC24: UC25: UC26: UC27: UC28: UC29: UC30: UC31: Angive/vedligeholde personoplysninger så som adgangskode/fingeraftryk, mobil.nr., e-mail-adresse og billede. Angive roller, tidsintervaller og tilknytte disse til personer. Angive oplysninger om hus så som adresse, plantegning og tilknyttede personer. Angive rum. Angive udvendige vinduer og døre. Angive oplysninger om alarm-system. Angive bevægelses-sensor. Angive lys-sensor. Angive strømsvigt-føler. Angive gaslugt-sensor. Angive røgalarmer. Angive vandmåler. Angive temperatur-følere. Angive tænd/sluk kontakter og om disse kan fjernstyres. Angive lukke/åbne mekanismer og om disse kan fjernstyres. Angive ønskede temperaturer. Angive oplysninger om varmesystemet. Angive varmestyringsperioder. Simulere ændringer i systemets opsætning. Sætte alarm til. Slå alarm fra. Tænde for lys. Slukke for lys. Give alarm. Regulere rum-temperatur. Regulere varmtvandstemperatur. Slukke for gas. Slukke for vand. Start systemet. Genstarte system-processer, der er gået ned. Meddele systemadministrator vedr. system-fejl. Uden for denne rapport er disse Use Cases beskrevet i "Brief Format". Ligeledes uden for rapporten udarbejdes på dette tidspunkt i projektet et Use Case Context diagram for at tilvejebringe et overblik over systemet. Det er vigtigt at notere sig, at ovenstående liste, i nuværende fase, ikke er udtømmende. Endvidere vil de funktionelle krav, som vores Use Cases skal være med til at afdække, næsten med sikkerhed, blive udsat for ændringer. Ændringer undervejs i projektforløbet skal ikke opfattes som et problem, men nærmere som en drivkraft i den igangværende proces (UP).

OOPJ-E-1 F2003 Side 5 af 38 Ved fortsat at benytte FURPS+ modellen, skal de ikke-funktionelle krav nu findes. Endvidere skal næste iteration planlægges ved at "ranke" kravene. Disse ting udelades dog også i besvarelsen af denne opgave. Go - No go? Det vurderes at projektet kan gennemføres samt at der vil være et stigende og profitabelt marked for systemer af denne type. Det besluttes at gå videre til Elaboration-fasen. Elaboration-fasen Højest rankede Use Cases beskrives nu i "Fully Dressed" format (her vises kun Basic Flows). Disse bør i virkelighedens verden understøttes/ledsages af hurtigt udarbejdede skærmbillede layouts. UC1: Angive/vedligeholde personoplysninger så som adgangskode/fingeraftryk, mobil.nr., e-mailadresse og billede. Primary Actor: Husejeren. Stakeholders and Interests: Husejeren: Ønsker at registrere oplysninger om personer, der relaterer sig til IHCS. Preconditions: Husejeren er logget på systemet. Success Guarantee (Postconditions): Oplysninger om person er registeret i systemet. Trigger: Husejeren ønsker at tilknytte personer til IHCS. Basic Flow: 1. Husejeren starter skærmbilledet "Registrer personoplysninger". 2. Systemet søger efter allerede registrede personer. 3. Systemet lister de oprettede personer. 4. Husejeren markerer den person, hvor oplysningerne skal opdateres. 5. Husejeren opdaterer relevante felter. 6. Husejeren trykker på "Gem". 7. Systemet gemmer personoplysningerne. UC3: Angive oplysninger om hus så som adresse, plantegning og tilknyttede personer. Primary Actor: Husejeren. Stakeholders and Interests: Husejeren: Ønsker at registrere oplysninger om sit hus, der skal styres af IHCS. Preconditions: Husejeren er logget på systemet. Success Guarantee (Postconditions): Oplysninger om huset er registeret i systemet. Trigger: Husejeren ønsker at styre sit hus vha. IHCS. Basic Flow: 1. Husejeren starter skærmbilledet "Registrere husoplysninger". 2. Systemet søger efter husoplysninger. 3. Systemet konstaterer at der ikke findes oplysninger. 4. Husejeren udfylder felterne. 5. Husejeren trykker på "Gem". 6. Systemet gemmer oplysningerne.

OOPJ-E-1 F2003 Side 6 af 38 UC4: Angive rum. Primary Actor: Husejeren. Stakeholders and Interests: Husejeren: Ønsker at registrere oplysninger om rummene i huset, der skal styres af IHCS. Preconditions: Husejeren er logget på systemet. Success Guarantee (Postconditions): Oplysninger om rum er registeret i systemet. Trigger: Husejeren ønsker at styre sit hus vha. IHCS. Basic Flow: 1. Husejeren starter skærmbilledet "Registrere rum". 2. Systemet søger efter rum. 3. Systemet konstaterer at der ikke findes oplysninger. 4. Husejeren udfylder felterne. 5. Husejeren trykker på "Gem". 6. Systemet gemmer oplysningerne. UC5: Angive udvendige vinduer og døre. Primary Actor: Husejeren. Stakeholders and Interests: Husejeren: Ønsker at registrere oplysninger om vinduer og døre i huset, der skal styres af IHCS. Preconditions: Husejeren er logget på systemet. Success Guarantee (Postconditions): Oplysninger om udvendige vinduer og døre er registeret i systemet. Trigger: Husejeren ønsker at styre sit hus vha. IHCS. Basic Flow: 1. Husejeren starter skærmbilledet "Registrere vinduer og døre". 2. Systemet præsenterer rummene og husejeren udvælger et. 3. Husejeren tilføjer de nødvendige vinduer/døre (mulige typer er foruddefineret i systemet). 4. Husejeren trykker på "Gem". 5. Systemet gemmer oplysningerne. UC7 og 8: Angive bevægelses-sensor, lys-sensor. Primary Actor: Husejeren. Stakeholders and Interests: Husejeren: Ønsker at registrere oplysninger om bevægelses- og lys-sensorer i huset, der skal styres af IHCS. Preconditions: Husejeren er logget på systemet. Success Guarantee (Postconditions): Oplysninger om bevægelses- og lys-sensor er registeret i systemet. Trigger: Husejeren ønsker at styre sit hus vha. IHCS. Basic Flow: 1. Husejeren starter skærmbilledet "Registrere bevægelses- og lys-sensorer". 2. Systemet præsenterer rummene og husejeren udvælger et. 3. Husejeren tilføjer bevægelses- og/eller lys-sensor. 4. Husejeren trykker på "Gem". 5. Systemet gemmer oplysningerne.

OOPJ-E-1 F2003 Side 7 af 38 UC14: Angive tænd/sluk kontakter og om disse kan fjernstyres (er simplificeret til "Angiv lampe"). Primary Actor: Husejeren. Stakeholders and Interests: Husejeren: Ønsker at registrere oplysninger om lamper i huset, der skal styres af IHCS. Preconditions: Husejeren er logget på systemet. Success Guarantee (Postconditions): Oplysninger om lampe er registeret i systemet. Trigger: Husejeren ønsker at styre sit hus vha. IHCS. Basic Flow: 1. Husejeren starter skærmbilledet "Registrere lamper". 2. Systemet præsenterer rummene og husejeren udvælger et. 3. Husejeren tilføjer lampe. 4. Husejeren trykker på "Gem". 5. Systemet gemmer oplysningerne. UC19: Simulere ændringer i systemets opsætning. Primary Actor: Husejeren. Stakeholders and Interests: Husejeren: Ønsker at simulere opsætningen af IHCS. Preconditions: IHCS er sat op og startet. Husejeren er logget på systemet. Success Guarantee (Postconditions): Husejeren har fået et overblik over hvorledes huset fungerer med den nuværende opsætning af IHCS. Trigger: Husejeren ønsker at afgøre om opsætningen af IHCS er optimal. Basic Flow: 1. Husejeren vælger hus, der skal simuleres. 2. Husejeren starter skærmbilledet "Simuler IHCS opsætning". 3. Systemet præsenterer rum, sensorer, lamper samt instruktioner. 4. Husejeren følger instruktionerne, herunder bevæge cursoren hen over de grønne bevægelses-følere for at simulere bevægelse, for at sikre sig at opsætningen af IHCS er optimal. 5. Husejeren lukker vinduet. UC22: Tænde for lys (er tilsvarende UC14 simplificeret). Primary Actor: Bevægelse. Stakeholders and Interests: Husejeren samt øvrige personer med adgang til huset: Ønsker at øge komforten. Preconditions: IHCS er sat op og startet. Bevægelses- og lys-sensorerer er monteret. Lamper er tilsluttet. Success Guarantee (Postconditions): Lyset tændes som ønsket. Trigger: Bevægelses-sensor aktiveres. Basic Flow: 1. En bevægelses-sensor aktiveres og denne sender signal til IHCS. 2. I systemet sættes sensoren i "Bevægelse registreret" mode. 3. Sensoren notificerer registrerede bevægelses-lyttere at bevægelse forekom (bevægelses-lyttere svarer i denne Use Case kun til et rum, men andre objekter så som alarm etc. vil komme til). 4. Rummet finder lamper, der skal tændes ved bevægelse (hvis det ikke er for lyst). 5. Lyset tændes. UC23 er ikke implementeret rigtigt. Funktionen er kun implementeret i simuleringen, hvor tændte lamper slukkes efter 5 sekunder.

OOPJ-E-1 F2003 Side 8 af 38 Herefter skal der nu udarbejdes aktivitetsdiagrammer, der er OOAD s flowcharts, som viser aktiviteternes hændelsesforløb og billedeliggører vores Use Cases. Disse vises heller ikke i denne rapport. Testovervejelser Afprøvning af programmet er inspireret af testmetoden "test-first programming", der anvendes i Extreme Programming (XP). Og da hver iteration i UP i princippet indeholder en "mini V-model", har de gode gamle test-dyder fra V-modellen, der jo også indgyder til at teste fra starten, selvfølgelig også været en kilde til inspiration. Fremgangsmåden ved testmetoden "test-first programming" er først at skrive lidt testkode, dernæst lidt kode der skal testes. Når koden er succesfuldt testet gentages forløbet. Ovenstående er gennemført vha. klassen SystemTester.java som kan ses i Bilag 1. Outputtet af testen kan ses i Bilag 2. Hvordan opgaven tænkes løst Før det egentlige designarbejde påbegyndes, er det formålstjenstligt at få afklaret input og output system events relateret til "Basic Flow" scenariet i den Use Case, der arbejdes med. Det letter overgangen fra analysearbejdet til designarbejdet. Hertil anvendes et System Sekvens diagram, som konkretiserer operationerne, der relaterer sig til Basic Flow scenariet. Senere i design-forløbet laves "rigtige" sekvensdiagrammer, hvor det vil fremgå hvilke objekter i systemet, der får ansvaret for at udføre operationerne. Domain Model Designarbejdet påbegyndes ved at udarbejde en Domain Model. Da vi jo arbejder i henhold til UP er det vigtigt ikke at kaste sig ud i og lave en komplet model på nuværende stadie. I efterfølgende iterationer udbygges modellen til også at afspejle disse. Domain modellen repræsenterer konceptuelle klasser (ting, begreber fra den virkelige verden) og ikke software klasser. Et eksempel på en software klasse kan f.eks. være en interface klasse til en database. For at finde de konceptuelle klasser i problem-domænet er Use Cases gennemgået for navneord og ydermere er der anvendt en "Conceptual Class Category List". Kandidater, der kan repræsenteres vha. simple datatyper som f.eks. int, er ikke konceptuelle klasser, men nærmere attributter. Andre kandidater som eksempelvis mobil.nr. og e-mailadresse der repræsenteres vha. en lidt mere kompleks datatype nemlig String, betragtes stadig som attributter. Flg. liste repræsenterer de konceptuelle klasser, der relaterer sig til iterationerne gennemløbet indtil nu: Hus Lampe Person Rum Bevægelses-sensor Dør Lys-sensor Vindue Alarm Varmesystem

OOPJ-E-1 F2003 Side 9 af 38 Herefter skal vi, uden at anvende ret meget tid, identificere associationer mellem de konceptuelle klasser. Hertil anvendes en "Common Associations List": Category A is physical part of B* A is logical part of B* A is physically contained in/on B* A is logically contained in B* A is a description for B A is a line item of a transaction or report B A is known/logged/recorded/reported/captured in B* A is a member of B A is an organizational subunit of B A uses or manages B A communicates with B A is related to a transaction B A is a transaction related to another transaction B A is next to B A is owned by B A is an event related to B Candidates Rum - Hus Dør - Rum Vindue - Rum Varmesystem - Hus Alarm - Hus Bevægelses-sensor - Rum Lys-sensor - Rum Lampe - Rum Person - Hus Kategorier markeret med * er af speciel vigtighed i Domain Model henseende.

OOPJ-E-1 F2003 Side 10 af 38 Slutteligt er attributter identificeret for de enkelte klasser i Domain modellen, der herefter, på nuværende tidspunkt, ser således ud: Figur 1: Domain Model Det er nærliggende at lave i hvert fald to nye generelle (abstrakte) klasser: Aabning som Doer og Vindue kunne nedarve fra og Sensor som BevaegelsesSensor og LysSensor kunne nedarve fra. Detaljeret design Efter alle de forudgående undersøgelser føler jeg mig godt rustet til det mere detaljerede designarbejde og kaster mig over udarbejdelse af klassediagram og sekvensdiagrammer, hvor kun klassediagrammet (se Bilag 4) er medtaget i denne rapport. Beskrivelse af hvordan programmet virker Ved distribution af programmet leveres et eksempel på en plantegning samt en eksekverbar jar-fil (indeholder både class- og java-filer) og startes eksempelvis fra kommandolinien ved at skrive: java -jar IHCS.jar

OOPJ-E-1 F2003 Side 11 af 38 Filen IHCS.jar er gjort eksekverbar ved at lægge en manifest-fil med i jar-filen. I manifestfilen står der hvilken klasse (miracon.ihcs.systemtester) som indeholder main()-metoden. Jeg har valgt at placere klasserne i forskellige pakker således at klasser med beslægtet funktionalitet er placeret i samme pakke. Pakkehierarkiet er som følger: miracon.ihcs miracon.ihcs.dbpackage miracon.ihcs.huspackage miracon.ihcs.installationerpackage miracon.ihcs.personpackage miracon.ihcs.uipackage (SystemTester) (TestDb og Sequences) (Hus, Rum, Aabning, Hoveddoer, Vindue etc.) (VarmeSystem, Alarm, Sensor, Lampe etc.) (Person) (SimulerApplet, SimulerFrame, LukVindue etc.) Ovenstående er også afbildet på klassediagrammet (se Bilag 4). I kildeteksten (se Bilag 3) for programmet er der undervejs kommentarer med henvisninger til de ovenfor beskrevne Use Cases. På den måde anskueliggøres det hvor i koden de funktionelle krav implementeres. Når programmet startes slettes eventuelt eksisterende filer, skabt vha. Java's mekanisme kaldet serialisering, indeholdende opsætningen af IHCS. Dette vil selvfølgelig ikke ske i den endelige version af programmet. Herefter instantieres testdatabasen (se kommentarer i SystemTester.java og TestDb.java for flere detaljer) således, at vi nemt kan gemme ændringer i opsætningen af IHCS. Samtidig instantieres klassen Sequences, der benyttes ved tildeling af et unikt personid til hver person, der oprettes i systemet. Det unikke personid hentes vha. metoden getnextpersonid() som er placeret i klassen TestDb. Herefter oprettes testpersoner. Disse smides i en Vector som gemmes i filen personer.ser. Bemærk at der anvendes forskellige konstruktører. Konsruktøren i klassen Person er overloaded (parameterlisterne er forskellige). Bemærk også at data i klassen Person er indkapslede (beskyttede). Det er opnået ved at erklære variablerne private og herefter oprette såkaldte get- og set-metoder. Opstår der fejl skrives fejlmeddelelse til standard output, hvilket vil sige det vindue hvorfra programmet blev startet. Ligeledes i dette vindue vises nu de oprettede testpersoner således, at den liste kan sammenlignes med en senere liste, der vises efter sletning af en person; oprettelse af en ny og endelig opdatering af en eksisterende. Herefter fødes systemet med oplysninger om huset, der skal styres af IHCS. Også huset lægges i en Vector (på sigt skal systemet måske kunne styre flere huse), der senere gemmes i filen huse.ser. Også i klassen Hus er data indkapslede. Som det også fremgår af klassediagrammet er der en "har-relation" mellem Hus og Rum: Et Hus har 1 til * (flere) Rum. Denne relation betegnes også som en "Composite Aggregation"; derfor den fyldte "diamant" i den ene ende af relationen. Relationen er implementeret vha. Vectoren vrum i klassen Hus, der så også er blevet tildelt ansvaret for at addere, fjerne og oplyse om rum. Dette er implementeret ved oprettelse af metoderne addrum, removerum og getrum. Netop addrum anvendes nu til at oprette rum og knytte dem til huset. Metoden removerum testes også. Dernæst oprettes vinduer, døre, bevægelses- og lys-sensorer samt lamper. Ansvaret for dette er tildelt til klassen Rum, der har en "har-relation" til disse objekter. Vinduerne og dørene, der er specialiseringer af den abstrakte klasse Aabning, adderes vha. metoden addaabning. Udover denne metode har Rum også metoderne removeaabning og getaabninger. Bevægelses-sensorer adderes med metoden addbevaegelsessensor. I den metode instantieres BevaegelsesSensor med bla. en reference til rummet som parameter.

OOPJ-E-1 F2003 Side 12 af 38 Rummet sender altså en reference til sig selv og det i sin egenskab som "bevægelses-lytter". Dette er et tydeligt eksempel på polymorfi (mere om det senere). Rummet er i stand til at opføre sig som en "bevægelses-lytter", da klassen implementer interfacet BevaegelsesListener. Bevægelses-sensoren gør så det i sin konstruktør, at den registrerer lytteren ved at kalde metoden addbevaegelseslistener. Lys-sensorer adderes vha. metoden addlyssensor og lamper adderes vha. metoden addlampe. Ved oprettelsen af en lampe kan det bestemmes om den skal tænde ved bevægelse eller ej. Dette kan selvfølgelig ændres senere hvis husejeren måtte ønske det. Så er vi ved at være ved vejs ende mht. opsætningen af IHCS i nuværende version. Vi mangler bare at tilknytte alle personer til huset. Det sker ved at kalde metoden addperson på det objekt (Hus) som variablen vhus1 peger på. Udover addperson indeholder Hus også metoderne removeperson og getpersoner. Metoden removeperson testes ved at lade som at en person fraflytter. Endeligt gemmes, som også nævnt tidligere, Vectoren indeholdende Hus(e) med alle relaterede objekter i filen huse.ser. Hvad objektet Hus faktisk indeholder vises til sidst ved at udskrive objektet. Huset's tostring metode, der er nedarvet fra Object men her tilsidesat, kaldes implicit. Nu da systemets opsætning er klar/ændret kan UC19 og 22 implementeres/testes. Med muligheden for at køre simuleringen via Internettet i baghovedet, blev dette til at starte med forsøgt vha. klassen SimulerApplet, der nedarver fra Applet. Men jeg kom hurtigt ud i nogle sikkerhedsmæssige problemer. Se følgende output fra Java-konsol vinduet i Internet Explorer: com.ms.security.securityexceptionex[miracon/ihcs/uipackage/simulerapplet.jbinit]: cannot access file huse.ser at com/ms/security/permissions/fileiopermission.check... Appletten kunne ikke initialiseres. Kontakt venligst leverandøren af IHCS og oplys nedenstående fejl: com.ms.security.securityexceptionex[miracon/ihcs/uipackage/simulerapplet.jbinit]: cannot access file huse.ser... Dette blev forsøgt omgået ved at generere html-fil inkl. parametre til appletten dynamisk, men det viste sig hurtigt ikke at være en farbar vej. Jeg valgte herefter at bruge en Frame (klassen SimulerFrame) og ved nærmere eftertanke synes jeg det er ok, at simuleringen ikke kan køre via Internettet. Under testen af appletten benyttedes muligheden for automatisk at starte brugerens standardbrowser med html-filen som argument. SimulerFrame instantieres med Vectoren vhuse som parameter; størrelsen sættes og vinduet gøres synligt på skærmen. JDeveloper generer kode således at brugeren kan lukke vinduet ved at aktivere menupunktet File, Exit. Men jeg har tilføjet muligheden for at lukke vinduet ved at trykke på på krydset i øverste højre hjørne eller taste Alt-F4 (Windows). Implementeret ved flg. linie: this.addwindowlistener(new LukVindue()); Klassen LukVindue er i stand til at opføre sig som WindowListener, ikke ved at implementere interfacet, men ved at nedarve fra WindowAdapter, der implementerer interfacet. På den måde behøver vi kun at tilsidesætte den metode vi har brug for (windowclosing) frem for at skulle implementere alle, af interfacet, krævede metoder. Herefter sættes Framen (implements MouseMotionListener) til at lytte efter musebevægelser. Musebevægelserne anvendes til at simulere bevægelse i huset.

OOPJ-E-1 F2003 Side 13 af 38 For at kunne simulere både når det er mørkt og når det er lyst startes en tråd under initialiseringen af Framen. Tråden sørger for at der skiftes mellem lys og mørke hvert halve minut og startes vha. flg. linie: new Thread(new SkiftMoerkeLys(vRum, this)).start(); Klassen SkiftMoerkeLys kan køre i en tråd da den implementerer interfacet java.lang.runnable. Bemærk at Framen overfører en reference til sig selv således at SkiftMoerkeLys kan gentegne Framen. Selve skiftet mellem mørkt og lyst sker ved at manipulere med værdien for variablen antalluxligenu i alle instanser af LysSensor. Efter initialiseringen kaldes paint()-metoden automatisk og hus samt installationer tegnes (bemærk at de forskellige installationer har ansvaret for at tegne sig selv): Figur 2: Simuler IHCS opsætning (2 lamper tændt) Sensorer og rektanglet, der repræsenterer dem, gemmes i en Hashtable, der efterfølgende gennemløbes i metoden mousemoved. Til sidst i paint()-metoden startes en tråd, der sørger for at slukke lamper, der har været tændt i 5 sekunder. Det sker vha. flg. linie: new Thread(new SlukLamper(vRum, 5000, this)).start(); Klassen SlukLamper implementerer interfacet Runnable og kalder metoden settaendt med parameteren false på de instanser af Lampe, hvor gettaendttid() er større end 5 sekunder.

OOPJ-E-1 F2003 Side 14 af 38 Når brugeren simulerer bevægelse ved at bevæge musecursoren kaldes metoden mousemoved. Ovennævnte Hashtable gennemløbes ved at bruge en Enumeration (opremsning). Er musecursoren placeret indenfor et rektangel, der repræsenterer en sensor, og er dette en bevægelses-sensor, kaldes metoden setbevaegelse med parameteren true på instansen af bevægelses-sensoren. Det medfører kald af metoden notificerbevaegelseforekom(), som også er placeret i BevaegelsesSensor. Et event af typen BevaegelsesEvent oprettes med en reference til bevægelses-sensoren selv, således at vi altid kan se hvilket objekt der initierede eventet. Og så er vi tilbage til det med polymorfien. Nu sendes BevaegelsesEvent'et nemlig til de registrerede "bevægelses-lyttere" som i teorien kan være objekter af alle typer blot de implementerer interfacet BevaegelsesListener. Event'et sendes vha. flg. linie: ((BevaegelsesListener)regBevaegelsesLyttere.elementAt(i)).bevaegelseForekom(be); Klassen Rum opfylder sin pligt og implererer den krævede metode bevaegelseforekom. Her findes de lamper, der skal tændes ved bevægelse (hvis det ikke er for lyst). Skal lampen tændes kaldes metoden settaendt med parameteren true på instansen af den pågældende lampe. Det medfører kald af metoden settaendttid således, at vi kan holde styr på de lamper, der skal slukkes efter 5 sekunder. Slutteligt kaldes repaint() således, at vinduet afspejler objekternes tilstand. Lever programmet op til forventningerne Jeg synes at man med rimelighed kan sige, at de funktionelle krav, som der er arbejdet med indtil nu, er/kan blive opfyldt. Endvidere føler jeg mig overbevist om at systemet, når alle iterationer er gennemført, kan leve op til visionen for programmet.

OOPJ-E-1 F2003 Side 15 af 38 Bilag Bilag 1: SystemTester.java package miracon.ihcs; import miracon.ihcs.dbpackage.*; import miracon.ihcs.huspackage.*; import miracon.ihcs.personpackage.*; import miracon.ihcs.uipackage.*; import java.awt.*; import java.io.*; import java.util.*; public class SystemTester public static void main(string[] args) // Oplysninger omkring systemets opsætning gemmes i filer. // Ved start op denne test ønskes det at starte fra scratch. // Filer indeholdende serialiserede objekter slettes. File workdir = new File("."); // Opret et array af filer. File[] fil = workdir.listfiles(); // Gennemløb array. for (int i = 0; i < fil.length; i++) if (fil[i].isfile() && fil[i].getname().tolowercase().endswith(".ser")) fil[i].delete(); // Instantier testdatabasen. TestDb kan kun instantieres en gang (Singleton). // Metoden getinstance er static (klassemetode), hvorfor den kan kaldes selvom // der endnu ikke findes en instans af TestDb. TestDb db = TestDb.getInstance(); // UC1, punkt 1: Husejeren starter skærmbilledet "Registrer personoplysninger" (ikke // implementeret). // Hent testpersoner (UC1, punkt 2: Systemet søger efter allerede registrede personer). Vector vpersoner = new Vector(); try vpersoner = (Vector) db.hent("personer.ser"); catch (Exception exhent) // Testpersoner kunne ikke findes. Opret testpersoner. vpersoner.addelement(new Person(db.getNextPersonId(), "Kim Damgaard", "+4551901962", "kim.damgaard@mail.dk", "kd.jpg", 1234)); vpersoner.addelement(new Person(db.getNextPersonId(), "Janette Damgaard", "+4536451234", "jd@mail.dk", "jd.jpg", 2345)); vpersoner.addelement(new Person(db.getNextPersonId(), "Marc Damgaard", "+4536451245", "md@mail.dk", "md.jpg", "md_finger.jpg")); // Gem testpersoner. try db.gem(vpersoner,"personer.ser"); catch (Exception exgem) System.out.println("Systemfejl. Personer kan ikke gemmes. Kontakt venligst "+ "leverandøren af IHCS og oplys nedenstående fejl:"); exgem.printstacktrace(); // Vis testpersoner (UC1, punkt 3: Systemet lister de oprettede personer). System.out.println("\nOprettede personer:\n"+ "-------------------"); for (int i = 0; i < vpersoner.size(); i++) System.out.println((Person)vPersoner.elementAt(i)); // Slet testperson og opret en ny vpersoner.removeelementat(1); vpersoner.addelement(new Person(db.getNextPersonId(), "Simone Damgaard", null, "sd@mail.dk", "sd.jpg", "sd_finger.jpg")); // Opdater personid 1 (UC1, punkt 4: Husejeren markerer den person, hvor oplysningerne // skal opdateres.) for (int i = 0; i < vpersoner.size(); i++) if (((Person)vPersoner.elementAt(i)).getPersonId() == 1) // UC1, punkt 5: Husejeren opdaterer relevante felter.

OOPJ-E-1 F2003 Side 16 af 38 ((Person)vPersoner.elementAt(i)).setEMailAdr("kd@mail.dk"); // UC1, punkt 6: Husejeren trykker på "Gem". // UC1, punkt 7: Systemet gemmer personoplysningerne. // Gem og hent testpersoner. try db.gem(vpersoner,"personer.ser"); vpersoner = (Vector) db.hent("personer.ser"); // Vis testpersoner igen. System.out.println("Personer efter sletning af en, oprettelse af en ny og opdat. af en "+ "eksist.:\n"+ "---------------------------------------------------------------------------"); for (int i = 0; i < vpersoner.size(); i++) System.out.println((Person)vPersoner.elementAt(i)); catch (Exception ex) System.out.println("Person-oplysninger kunne ikke gemmes/hentes. Kontakt venligst "+ "leverandøren af IHCS og oplys nedenstående fejl:"); ex.printstacktrace(); // UC3, punkt 1: Husejeren starter skærmbilledet "Registrere husoplysninger" (ikke // implementeret). // Hent husoplysninger (UC3, punkt 2: Systemet søger efter husoplysninger). // Til at starte med opererer vi kun med et hus. På sigt skal systemet kunne styre flere // huse/bygninger; derfor bruges en Vector. Vector vhuse = new Vector(); Vector vrum = new Vector(); try vhuse = (Vector) db.hent("huse.ser"); catch (Exception exhent) // Husoplysninger kunne ikke findes (UC3, punkt 3: Systemet konstaterer at der ikke // findes oplysninger). // Opret hus (UC3, punkt 4: Husejeren udfylder felterne). Hus vhus1 = new Hus("Valbo Alle","16","2665","Vallensbæk Strand","plantegning.gif"); // UC4, punkt 1: Husejeren starter skærmbilledet "Registrere rum" (ikke implementeret). // UC4, punkt 2: Systemet søger efter rum. if (vhus1.getrum().size() == 0) // UC4, punkt 3: Systemet konstaterer at der ikke findes oplysninger. // Opret rum i huset (UC4, punkt 4: Husejeren udfylder felterne). vhus1.addrum("bryggers",330,10,160,182); vhus1.addrum("gang",330,192,(3*160),91); vhus1.addrum("køkken",170,10,160,182); vhus1.addrum("spisestue",10,10,160,182); vhus1.addrum("stue",10,192,320,(182+91)); vhus1.addrum("kontor",330,(192+91),160,182); vhus1.addrum("børneværelse1",(330+160),(192+91),160,182); vhus1.addrum("børneværelse2",(330+160*2),(192+91),160,182); vhus1.addrum("soveværelse",650,10,160,182); vhus1.addrum("badeværelse1",490,10,160,91); vhus1.addrum("badeværelse2",490,101,160,91); vhus1.addrum("badeværelse3",10,10,100,100); // Vi prøver også lige at fjerne et rum (Badeværelse3). vrum = vhus1.getrum(); for (int i = 0; i < vrum.size(); i++) if (((Rum)vRum.elementAt(i)).getBetegnelse().equals("Badeværelse3")) vhus1.removerum((rum)vrum.elementat(i)); // UC5, punkt 1: Husejeren starter skærmbilledet "Registrere vinduer og døre" (ikke // implementeret). // UC7 og 8, punkt 1: Husejeren starter skærmbilledet "Registrere bevægelses- og // lys-sensorer" (ikke implementeret). // UC14, punkt 1: Husejeren starter skærmbilledet "Registrere lamper" (ikke // implementeret). for (int i = 0; i < vrum.size(); i++) // UC5, 7, 8 og 14, punkt 2: Systemet præsenterer rummene og husejeren udvælger et. if (((Rum)vRum.elementAt(i)).getBetegnelse().equals("Bryggers")) // UC5, punkt 3: Husejeren tilføjer de nødvendige vinduer/døre (mulige typer er // foruddefineret i systemet). ((Rum)vRum.elementAt(i)).addAabning("Bryggersdør"); // UC7 og 8, punkt 3: Husejeren tilføjer bevægelses- og/eller lys-sensor. // Sensoren registrerer rummet som lytter, hvilket kan lade sig gøre da Rum // implementerer interfacet BevaegelsesListener. På "objekt-sprog" kan man sige at // rummet "ACTS AS A" BevaegelsesListener. ((Rum)vRum.elementAt(i)).addBevaegelsesSensor(10000);

OOPJ-E-1 F2003 Side 17 af 38 ((Rum)vRum.elementAt(i)).addLysSensor(8000); // UC14, punkt 3: Husejeren tilføjer lampe. ((Rum)vRum.elementAt(i)).addLampe(true); if (((Rum)vRum.elementAt(i)).getBetegnelse().equals("Gang")) ((Rum)vRum.elementAt(i)).addAabning("Hoveddør"); ((Rum)vRum.elementAt(i)).addBevaegelsesSensor(8000); ((Rum)vRum.elementAt(i)).addLysSensor(9000); ((Rum)vRum.elementAt(i)).addLampe(true); ((Rum)vRum.elementAt(i)).addLampe(true); ((Rum)vRum.elementAt(i)).addLampe(false); if (((Rum)vRum.elementAt(i)).getBetegnelse().equals("Spisestue") ((Rum)vRum.elementAt(i)).getBetegnelse().equals("Stue")) ((Rum)vRum.elementAt(i)).addAabning("Terrassedør"); if (((Rum)vRum.elementAt(i)).getBetegnelse().equals("Køkken") ((Rum)vRum.elementAt(i)).getBetegnelse().equals("Spisestue") ((Rum)vRum.elementAt(i)).getBetegnelse().equals("Stue") ((Rum)vRum.elementAt(i)).getBetegnelse().equals("Kontor") ((Rum)vRum.elementAt(i)).getBetegnelse().equals("Børneværelse1") ((Rum)vRum.elementAt(i)).getBetegnelse().equals("Børneværelse2") ((Rum)vRum.elementAt(i)).getBetegnelse().equals("Soveværelse") ((Rum)vRum.elementAt(i)).getBetegnelse().equals("Badeværelse1")) ((Rum)vRum.elementAt(i)).addAabning("Vindue"); ((Rum)vRum.elementAt(i)).addLampe(false); if (((Rum)vRum.elementAt(i)).getBetegnelse().equals("Soveværelse")) ((Rum)vRum.elementAt(i)).addAabning("Tagvindue"); // Tilknyt alle personer til hus. for (int i = 0; i < vpersoner.size(); i++) vhus1.addperson((person)vpersoner.elementat(i)); // En person fraflytter. vhus1.removeperson((person)vpersoner.elementat(vpersoner.size()-1)); // UC3, 4 og 5, punkt 5 samt UC7, 8 og 14, punkt 4: Husejeren trykker på "Gem". // UC3, 4 og 5, punkt 6 samt UC7, 8 og 14, punkt 5: Systemet gemmer oplysningerne. // Gem hus inkl. tilknyttede objekter. vhuse.addelement(vhus1); try db.gem(vhuse,"huse.ser"); catch (Exception exgem) System.out.println("Hus-oplysninger kunne ikke gemmes. Kontakt venligst leverandøren "+ "af IHCS og oplys nedenstående fejl:"); exgem.printstacktrace(); // Vis hus inkl. tilknyttede objekter. for (int i = 0; i < vhuse.size(); i++) System.out.println((Hus)vHuse.elementAt(i)); // Forsøg på implementering af UC19 vha. en Applet. Blev opgivet pga. omstændigheder omtalt // i rapporten. // Html-fil med applet-tag genereres dynamisk. try PrintWriter hg = new PrintWriter(new FileWriter("simuler.html")); hg.println("<html><head><title>ihcs</title></head><body><h2>simuler IHCS opsætning</h2>"); hg.println("<br><applet CODE=\"miracon.ihcs.UiPackage.SimulerApplet\" CODEBASE=\".\" "+ "ARCHIVE=\"IHCS.jar\" HEIGHT=\"600\" WIDTH=\"820\" ALIGN=\"bottom\">"); hg.println("<param name=\"phuse\" value=\"huse.ser\">"); hg.println("denne browser understøtter ikke Applets.</APPLET></BODY></HTML>"); hg.close(); catch (IOException ex) System.out.println("Kan ikke generere html-fil. Kontakt venligst leverandøren af IHCS "+ "og oplys nedenstående fejl:"); ex.printstacktrace(); // Start brugerens standardbrowser. Virker kun i Windows. // Kilde: www.eksperten.dk try String command = "rundll32 url.dll,fileprotocolhandler simuler.html"; Runtime.getRuntime().exec(command);

OOPJ-E-1 F2003 Side 18 af 38 catch (java.io.ioexception e) System.out.println("Kan ikke starte browser. Vær opmærksom på at dette kun virker i "+ "Windows."); e.printstacktrace(); // UC19, punkt 1: Husejeren vælger hus, der skal simuleres. // UC19, punkt 2: Husejeren starter skærmbilledet "Simuler IHCS opsætning". SimulerFrame vindue = new SimulerFrame(vHuse); vindue.setsize(new Dimension(830,600)); vindue.setvisible(true); // end main // end class SystemTester

OOPJ-E-1 F2003 Side 19 af 38 Bilag 2: Output ved kørsel af klassen SystemTester Oprettede personer: ------------------- Person id : 1 Navn : Kim Damgaard Mobilnr. : +4551901962 E-mail : kim.damgaard@mail.dk Billede : kd.jpg Adg.kode : 1234 Fingeraftryk: null Person id : 2 Navn : Janette Damgaard Mobilnr. : +4536451234 E-mail : jd@mail.dk Billede : jd.jpg Adg.kode : 2345 Fingeraftryk: null Person id : 3 Navn : Marc Damgaard Mobilnr. : +4536451245 E-mail : md@mail.dk Billede : md.jpg Adg.kode : 0 Fingeraftryk: md_finger.jpg Personer efter sletning af en, oprettelse af en ny og opdat. af en eksist.: --------------------------------------------------------------------------- Person id : 1 Navn : Kim Damgaard Mobilnr. : +4551901962 E-mail : kd@mail.dk Billede : kd.jpg Adg.kode : 1234 Fingeraftryk: null Person id : 3 Navn : Marc Damgaard Mobilnr. : +4536451245 E-mail : md@mail.dk Billede : md.jpg Adg.kode : 0 Fingeraftryk: md_finger.jpg Person id : 4 Navn : Simone Damgaard Mobilnr. : null E-mail : sd@mail.dk Billede : sd.jpg Adg.kode : 0 Fingeraftryk: sd_finger.jpg Husoplysninger: --------------- Adresse : Valbo Alle 16 2665 Vallensbæk Strand Plantegning : plantegning.gif Rum : ------------- Bryggers Udvendige åbninger: Bryggersdør Lamper: Lampe tændes ved bevægelse Gang Udvendige åbninger: Hoveddør Lamper: Lampe tændes ved bevægelse, Lampe tændes ved bevægelse, Lampe tændes ikke ved bevægelse Køkken Udvendige åbninger: Vindue Lamper: Lampe tændes ikke ved bevægelse Spisestue Udvendige åbninger: Terrassedør, Vindue Lamper: Lampe tændes ikke ved bevægelse Stue Udvendige åbninger: Terrassedør, Vindue Lamper: Lampe tændes ikke ved bevægelse

OOPJ-E-1 F2003 Side 20 af 38 Kontor Udvendige åbninger: Vindue Lamper: Lampe tændes ikke ved bevægelse Børneværelse1 Udvendige åbninger: Vindue Lamper: Lampe tændes ikke ved bevægelse Børneværelse2 Udvendige åbninger: Vindue Lamper: Lampe tændes ikke ved bevægelse Soveværelse Udvendige åbninger: Vindue, Tagvindue Lamper: Lampe tændes ikke ved bevægelse Badeværelse1 Udvendige åbninger: Vindue Lamper: Lampe tændes ikke ved bevægelse Badeværelse2 Udvendige åbninger: Ingen Lamper: Ingen Brugere : ------------- Person id : 1 Navn : Kim Damgaard Mobilnr. : +4551901962 E-mail : kd@mail.dk Billede : kd.jpg Adg.kode : 1234 Fingeraftryk: null Person id : 3 Navn : Marc Damgaard Mobilnr. : +4536451245 E-mail : md@mail.dk Billede : md.jpg Adg.kode : 0 Fingeraftryk: md_finger.jpg