Giter VIP home page Giter VIP logo

weatherdrobe's Introduction

WeatherDrobe

Purpose of this app

WeatherDrobe's purpose is to help in everyday situations in which we often don't have time to dress properly or check upcoming weather news. Did you ever have problem with time missing? This application has been created to sort it out. The Main Algorithm of WeatherDrobe will prepare for you few proposals of dressing, based on actual weather informations, whereby you will never again forget to take an umbrella ;)

All screenshots presented below do not represent the final state of the product. Appearance may change in the future.

Home Page

On the homepage, the user will be able to receive information such as suggested clothing, the current weather forecast, and by pressing the top banner, the hourly weather forecast. In addition, in the left column there are suggestions such as umbrella, wristwatch, etc. Do you like the look of this app? Check Graphic Attribution!

Outfit Creator - Temperature Outfit Creator - Temperature

Virtual Wardrobe

In the virtual wardrobe, users can browse their own collection, which is automatically downloaded from the Firebase server (Check Data Fetching). When you click on a piece of clothing, informations about it appears on the screen. In the future we are also planning a function of editing and deleting the created clothes.

Outfit Creator - Temperature Outfit Creator - Temperature

Outfit Creator

The following images represent the appearance of the Outfit Creator. The user can easily create new clothing by setting four attributes - template, color, temperature and additional weather conditions. After pressing the 'Save' button, the information of the newly created outfit is sent to the Firebase server. Check FireBase Data Sending for more detailed informations.

Outfit Creator - Temperature Outfit Creator - Temperature Outfit Creator - Temperature Outfit Creator - Temperature

Weather API

WeatherDrobe's weather informations are based on Open Weather Map API which allows to use a powerfull One Call API option with the following feedback data:

  • Current weather
  • Minute forecast for 1 hour
  • Hourly forecast for 48 hours
  • Daily forecast for 7 days
  • National weather alerts
  • Historical weather data for the previous 5 days
  • Current and forecast weat

Currently WeatherDrobe is using following data:

CurrentData({this.iconId, this.temperature, this.description, this.time});

  factory CurrentData.fromJson(dynamic json) {
    return CurrentData(
        iconId: json["weather"][0]["icon"],
        temperature: json["temp"].toDouble(),
        description: json["weather"][0]["description"],
        time: json["dt"]);
  }
HourlyForecast({this.iconId,this.temperature,this.description,this.propabilityOfPrecipitation,this.time});

  factory HourlyForecast.fromJson(Map<String, dynamic> json) {
    return HourlyForecast(
        iconId: json["weather"][0]["icon"],
        temperature: json["temp"].toDouble(),
        description: json["weather"][0]["description"],
        propabilityOfPrecipitation: json["pop"].toDouble(),
        time: json["dt"]);
  }

Firebase

WeatherDrobe is using Firebase Could Firestore databese to allows users multi-device experience. All garments created on one device will be available in another ones. (Provided that user will be on the same account)

User authentication

On the first run of application User is asked to create an account or Sign-in to an existing one. The following code is responsible for all authentication operations with Firebase server:

  //Logging in
  
  Future<void> signIn(String email, String password) async {
    try {
      userCredential = await _auth.signInWithEmailAndPassword(
          email: email, password: password);
    } on FirebaseAuthException catch (e) {
      if (e.code == 'user-not-found') {
        print('No user found for that email.');
      } else if (e.code == 'wrong-password') {
        print('Wrong password provided for that user.');
      }
    }
  }

Checking changes in authentication states during the application run (Depending on status state, relevant data will be showed on User's screen):

Future<void> _onAuthStateChanged(User firebaseUser) async {
  if (firebaseUser == null) {
    status = Status.Unauthenticated;
  } else {
    _user = firebaseUser;
    status = Status.Authenticated;
  }
  notifyListeners();
}
//Registration

Future<void> register(String email, String password) async {
    try {
      userCredential = await _auth.createUserWithEmailAndPassword(
          email: email, password: password);
    } on FirebaseAuthException catch (e) {
      if (e.code == 'weak-password') {
            print('The password provided is too weak.');
      } else if (e.code == 'email-already-in-use') {
            print('The account already exists for that email.');
      }
    } catch (e) {
          print(e);
    }
}

//Logging out

    Future<void> signOut() async {
        await _auth.signOut();
    }
}

Storing data on the server

In order to maintain clarity and speed of movement through the database, data should be entered in an appropriate manner.

When the User000 creates a garment with the following characteristics:

  1. Red hat
  2. Best for 26°C — 29°C
  3. Suitable for strong sun

The data would be stored in the following way:

Data Storing

Since it would be highly inefficient to store two variables corresponding to minimum and maximum temperature, the following assignment of ranges to corresponding words and numbers was used in the process of storing the temperature data:

0:   -∞ — -10° = Freezing

1:    -9° — 0° = Cold

2:    1° — 4° = Chilly

