GithubHelp home page GithubHelp logo

codi-hacks / weather-station Goto Github PK

View Code? Open in Web Editor NEW
46.0 5.0 6.0 3.69 MB

Everything you need to run and monitor your own open source weather station. ⛅

Home Page: https://weather.codihacks.org/

License: Other

JavaScript 12.37% HTML 1.78% Vue 31.06% C++ 20.65% C 2.93% Shell 0.23% Rust 30.25% PLpgSQL 0.74%
weather-app weather pwa rust-api rust-weather rust-web vue vuetify arduino esp8266

weather-station's People

Contributors

chrizafier avatar jaythomas avatar marciorene avatar supershadowplay avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

weather-station's Issues

Create data store

Rather than store API results in a particular component, put the data in the Vuex store so it's globally accessible.

Clean up migrations

Once done with #14 the only seed data that should be in the migrations is the sensor_types.

Clean up unnecessary routes

Given we have the UDP socket for uploading measurements and the weather station management script coming in #14 we don't need to manage data from the API and will only need to handle GET requests as such:

Screenshot from 2021-06-23 20-25-37

All other routes should be removed as well as the associated functions on the models (with the exception of what the UDP socket is using).

Add an empty dashboard alert

When the dashboard is empty, create an alert that displays in place of the grid to tell the user they need to open the sidebar and add some "cards" to their dashboard.

/stations not returning sensors

Hitting the /stations route on the server I am only getting back the ID and label for the stations:

[
  {
    "id": "cbcb99ef-f20e-4484-93dd-ebda4a259481",
    "label": "Trevor Station"
  },
  {
    "id": "60965d1a-e02d-41a4-843c-38efa7cb334b",
    "label": "R3-S6"
  },
  {
    "id": "112fcf4c-c279-44ea-b400-6f3e3e17b472",
    "label": "Ithaca"
  }
]

I should also be receiving an array of sensors:

[
  {
    "id": "a7d6f7f3-a5b3-459a-83d7-87a3af57fe57",
    "label": "Swiftcreek Reservoir",
    "sensors": [
      {
        "id": "35072d26-5306-4b4e-b459-81758e35a202",
        "alias": "signal",
        "label": "signal",
        "created_at": "2021-05-01T04:22:20.804463",
        "updated_at": "2021-07-21T16:52:48.765878"
      },
      {
        "id": "e67740bf-3e26-4145-8647-35f1b0914b5f",
        "alias": "altitude",
        "label": "altitude",
        "created_at": "2021-05-01T04:22:20.804463",
        "updated_at": "2021-07-21T16:52:48.770524"
      },
      {
        "id": "f8a89dbb-57e1-442e-b19d-79a4787ffbc1",
        "alias": "air_temp",
        "label": "air_temp",
        "created_at": "2021-05-01T04:22:20.804463",
        "updated_at": "2021-07-21T16:52:48.773889"
      },
      {
        "id": "ac7327c2-0ec6-4f4d-a55a-384cd23f519e",
        "alias": "pressure",
        "label": "pressure",
        "created_at": "2021-05-01T04:22:20.804463",
        "updated_at": "2021-07-21T16:52:48.777502"
      },
      {
        "id": "eca63f73-0897-4cb4-ba78-adf673929e5e",
        "alias": "humidity",
        "label": "humidity",
        "created_at": "2021-05-01T04:22:20.804463",
        "updated_at": "2021-07-21T16:52:48.781044"
      },
      {
        "id": "d61063a3-7459-4d72-a9a5-7801800f0b27",
        "alias": "voltage",
        "label": "voltage",
        "created_at": "2021-05-01T04:22:20.804463",
        "updated_at": "2021-07-21T16:52:48.784098"
      }
    ]
  }
]

Add zoom reset button

You can zoom in on the chart by dragging the mouse across a section of the chart, narrowing the time scope even further than the selected time series. Next to the other time buttons, add a zoom reset button that appears when the chart is in a zoomed-in state that will reset the zoom when clicked (then hide again).

Create subdomain for production instance

We need a production server and subdomain to host the API server on once it is complete. Somewhere that can handle a growing PostgreSQL database and provide direct shell access for maintenance and remote debugging.

Move the side drawer into a dedicated component

Currently the <v-navigation-drawer> and all its content lives inside the layout (components/Layout.vue) but it would be cleaner to have this code live in a dedicated SideDrawer.vue component.

Show originating station on the dashboard.

