Starting with HubHazard
Tags: hubitat, hubhazard, automation, tutorial
Published: 2020-09-02 03:50:02

One of the main goals of [HubHazard][hubhazardcore] is to make the setup step as easy as possible. In this post I'll present the simplest way of creating a HubHazard project - using the [HubHazard Basic Template][hubhazardtemplate]. In short:

1. Create a new repository from the [template][hubhazardtemplate].
1. Clone the repository
1. Install dependencies (`npm install`)
1. Start the server (`npm run start:dev`)

## Creating a Github repository from a template

It's always a good idea to start your project by creating a git repository for it. Go to the [HubHazard Basic Template github repository][hubhazardtemplate] and press the `Use this template` button to create a repository out of it.

![`Use this template` button](https://dev-to-uploads.s3.amazonaws.com/i/tzekl0n3mffoo23f5lf6.png)

On the next screen give your repository a name and click the `Create a repository from template` button. You're new repo is ready to be cloned.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3zwc7oguf6wb9d8p3x02.png)

After cloning the repo remember to install all packages by running:

```sh
npm install
```

## Project startup and Nest.js basics

The [HubHazard][hubhazardcore] is running on the [Nest.js][nestjs] framework:

> Nest is a framework for building efficient, scalable Node.js server-side applications. It uses modern JavaScript, is built with TypeScript (preserves compatibility with pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).

The [Nest.js][nestjs] framework has an [amazing documentation][nestjsdocs], but you don't need to know how it really works to use [HubHazard][hubhazardcore]. It won't hurt to know something about [modules][nestjsmodules] and [providers][nestjsproviders] though.

When working on your automations you can run the server in *development mode*. To do that just run the `start:dev` script:

```sh
num run start:dev
```

The project should compile and run. The project template comes with one example automation that shows a message every 15 seconds, so you should see those messages:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ocujmzuetbdplrnoprf5.gif)

## What happens under the hood

So what is really going on here under the hood? There are 4 main elements at play:

- **Automations** - An automation is a piece of code executed when conditions described by its triggers are met. Each automation is represented by a class extending the [Automation][automation] class. They register to the [AutomationsService].[automationsservice].
- **Events Services** - They act as events factories that send those events to subscribed automations. Each events service knows all of its subscribers. Each events service is represented by a class implementing the [EventsService][eventsservice] class. They register to the [AutomationsService][automationsservice].
- **Automations Service** - A class managing registrations of automations and events services. It links them all together.

In case of the [template project][hubhazardtemplate] we have only one events service and only one automation:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/q25ofmas1rtfikxwo7ol.png)

Everything starts with the `app.module.ts` file. This is the main module of the server. All used events services and automations should be registered here.

```ts
import { AutomationsModule, TimerEventsModule } from '@hubhazard/core';
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { BasicAutomation } from './automations/basic-automation';

@Module({
  imports: [
    AutomationsModule,
    ConfigModule.forRoot({ isGlobal: true }),
    TimerEventsModule,
  ],
  providers: [BasicAutomation],
})
export class AppModule {}
```

All events services mentioned in `imports` will be automatically registered in the [AutomationsService][automationsservice]. Similarly all automations mentioned in `providers` will be automatically registered in the [AutomationsService][automationsservice]. All you need to remember about when creating a new automation is to add it to the providers list in the `app.module.ts` file.

When the `BasicAutomation` is registered, it's passed to the [TimerEventsService][timereventsservice]. The [TimerEventsService][timereventsservice] scans triggers of the automation in search for ones it can handle. In case of `BasicAutomation` there is one trigger definition asking to run the automation once every 15 seconds. The [TimerEventsService][timereventsservice] remembers it and will send an [automation event][automationevent] **directly** to that automation every 15 seconds.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/bxbwnmh1ufw6wf0yzm5o.png)

All [automations][automation] must implement the `handleEvent` function. That function is called by events services and used to provide the [automation events][automationevent].

```ts
import { Automation, TimerTrigger } from '@hubhazard/core';
import { Injectable } from '@nestjs/common';

@Injectable()
export class BasicAutomation extends Automation {
  readonly name = 'Basic automation';
  readonly triggers = [TimerTrigger.every(15, 'seconds')];

  private counter = 0;

  // Handle the timer event
  async handleEvent() {
    this.counter++;
    console.log(`Triggered the '${this.name}' ${this.counter} times.`);
  }
}
```

## Up next

In the next article I'll explain how setup the[HubHazard][hubhazardcore] server on [Raspberry Pi Zero W][raspberryzero] - the $5 computer perfect for this purpose.



[hubhazardcore]: https://github.com/hubhazard/core
[hubhazardtemplate]: https://github.com/hubhazard/hubhazard-basic-template
[nestjs]: https://nestjs.com/
[nestjsdocs]: https://docs.nestjs.com/
[nestjsmodules]: https://docs.nestjs.com/modules
[nestjsproviders]: https://docs.nestjs.com/providers
[nestjsconfig]: https://docs.nestjs.com/techniques/configuration
[automation]: https://hubhazard.github.io/core/classes/automations.automation.html
[eventsservice]: https://hubhazard.github.io/core/interfaces/automations.ieventsservice.html
[automationsservice]: https://hubhazard.github.io/core/classes/automations.automationsservice.html
[timereventsservice]: https://hubhazard.github.io/core/classes/timerevents.timereventsservice.html
[automationevent]: https://hubhazard.github.io/core/classes/automations.automationevent.html
[raspberryzero]: https://www.raspberrypi.org/products/raspberry-pi-zero-w/