LukasBombach / de1

JavaScript API for the DE1 Espresso Machine
MIT License
20 stars 0 forks source link

App Concept? #18

Open LukasBombach opened 4 years ago

LukasBombach commented 4 years ago

I am moving PR https://github.com/LukasBombach/de1/pull/6 to this issue so the PR can be closed

DE1 lib Api

What do we want to do?

In this list I am not sure right now

  1. Which temperatures there are to read (I am on the train right now and would need to do some digging)
  2. Which settings can be set

The second point is a tricky one. As I understand it, you can set the espresso settings just as you would set them in the stock app. I.e. you choose values for the preinfusion, the pouring and the drop off. Then you would save them and later just then the command "start the espresso". The espresso would then be poured according to the settings. I talked to some DE1 engineer about this and he said everything can be set up in any way. I am not sure what he meant because I feel like the description I just wrote is about right and the workflow I described (setting -> then pouring) is too. But that needs more investigation.

abstract class DE1 {
  public abstract async connect(): Promise<void>;
  public abstract async disconnect(): Promise<void>;
  public abstract async turnOn(): Promise<void>;
  public abstract async turnOff(): Promise<void>;
  public abstract async startEspresso(): Promise<void>;
  public abstract async stopEspresso(): Promise<void>;
  public abstract async startSteam(): Promise<void>;
  public abstract async stopSteam(): Promise<void>;
  public abstract async startHotWater(): Promise<void>;
  public abstract async stopHotWater(): Promise<void>;
  public abstract async startFlushing(): Promise<void>;
  public abstract async stopFlushing(): Promise<void>;
  public abstract async startDescaling(): Promise<void>;
  public abstract async stopDescaling(): Promise<void>;
  public abstract async getWaterlevel(): Promise<number>;
  public abstract async getTemperatures(): Promise<Temperatures>;
  public abstract async setXXX(): Promise<void>;
}

interface Temperatures {
  groupHead: number;
  steam: number;
  /* ... */
}

DE1 GraphQL Api

I assume the GraphQL Api would be somewhat the same as the lib api, what do you think?

I think we should write an own Apollo connector for the DE1

https://github.com/apollographql/graphql-tools/blob/master/designs/connectors.md

App Concept Draft

Purpose of this document

The purpose of this document is to find a common idea of the technological architecture and the purpose of such.

Technological possibilites

The DE1 can be controlled wirelessly via Bluetooth Low Energy (BLE). This app being based on JavaScript there are exaclty 4 ways (called "platforms" from hereon) to work with BLE.

Each of these ways come with up- and downsides, capabilities and limitations. The following list shall depict the benefits and disadvantages relevant to the DE1 app.

Platform Web Bluetooth Node.js Mobile App Wrapper React Native / NativeScript
Can be run without installation - - -
Can be run without permission -
Can control the screen's brightness - -
Can control the sleep state - -
Can read the battery level - -
Has appropriate performance ? - ?
Has the best performance - - -
incomplete ... ... ... ...

Progessive enhancement

To make the most use of the advantages possible with each platform while dealing with the disadvantages in the best possible manner we can go the way of progrssive enhancement. This means we can implement and architecture the can be used on each platform and enhances with the capabilities the platform provides.

Draft of the idea:

check out this svg's source figma file

Design & UX Concepts

tl;dr let's use Material UI

The design and UX of the app is a crutial effort in making this app. It should be a vast improvement over the stock app. Apart from the generally clear benefits of having a well-deigned user interface and a thought through user experience, hopefully other users of the DE1 can be convinced to use this app for its joy of use. The goals for the UI include

By the beginning of a project developers and designers tend to be very excited of the opportunities that can be taken in this new endeavour. From this, actually good ideas get spawned and the motivation to make these ideas a reality are honest. Sadly, many of us know the experience that as the project progresses these ideas will be met with the reality of the time we have at hand and because software projects of a certain size span over months the initial motivation gets lost in the tedious work of fixing bugs and implementing features that emotionally become chores instead of exciting new ideas.

To meet this problem, we should take the route of least effort and make decisions that enable us to implement usable features effectively, with clean code and concentration on what we want to achieve rather than how we want to achieve it and not re-invent the wheel.

Of course, generally speaking this cannot always be done, and some discussions should precisely about how to achieve a feature rather than what to achieve.

In regards to UI and UX luckily there is a solution for this already, Design Systems with ready-made UI components and a thought system of UX patterns. We can use a Design System and stick to it at first, to get things done and lateron iterate on the design. Furthermore, a lot of feature and design decisions become clearer once something can be seen and used, so it might even be a good idea to start and play around with something rather than trying to hit the nail on the head by the very beginning of the project.

This here is a placeholder for a decision matrix on a design system, but frankly, I suggest we use material-ui just because of the maturity and feature-richness of this framework

App Code

Since this is just a draft, I want to add this quick note and add a proper paragraph later. This is what I would do:

As described in the Flowchart I would write the app so that it works solely as a SPA using Web Bluetooth and check if

The last point might seen op, but my reasoning would be that the app itself could run a GraphQL server that provides the functionality. Now other devices, like a phone could also connect to that GraphQL server, simultaneously with the app on the tablet. I already have 2 use cases for this:

TypeScript

I want to write some notes here to convice you to use TypeScript, because it makes code much safer and bug- and worry-free. Even though it has an admittedly steep learning curve and gets you frustrated at times.

Features

A place to discuss features

Repo, GitHub & CI

I would suggest working with a Monorepo, Github Actions as a CI tool. I would scrap the current packages in the current monorepo except for the de1 lib, refactor it like crazy (or start from new there too, I would not mind) and create separate packages for the app and other stuff.

LukasBombach commented 4 years ago

concept-flowchart.svg.zip

Here's the SVG above in a zip (I cant upload it otherwise) so its persisted on GitHub and I can remove it from my disk