Tutorial 2 - Completed

Behavior Graph Tutorial 2 Completed

by slevin11

HTML

<html>

  <head>

  </head>

  <body>

    <div class="thermostat">

      <div class="name">Tempwell</div>

      <div class="display">


        <div class="heat-display">
          Heat: <span id="heatStatus"></span>
        </div>

        <div class="display-item">
          <div class="display-item-title">Current</div>
          <div class="display-item-text" id="currentTemperatureDisplay"></div>
        </div>

        <div class="display-spacer">
        </div>

        <div class="display-item">
          <div class="display-item-title">Desired</div>
          <div class="display-item-text" id="desiredTemperature"></div>
        </div>

      </div>

      <div class="buttons">
        <button id="up">Up</button>
        <br />
        <button id="down">Down</button>
      </div>

    </div>

  </body>

</html>

CSS

.thermostat {
  width: 400px;
  height: 200px;
  border: 3px solid #333;
  padding: 20px;

}

.name {
  font: 1.6em sans-serif;
  margin-bottom: 50px;
}

.buttons {
  display: inline-block;
  vertical-align: top;
}

.buttons button {
  width: 50px;
  margin-bottom: 5px;
}

.display {
  margin-right: 10px;
  width: 290px;
  height: 80px;
  background-color: lightgray;
  display: inline-block;
  padding: 4px;
}

.heat-display {
  font: 1em sans-serif;
  margin-bottom: 4px;
}

.display-item {
  display: inline-block;
  vertical-align: top;
  width: 100px;
  text-align: center;
}

.display-item-title {
  font: 0.8em sans-serif;
}

.display-item-text {
  font: 1.4em sans-serif;
}

.display-spacer {
  width: 50px;
  display: inline-block;
  vertical-align: top;
}

body {
  font: 1.2em sans-serif;
}

JavaScript

import * as bg from "https://cdn.skypack.dev/behavior-graph";

class Thermostat extends bg.Extent {
  constructor(graph) {
    super(graph);

    this.up = this.moment();
    document.querySelector('#up').addEventListener('click', () => {
      this.up.updateWithAction();
    });

    this.down = this.moment();
    document.querySelector('#down').addEventListener('click', () => {
      this.down.updateWithAction();
    });
    this.desiredTemperature = this.state(60);

    this.currentTemperature = this.state(60);
    this.heatOn = this.state(false);

    this.behavior()
      .demands(this.up, this.down, this.addedToGraph)
      .supplies(this.desiredTemperature)
      .runs(() => {
        if (this.up.justUpdated) {
          this.desiredTemperature.update(this.desiredTemperature.value + 1);
        } else if (this.down.justUpdated) {
          this.desiredTemperature.update(this.desiredTemperature.value - 1);
        }
        this.sideEffect(() => {
          document.querySelector('#desiredTemperature').innerText = this.desiredTemperature.value;
        });
      });

    this.behavior()
      .demands(this.currentTemperature, this.addedToGraph)
      .runs(() => {
        this.sideEffect(() => {
          document.querySelector('#currentTemperatureDisplay').innerText = this.currentTemperature.value;
        });
      });

    this.behavior()
      .supplies(this.heatOn)
      .demands(this.currentTemperature, this.desiredTemperature, this.addedToGraph)
      .runs(() => {
        let heatOn = this.currentTemperature.value != null && this.desiredTemperature.value > this.currentTemperature.value;
        this.heatOn.update(heatOn);
        this.sideEffect(() => {
          document.querySelector('#heatStatus').innerText = this.heatOn.value ? "On" : "Off"
        });
      });

    this.behavior()
      .demands(this.heatOn)
      .runs(() => {
        if (this.heatOn.justUpdatedTo(true)) {
          this.sideEffect(() => {
            this.heatingIntervalId =...