3:    5° — 8° = Brisk

4:    9° — 13° = Cool

5:    14° — 18° = Mild

6:    19° — 25° = Perfect

7:    26° — 29° = Warm

8:    30° — 33° = Hot

9:    34° — ∞° = Scorching

The above assignment of temperature to appropriate terms was borrowed from u/_eurostep's post on Reddit (Last access 21.02.2020).

Data sending

In WeatherDrobe, the user has the ability to add new garments to their Virtual Wardrobe, based on which the algorithm will create a clothing composition.

Clothes data to be transmitted should include following informations:

  • The temperature range in which the garment performs best.
  • Name of the garment template.
  • The color of the garment.
  • Additional weather conditions the garment can handle.
  • What part of the body this garment is designed for.

The code responsible for sending data to Firestore server:

Future<void> saveCloth(FirebaseAuth auth) {
    CollectionReference users = FirebaseFirestore.instance.collection('users');
    ClothType clothType = ClothType.values.elementAt(type);
    //users.add({'userID': userID});
    users
        .doc(auth.currentUser.uid)
        .set({'email': auth.currentUser.email, 'userID': auth.currentUser.uid});
    users.doc(auth.currentUser.uid).collection(clothTypeName).add({
      'temperature': temperatureRating,
      'snow': snow,
      'rain': rain,
      'sun': sun,
      'wind': wind,
      'dir': dir,
      'color': color
    });
  }

Data Fetching

On the server, the data is stored in four separated collections that correspond to head, upper body, lower body, and foot garment types. All of these collections are children of the parent document that is assigned to our account. Unfortunately, Firebase does not allow us to access the sub-collections from within the document (DocumentSnapshot), so we had to perform the operation four times while retrieving the data.

void getGarments(FirebaseAuth auth) async {
    List<QueryDocumentSnapshot> temp = [];
    await users
        .doc(auth.currentUser.uid)
        .collection('head')
        .get()
        .then((QuerySnapshot querySnapshot) => {
              if (querySnapshot.size > 0)
                {
                  querySnapshot.docs.forEach((doc) {
                    temp.add(doc);
                  })
                }
            });
    headwear = temp;
    temp = [];
    await users
        .doc(auth.currentUser.uid)
        .collection('top')
        .get()
        .then((QuerySnapshot querySnapshot) => {
              if (querySnapshot.size > 0)
                {
                  querySnapshot.docs.forEach((doc) {
                    temp.add(doc);
                  })
                }
            });
    top = temp;
    temp = [];
    await users
        .doc(auth.currentUser.uid)
        .collection('legs')
        .get()
        .then((QuerySnapshot querySnapshot) => {
              if (querySnapshot.size > 0)
                {
                  querySnapshot.docs.forEach((doc) {
                    temp.add(doc);
                  })
                }
            });
    legs = temp;
    temp = [];
    await users
        .doc(auth.currentUser.uid)
        .collection('feet')
        .get()
        .then((QuerySnapshot querySnapshot) => {
              if (querySnapshot.size > 0)
                {
                  querySnapshot.docs.forEach((doc) {
                    temp.add(doc);
                  })
                }
            });
    feet = temp;
    temp = [];
    userCollections = await users.doc(auth.currentUser.uid).get();
    notifyListeners();
  }

Algorithm

In the app, the most important factor is the algorithm that suggests clothes based on weather conditions. Below is a simplified flowchart of the clothing suggestion and display. In the diagram, the current temperature represents the median temperature for the next X hours (for now it's 10 hours). Clothing Proposal Algorithm Schema

Creating a Model

When creating a new Clothing object, the program checks what weather conditions will occur in the next X hours. To do this, the weather ID that OpeWeatherMap passes to us via its API is checked. The weather ID is a three-digit code that describes the exact weather phenomenon. There are seven main groups of weather conditions, which are subdivided into minor, more accurate weather descriptions. Below We present the main weather groups Full description of Weather Groups

Weather Group Description
2XX Thunderstorm
3XX Drizzle
5XX Rain
6XX Snow
7XX Atmosphere
800 Clear Sky
80X Clouds

Weatherdrobe details four types of weather phenomena: Rain, Snow, Strong Wind and Strong Sun, so the application analyses the received data from the OpenWeatherMap server as follows:

Weather Condition ID
Rain [200 - 531]
Snow [600 - 622]
Wind 771, 781
Sun 800

When creating a model, the algorithm will prioritise those garments that had compatibility with a given weather condition ticked during creation. In this way, on a rainy day, the algorithm will suggest a jacket first and clothes that are only suitable because of the temperature will appear in the next models.

Graphic Attribution

In the application, apart from using the icons available as standard in flutter, and the usual emoji - I also used icons made available on the internet for free use. Below I present all the information about the authors of the graphics I used for this project.

weatherdrobe's People

Contributors

itsmelucifer avatar

Stargazers

 avatar Artur Witkowski avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.