If one were to bookmark cards from different stations, there is no good way to tell which is which. Something like `Ithaca's Temperature" in the corner would be nice.

Update to Actix V4

Before you say? BuT tHiS iS nOt IMpOrTaNt

  1. Keeping libraries up to date keep things secure
  2. I like Rust and it would keep me happy to do this. (Free Dopamine)
  3. More Features maybe. IDK

Ability to pin sensor cards to dashboard

The dashboard will be a place the user can see only the cards/sensor data they want to see. Add a button to the corner of cards on the station page that gives the ability to pin these cards to the dashboard. The list of pinned sensors should be stored in the indexdb.

This depends on #8.

Get the sidebar station routes working

Come up with some mock data to use to get the sidebar functionality. This mock data will also model how we want the data from the api server to look so that those api server dudes will know what to send us.

Create UDP socket and message parser

Weather stations send data to the server in the form of a UDP datagram. The server needs to expose a UDP socket and parse incoming messages per the format described by the sketch.

Max voltage on voltage card cutting off

If the voltage of a battery is ~4.2v then it gets cut off on the graph because 4.2 is currently the max peak on the chart. We should set it to something slightly higher like 4.25 or 4.3.

Add CORS header middleware

Client browser will block api requests across domains if we don't set a CORS policy, meaning we can't receive JSON from the server unless the server sends the appropriate HTTP headers in the response data. From the actix middleware, add some CORS header policies to the app. Something like this is probably good enough:

            .wrap(middleware::DefaultHeaders::new().header("Access-Control-Allow-Methods", "GET"))
            .wrap(middleware::DefaultHeaders::new().header("Access-Control-Allow-Origin", "*"))

Add homepage route

If a client connects directly to "/" then display to them a friendly html page to let them know the server is running.

You can use the include_str! macro to pull in an html file in the source code as a String.

Flesh out About page

The About page on the web app is currently one line of text. Make it not so!
A few starter ideas on what to include:

  • State the purpose of this project.
  • Explain the features.
  • Possibly give a brief overview of the frameworks and languages that make the project possible (Vue, Rust, the weather station hardware, etc.)

Create preferences menu

Create a side drawer that slides out from the right, similar to the navigation drawer that resides on the left side of the page. This will allow the user to set preferences from it such as preferred spacial units (meters/feet), preferred temperature units (celsius/fahrenheit), and color theme. This issue is specifically focused on creating the component rather than all the functionality that will reside on it.

Create associations in schema and models

From the bottom up, measurements belong to sensors and sensors belong to sensor_types and stations. In other words, weather stations have sensors (of a given sensors type), which in turn have measurements.

So from the SQL perspective you should have a FOREIGN_KEY definition in the measurements table:

  FOREIGN KEY (sensor_id) REFERENCES sensors(id)

And in the sensors:

  FOREIGN KEY (type_id) REFERENCES sensor_types(id),
  FOREIGN KEY (station_id) REFERENCES stations(id)

DRY up card component code

In web-app/src/components/cards these components share a lot of duplicate code. Some of this code such as the header text and buttons could stand to be moved into a separate component. Or perhaps a generic card component could be made without adding much complexity.

Add remaining sensor cards

We have a Temperature card, now we need to copy the component design over to the rest of the sensor types:

  • Elevation
  • Humidity
  • Pressure
  • Signal
  • Voltage

Create cli utility to manage weather stations

Rather than exposing a public route on the API server to create stations, stations can be created and managed from a shell as needed. This will eliminate the need for authentication, at least remove the need for authentication within a 1.0 release.

This script will be located at src/bin/station.

Create database schema and server resources

This is the data structure we talked about in week 6. Take the sample api on the api branch and make it so!

  • stations:
    • id: Uuid
    • label: Varchar
    • key: Varchar
  • sensors:
    • id: Uuid
    • alias: Varchar
    • label: Varchar
    • type_id: Uuid
    • station_id: Uuid
    • created_at: Timestamp
    • updated_at: Timestamp
  • measurements:
    • id: Uuid
    • value: Numeric
    • sensor_id: Uuid
    • created_at: Timestamp
  • sensor_types:
    • id: Uuid
    • label: Varchar
    • description: Varchar

Add color themes

Provide the user with a dropdown to change the theme. This will reside on the settings menu (#38).

See the theme generator and example implementation of loading theme variations

Edit:

So I can see two different things in one package here. The "theme" we could set different colors, e.g., a "blue" theme and "green" theme, and then on the Preferences menu have a second option for "contrast" so you can select a "light" or "dark" contrast of the theme you're using, e.g. a "light green" and "dark green".

Looking at the documentation this will probably be one of the trickier ones. For starters though you should be able to import the vuetify plugin instance and poke around:

import vuetify from '@/plugins/vuetify'

And console.log(vuetify) to see where the dark/light boolean variables are inside the vuetify object and then try toggling one of them when the contrast is changed..

Guard against replay attacks

Say a hooligan wants to send garbage measurements to an api server. If they knew the both the ID and private key of a station they could easily do so. To prevent this, the key is never sent as part of the datagram. Simply a hash derived from the key is used.

And that's it. There is no handshake or further encryption of the message. The weather station sends the UDP datagram and goes back to sleep as quickly as possible. It doesn't wait around and waste battery life.

What this means for the hooligan is if they don't have an id and key of a weather station, if they intercepted a datagram they would have a valid message they could send and re-send to the server over and over again to fill up the database with bogus measurements. This is a replay attack. This scenario isn't likely so I'm not labeling the issue as a critical vulnerability or anything like that. But it may be possible to fix while maintaining compatibility with the current message specification.

Let's say every message send from a weather station has a randomly-generated UUID included in it:

air_temp=23.4,humidity=62.45,id=053050d3-7fa7-438d-93f1-8285fd5eef79,uuid=469f1b70-712a-4cb6-9a87-da8eff3e90ba
#540151989

Since the hash changes every time the message changes, no two messages will have the same hash assuming each uuid is indeed unique. The api server can store this uuid in a new column (or part of the measurements' ID's in some way) and look up later when adding new measurements to make sure it hasn't seen this uuid before.

Allow dashboard to be sorted

On mobile:

  • Add a button to the top bar that displays when you're on the dashboard
  • When clicked, it drops you into edit mode that displays the Mode button, Time buttons, and two new Sort buttons
  • The sort buttons will be up/down arrows and be displayed to the right of the mode button

On desktop:

  • Always display the sort buttons, but display left/right arrows as it makes more sense in a multi-column mode.

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.