Project was done as a semester teamwork at Object-oriented design and Modeling CTU course.
Present project simulates life in smart home. Residents using devices on their needs and living their happiest life.
- Dynamic weather changes based on real data
- Real existing media content (videos, songs, games)
- Finest adjustment of the room's ecosystem through a control panel
- Random event generation: from device malfunctions to complete shutdowns
- An astonishing variety of devices
- Rich diversity of people's functionality
- Detailed and visual reports on ongoing activities
- Choose existing configuration or create a new one based on tutorial.
- Set proper simulation settings.
- Run
main
function.
Simulation.json
"config" : "1" |
Current configuration to load (name of folder) |
"duration" : 30 |
Simulation duration (in days) |
Configuration folder should exist in config
directory and have Home.json
, Creature.json
, Device.json
.
Duration should be integer non-negative value.
Home.json
"HOME" : [1, 2] |
Floors in home |
"FLOOR" : [[1, 2], [3, 4]] |
Rooms at floor (each floor should have it own pair of brackets) |
"ROOM" : ["KITCHEN", "HALL", "TOILET", "BEDROOM"] |
List of rooms (types) |
Numbers are IDs (integer) and should be unique for floors and rooms. They are connected with values in proper array (1-based).
Room types should match these values.
Device.json
"FRIDGE" : [1, 2, 3] |
Device type and its instances |
Numbers are room IDs (integer).
Device types should match these values.
Creature.json
"name" : "Jirka" |
Person's name |
"gender" : "MALE" |
Person's gender |
"status" : "ADULT" |
Person's family status |
Gender should match these values.
Family status should match these values.
"name" : "Garfield" |
Pet's name |
"gender" : "CAT" |
Pet's type |
Pet type should match these values.
Content.json
"author" : "MC Adolfeen" |
Author of song |
"album" : "Je mi to jedno" |
Name of album |
"name" : "Corona Firus" |
Name of song |
"genre" : "HIP_HOP" |
Song genre |
"duration" : 3 |
Duration (in minutes) |
Duration should be integer non-negative value.
Song genre should match these values.
"name" : "Baby Shark Dance" |
Name of video |
"description" : "Baby shark, doo doo doo doo doo doo." |
Short video description |
"platform" : "YOUTUBE" |
Video platform (channel, streaming service, ...) |
"duration" : 2 |
Duration (in minutes) |
Duration should be integer non-negative value.
Video platform should match these values.
"name" : "Mafia: The City of Lost Heaven" |
Name of game |
"description" : "Classic Czech game about italian mafia in USA." |
Short game description |
"genre" : "ACTION" |
Game genre |
Game genre should match these values.
RoomConfiguration.json
"name" : "Bathhouse" |
Configuration name |
"temperature" : 90 |
Set temperature (in ºC) |
"humidity" : 85 |
Set humidity (in %) |
"brightness" : 20 |
Set brightness (in %) |
"color" : [255, 253, 141] |
Set color of light |
Temperature can be negative and float.
Humidity should be in range 0-100. Can be float.
Brightness should be in range 0-100. Can be float.
Color should have three integers in range 0-255 representing RED
, GREEN
, BLUE
components.
Weather.json
"temperature" : [[-10.2, -11.2, ...], ...] |
Temperature map |
"humidity" : [[69.3, 68.1, ...], ...] |
Humidity map |
"brightness" : [[16.8, 16.9, ...], ...] |
Brightness map |
Temperature can be negative and float.
Humidity should be in range 0-100. Can be float.
Brightness should be in range 0-100. Can be float.
Each map should contain 12 arrays of 24 values representing temperature/humidity/brightness in concrete hour of concrete month (starting from 00:00 and January).
Configuration.txt
House Configuration ReportStores all configuration information about home hierarchy and its residents.
Home <- Information about home Floor_1 <- First floor Room_1 (Hall) <- First room TV_1 <- Device Light_1 <- Device Floor_2 <- Second floor Room_2 (Kitchen) <- Second room Microwave_1 <- Device Light_2 <- Device Room_3 (Toilet) <- Third room WC_1 <- Device Residents <- Information about residents Bob (Male, Adult) <- Resident Bark (Dog) <- Resident
Consumption.tsv
Consumption ReportStores all information about every device consumption during simulation in easy-readable table form.
All information can be sorted, summed and filtered by auxiliary application
Date
Device
Electricity
Water
Gas
Money
Simulation day Device_ID Consumed electricity Consumed water Consumed gas Spent money
Activity.txt
Activity and Usage ReportStores all daily performed activity of every person during simulation.
12/01/2024 <- Simulation date Bob (Male, Adult) <- Person Activity <- Information about activity 20:25 - Go to Room_2 (Shower) <- Action 20:26 - Put clothes to Washer_1 <- Action 20:26 - Start Washer_1 with 'Washer Intensive program' <- Action 21:26 - Go to Room_3 (Toilet) <- Action 21:27 - Use WC_1 <- Action Usage <- Information about usage Washer_1 - 2 <- Device usage WC_1 - 1 <- Device usage
Event.tsv
Event ReportStores all information about handled events during simulation in easy-readable table form.
All information can be sorted, summed and filtered by auxiliary application
Created
Solved
Type
Creator
Solver
Date, time of creation Date, time of solution Event type Device_ID Person name
F1
Main entities in the project are Street, Home, Room, Person, Pet, Device, Sensor.Entities we work with are house, window (+outside blinds), floor in the house, sensor, device (=appliance), person, car, bike, pet other than farm type, plus any other entities.
F2
Most of the devices have API functions that Person use to interact with them (eg.Each device in the house has an API to control it. Devices have a state that can be changed using the API to control it. Actions from the API are applicable according to the state of the device. Selected devices can also have content.
startWash()
in Dishwasher).Other devices do not provide API directly for human. Instead of this they use their sensors to be controlled. Person interacts with Control Panel to change parameters, which ones have an impact to devices through sensors.
Each device (with few exclusions) can be in one of different states at the moment. This state have impact on device consumption and allowed functions to use.
Some devices (eg. TV, CoffeeMachine, ...) have content (eg. current Video in TV; water, milk, coffee beans in CoffeeMachine and so on).
F3
State of the device impacts device consumption rate using state multiplier. This multiplier applies to default device rate.Appliances have their consumption in active state, idle state, off state.
F4
Every device is consumer and stores amount of consumed resource in Electricity/Water/Gas meters where can be easily taken from.Each device has an API to collect data about that device. We collect data about devices such as electricity, gas, water consumption and functionality (decreases linearly with time).
Those three classes have information about consumption of every existing device and have an ability to switch them altogether or by concrete room (changing resource availability in room) just as in real life.
F5
Persons and pets are interacting with devices using their API functions. It changes actual state of the device (such as device stateIndividual persons and animals can perform activities (actions) that have an effect on the device or another person.
ON
/OFF
/STANDBY
, occupancy and so on).
F6
Both people and devices can be only in one room at the moment, which is quite physically logic. When person is outside (doing sports, went for a walk etc.) he marked as notIndividual devices and persons are in the one room at any time (unless they are doing sports) and randomly generate events (an event can be important information or an alert).
atHome
, but remember the room he lastly was.Devices communicate with people using Event generation.
Events can have restricted visibility: for example person can see flood from washing machine only if stands in the same room. In other hand alert about fire is loud enough to be heard throughout home.
F7
Events are taken only by persons who can solve it. Solution (as well as reaction) strategy depends on concrete attributes (in our case gender and family status representing age).Events are picked up and handled by the appropriate person(s) or device(s).
Concrete event can be solved only by one person.
F8
House Configuration Report creates once simulation started.Reports generating
- HouseConfigurationReport:
All configuration data of the house maintaining the hierarchy - house -> floor -> room -> window -> blinds etc. (+ residents)
- EventReport:
Report where we group events by type, event source and event target (what entity handled the event)
- ActivityAndUsageReport:
Report of actions (activities) of each person and animal, how many times which person used which device.
- ConsumptionReport:
How much electricity, gas, water each appliance consumed. Including a finances.
At the end of every simulation day remained three reports are generated with all information about living in home this day.
Required reports are generating as text files.
- HouseConfigurationReport, ActivityAndUsageReport as
.txt
- ConsumptionReport, EventReport as
.tsv
F9
Devices can break, which is absolutely natural. It can happen by several reasons:When a device breaks, the house resident must examine the documentation for the device - find the warranty card, review the repair manual and take corrective action (e.g., do-it-yourself repair, purchase a new one, etc.).
1. Device is loosing its durability linearly with time
2. Device is in permanently use
3. Pets are able to damage devices
4. Electricity using device may catch fire
5. Device can simply randomly break with no reason
In all cases proper person would do something with it. Firstly he will check warranty card if device can be given to Service Center.
If not - following steps depend on solving strategy.
F10
All home residents have sequences of actions they can perform.The family is active and spends their leisure time in roughly the same proportion (50% using appliances in the house and 50% playing sports using bicycles or skis). When there is no free appliance or sports equipment, the person waits.
These include both walking outside and using devices. Ratios of using functions can be easily varied.
If person is trying to use device, which already
isOccupied
by other person, he is reasonly not able to do this.Visitor
(4 implementations)Element - Consumer
accept() =
accept()
Element A - ElectricityConsumer
Element B - WaterConsumer
Element C - GasConsumer
Visitor - Visitor
visit() =
visit()
Visit function controls Element type
ConcreteVisitor A - AddVisitor
visit(Element A) =
visit(ElectricityConsumer)
visit(Element B) =
visit(WaterConsumer)
visit(Element C) =
visit(GasConsumer)
Visitor feature - add consumer device to all places (Simulation + proper SupplySystem)
ConcreteVisitor B - DeleteVisitor
visit(Element A) =
visit(ElectricityConsumer)
visit(Element B) =
visit(WaterConsumer)
visit(Element C) =
visit(GasConsumer)
Visitor feature - delete consumer device from all places (Simulation + proper SupplySystem)
ConcreteVisitor C - ConsumeVisitor
visit(Element A) =
visit(ElectricityConsumer)
visit(Element B) =
visit(WaterConsumer)
visit(Element C) =
visit(GasConsumer)
Visitor feature - make device consumption and write it to proper SupplySystem
ConcreteVisitor D - EventVisitor
visit(Element A) =
visit(ElectricityConsumer)
visit(Element B) =
visit(WaterConsumer)
visit(Element C) =
visit(GasConsumer)
Visitor feature - creates disaster events (fire/flood/leak) for proper consumer
Memento
(1 implementation)Memento - RoomConfiguration
Originator - ControlPanel
save() =
saveConfiguration()
restore() =
loadConfiguration()
Caretaker - Person
hitSave() =
saveConfiguration()
hitUndo() =
loadConfiguration()
State - preferred temperature, humidity, brightness, and light color (fields in the ControlPanel).
State is saved in a static field in ControlPanel.
Prototype
(2 implementations)Prototype - Prototype
ConcretePrototype - RoomConfiguration
clone() =
copy()
Prototype - Prototype
ConcretePrototype - Device (+ all inheritors)
clone() =
clone()
Builder
(1 implementation)Client - Simulation
ConcreteBuilder - HomeBuilder
reset() =
reset()
getResult() =
getHome()
buildStepA() =
buildHome()
buildStepB() =
buildFloor()
buildStepC() =
buildRoom()
There is no need in the project for a Builder interface as long as there is only one type of Home creating.
We don't also need a Director class because this role is played by the home draft read from the configuration file.
AbstractFactory
(1 implementation)AbstractFactory - ReportFactory
createProduct() =
createReport()
ConcreteFactory1 - ConfigurationReportFactory
createProduct() =
createReport()
ConcreteFactory2 - ConsumptionReportFactory
createProduct() =
createReport()
ConcreteFactory3 - ActivityReportFactory
createProduct() =
createReport()
ConcreteFactory4 - EventReportFactory
createProduct() =
createReport()
AbstractProduct - Report
ConcreteProduct1 - HouseConfigurationReport
ConcreteProduct2 - ConsumptionReport
ConcreteProduct3 - ActivityAndUsageReport
ConcreteProduct4 - EventReport
Client - ReportCreator
someOperationA() =
createConfigurationReport()
someOperationB() =
createConsumptionReports()
someOperationC() =
createActivityReports()
someOperationD() =
createEventReports()
Singleton
(2 implementations)Singleton - Simulation
Client - SmartHome and so on
Singleton - Street
Client - Simulation and so on
Facade
(2 implementations)ClientA - Simulation
ClientB - HomeBuilder
ClientC - ControlPanel
ClientD - EntertainmentService
ClientE - Street
Facade - ConfigurationReader
readSimulationConfig()
- (A) readHomeConfig()
- (B) readDeviceConfig()
- (A) readCreatureConfig()
- (A) readRoomConfigurationConfig()
- (C) readContentConfig()
- (D) readWeatherConfig()
- (E) Facade provides working with JSON files. Inside it reads, parses them, and creates objects depending on configuration info or sets different parameters.
Client - Simulation
Facade - ReportCreator
createReports()
createConfigurationReport()
Facade provides reports creation. Inside it collects all necessary information, creates reports, and writes it into files.
SimpleFactory
(3 implementations)Client - ConfigurationReader
Factory - CreatureFactory
createPerson()
createPet()
Factory provides Creature creations. Hidden complexity is control of the validity of given parameters.
Client - ConfigurationReader
Factory - DeviceFactory
createDevice()
Factory provides Device creations. Hidden complexity is control of the validity of given parameters.
Client - ConfigurationReader
Factory - EntertainmentFactory
createSong()
createVideo()
createGame()
Factory provides Song, Video, Game creations. Hidden complexity is control of the validity of given parameters.
Strategy
(2 implementations)Strategy - EventThrowStrategy
ConcreteStrategyA - HomeThrowStrategy
ConcreteStrategyB - FloorThrowStrategy
ConcreteStrategyC - RoomThrowStrategy
execute()
= throwEvent()
Client - Device
Context - Event
doSomething()
= throwEvent()
setStrategy()
is missing because it is set in the constructor Strategy - Strategy
ConcreteStrategyA - ManStrategy
ConcreteStrategyB - WomanStrategy
ConcreteStrategyC - ChildStrategy
ConcreteStrategyD - DogStrategy
ConcreteStrategyE - CatStrategy
ConcreteStrategyF - SomePetStrategy
execute()
= react()
ClientA - Person
ClientB - Pet
Context - Creature
doSomething()
is used in Creature routine function setStrategy()
is missing because strategies are set in creatures' constructors TemplateMethod
(1 implementation)AbstractClass - Creature
templateMethod()
= routine()
_step1()
(abstract) = decreaseFullness()
_step2()
(abstract) = decreaseHunger()
_step3()
(abstract) = chooseActivity()
_step4()
(abstract) = reactMaxFullness()
_step5()
= reactMaxHunger()
ConcreteClass1 - Person
_step1()
= decreaseFullness()
_step2()
= decreaseHunger()
_step3()
= chooseActivity()
_step4()
= reactMaxFullness()
ConcreteClass2 - Pet
_step1()
= decreaseFullness()
_step2()
= decreaseHunger()
_step3()
= chooseActivity()
_step4()
= reactMaxFullness()
Observer
(1 implementation)Publisher - SupplySystem
_subscribers_
= consumedMap
_subscribe()
= addConsumer()
_unsubscribe()
= deleteConsumer()
_notifySubscribers()
= switchRoom()
SubscriberA - ElectricityConsumer
SubscriberB - WaterConsumer
SubscriberC - GasConsumer
ConcreteSubscriber - Device
_update()
= turnOn()
_update()
= turnOff()
Concrete subscribers are all devices (depends on what resource they consume).
State
(1 implementation)State - Weather
ConcreteStateA - NormalWeather
ConcreteStateB - SunnyWeather
ConcreteStateC - CloudyWeather
ConcreteStateD - RainyWeather
ConcreteStateE - WindyWeather
_doThis()
= applyWeather()
There is no need in
_setContext()
because context is Singleton.Context - Street
_changeState()
= setWeather()
There is no need in explicit
_doThis()
- context uses applyWeather()
and changeWeather()
of its state.
InitialState is random Weather.
Adapter
(1 implementation)Client - PriorityQueue
Service - Deque
Adapter - RankedQueue
In the project Creature is need to work with its sequences of future actions (called memory). Those sequences have different priorities (what should be done next). Also, implementation requires to have ability in iteration by action sequences. For this reason PriorityQueue is used (is easily iterable + can add elements respecting priorities).
Every element of memory should be specific action sequence.
That's why adapter was implemented to store those action sequences and its priority to let PriorityQueue work with it later.