Successfully creating a database if it does not already exist
This commit is contained in:
parent
b688b365fb
commit
0fc390c713
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
node_modules
|
node_modules
|
||||||
bin
|
bin
|
||||||
|
automation.db
|
||||||
|
1
automation.db.sqbpro
Normal file
1
automation.db.sqbpro
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?><sqlb_project><db path="/Users/brandonwatson/Documents/Gitlab/Home/homebridge-automation/automation.db" foreign_keys="1" case_sensitive_like="0" temp_store="0" wal_autocheckpoint="1000" synchronous="2"/><attached/><window><current_tab id="0"/></window><tab_structure><column_width id="0" width="300"/><column_width id="1" width="0"/><column_width id="2" width="100"/><column_width id="3" width="1453"/><column_width id="4" width="0"/><expanded_item id="0" parent="1"/><expanded_item id="1" parent="1"/><expanded_item id="2" parent="1"/><expanded_item id="3" parent="1"/></tab_structure><tab_browse><current_table name="event_service_instance_characteristics"/><default_encoding codec=""/><browse_table_settings/></tab_browse><tab_sql><sql name="SQL 1"></sql><current_tab id="0"/></tab_sql></sqlb_project>
|
@ -3,5 +3,10 @@
|
|||||||
{
|
{
|
||||||
"path": "."
|
"path": "."
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"settings": {
|
||||||
|
"files.exclude": {
|
||||||
|
"node_modules": true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
1665
package-lock.json
generated
1665
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -25,15 +25,19 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/bonjour": "^3.5.5",
|
"@types/bonjour": "^3.5.5",
|
||||||
"@types/inflection": "^1.5.28",
|
"@types/inflection": "^1.5.28",
|
||||||
|
"@types/knex": "^0.16.1",
|
||||||
"@types/request-promise": "^4.1.44",
|
"@types/request-promise": "^4.1.44",
|
||||||
"@types/request-promise-native": "^1.0.16",
|
"@types/request-promise-native": "^1.0.16",
|
||||||
|
"@types/sqlite3": "^3.1.5",
|
||||||
"bonjour": "^3.5.0",
|
"bonjour": "^3.5.0",
|
||||||
"decamelize": "^3.2.0",
|
"decamelize": "^3.2.0",
|
||||||
"inflection": "^1.12.0",
|
"inflection": "^1.12.0",
|
||||||
|
"knex": "^0.19.4",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"request": "^2.88.0",
|
"request": "^2.88.0",
|
||||||
"request-promise-native": "^1.0.7",
|
"request-promise-native": "^1.0.7",
|
||||||
"source-map-support": "^0.5.13",
|
"source-map-support": "^0.5.13",
|
||||||
|
"sqlite3": "^4.1.0",
|
||||||
"tsyringe": "^3.3.0"
|
"tsyringe": "^3.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -55,16 +55,16 @@ export class HapMonitor extends EventEmitter {
|
|||||||
this.debug(`[HapClient] [${instance.ipAddress}:${instance.port} (${instance.username})] ` +
|
this.debug(`[HapClient] [${instance.ipAddress}:${instance.port} (${instance.username})] ` +
|
||||||
`Got Event: ${JSON.stringify(body.characteristics)}`);
|
`Got Event: ${JSON.stringify(body.characteristics)}`);
|
||||||
|
|
||||||
const response = body.characteristics.map((c: CharacteristicType): IServiceType | undefined => {
|
const response: Array<IServiceType> = body.characteristics.map((charType: CharacteristicType): IServiceType | undefined => {
|
||||||
// find the matching service for each characteristics
|
// find the matching service for each characteristics
|
||||||
const service = this.services.find(x => x.aid === c.aid && x.instance.username === instance.username);
|
const service = this.services.find(x => x.aid === charType.aid && x.instance.username === instance.username);
|
||||||
|
|
||||||
if (service) {
|
if (service) {
|
||||||
// find the correct characteristic and update it
|
// find the correct characteristic and update it
|
||||||
const characteristic = service.serviceCharacteristics.find(x => x.iid === c.iid);
|
const characteristic = service.serviceCharacteristics.find(x => x.iid === charType.iid);
|
||||||
if (characteristic) {
|
if (characteristic) {
|
||||||
characteristic.value = c.value;
|
characteristic.value = charType.value;
|
||||||
service.values[characteristic.type] = c.value;
|
service.values[characteristic.type] = charType.value;
|
||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ export class HapMonitor extends EventEmitter {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// push update to listeners
|
// push update to listeners
|
||||||
this.emit('service-update', response.filter((x: unknown) => x));
|
this.emit('service-updated', response.filter((service: IServiceType) => service));
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// do nothing
|
// do nothing
|
||||||
|
3
src/Models/IConfig.ts
Normal file
3
src/Models/IConfig.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export interface IConfig {
|
||||||
|
databaseLocation?: string;
|
||||||
|
}
|
10
src/index.ts
10
src/index.ts
@ -4,13 +4,15 @@ import { log, Homebridge } from './Types/types';
|
|||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import { container } from 'tsyringe';
|
import { container } from 'tsyringe';
|
||||||
import { Monitor } from './Services';
|
import { Monitor } from './Services';
|
||||||
|
import { IConfig } from './Models/IConfig';
|
||||||
|
import Knex = require('knex');
|
||||||
|
|
||||||
class AutomationPlatform {
|
class AutomationPlatform {
|
||||||
private log: log;
|
private log: log;
|
||||||
private config: {} = {};
|
private config: IConfig;
|
||||||
private api: EventEmitter;
|
private api: EventEmitter;
|
||||||
|
|
||||||
constructor(log: log, config: {}, api: EventEmitter) {
|
constructor(log: log, config: IConfig, api: EventEmitter) {
|
||||||
this.log = log;
|
this.log = log;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.api = api;
|
this.api = api;
|
||||||
@ -30,7 +32,11 @@ class AutomationPlatform {
|
|||||||
private main = (): void => {
|
private main = (): void => {
|
||||||
//Register the log function for DI
|
//Register the log function for DI
|
||||||
container.register("log", { useValue: this.log });
|
container.register("log", { useValue: this.log });
|
||||||
|
container.register<IConfig>("config", { useValue: this.config });
|
||||||
|
|
||||||
|
//Resolve singleton instances
|
||||||
container.resolve(Monitor);
|
container.resolve(Monitor);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,21 +1,136 @@
|
|||||||
import { HapClient } from "../HapClient";
|
import { HapClient, HapMonitor } from "../HapClient";
|
||||||
import { log } from '../Types/types';
|
import { log } from '../Types/types';
|
||||||
import { singleton, inject } from 'tsyringe';
|
import { singleton, inject, container } from 'tsyringe';
|
||||||
|
import { IServiceType } from "../HapClient/interfaces";
|
||||||
|
import { IConfig } from "../Models/IConfig";
|
||||||
|
import { Database } from "sqlite3";
|
||||||
|
import { mkdirSync } from 'fs';
|
||||||
|
import { join } from 'path';
|
||||||
|
import Knex = require("knex");
|
||||||
|
|
||||||
|
|
||||||
@singleton()
|
@singleton()
|
||||||
export default class Monitor {
|
export default class Monitor {
|
||||||
private log: log;
|
private log: log;
|
||||||
private api: any;
|
private config: IConfig
|
||||||
private client: HapClient;
|
private client: HapClient;
|
||||||
|
private pin = "031-45-154";
|
||||||
|
private databaseLocation = `/Users/brandonwatson/.homebridge/automation`;
|
||||||
|
private databaseName = 'automation.db';
|
||||||
|
private db?: Database;
|
||||||
|
private knex?: Knex;
|
||||||
|
|
||||||
constructor(@inject("log") log: log) {
|
constructor(@inject("log") log: log, @inject("config") config: IConfig) {
|
||||||
this.log = log;
|
this.log = log;
|
||||||
|
this.config = config;
|
||||||
|
|
||||||
this.client = new HapClient({
|
this.client = new HapClient({
|
||||||
pin: "031-45-154",
|
pin: this.pin,
|
||||||
logger: this.log,
|
logger: this.log,
|
||||||
config: {}
|
config: {}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Overwrite default db location
|
||||||
|
if (config.databaseLocation) {
|
||||||
|
this.databaseLocation = config.databaseLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.initializeDatabase().catch((err) => {
|
||||||
|
this.log(`Error connecting to sqlite database: ${err}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.initializeHapMonitor();
|
||||||
|
}
|
||||||
|
|
||||||
|
private get dbFullPath(): string {
|
||||||
|
return join(this.databaseLocation, this.databaseName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private initializeHapMonitor = async (): Promise<void> => {
|
||||||
|
await this.client.discover();
|
||||||
|
const services: Array<IServiceType> = await this.client.getAllServices();
|
||||||
|
|
||||||
|
const hapMonitor = new HapMonitor(this.log, this.log, this.pin, services);
|
||||||
|
|
||||||
|
//Set service updated event
|
||||||
|
hapMonitor.on('service-updated', this.onServiceUpdated);
|
||||||
|
|
||||||
|
this.log("Monitor ready");
|
||||||
|
}
|
||||||
|
|
||||||
|
private initializeDatabase = async (): Promise<void> => {
|
||||||
|
try {
|
||||||
|
mkdirSync(this.databaseLocation);
|
||||||
|
} catch (err) {
|
||||||
|
if (err.code !== 'EEXIST') {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.initDbFile(this.dbFullPath);
|
||||||
|
} catch (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.knex = Knex({
|
||||||
|
client: 'sqlite3',
|
||||||
|
connection: {
|
||||||
|
filename: this.dbFullPath
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
container.register<Knex>('knex', { useValue: this.knex });
|
||||||
|
|
||||||
|
const hasTables = await this.knex.schema.hasTable('events');
|
||||||
|
|
||||||
|
if (!hasTables) {
|
||||||
|
//create databse tables
|
||||||
|
await this.knex.raw(`CREATE TABLE "event_service_instance_characteristics" (
|
||||||
|
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||||
|
"instance_id" INTEGER NOT NULL,
|
||||||
|
"key" TEXT NOT NULL,
|
||||||
|
"type" TEXT NOT NULL,
|
||||||
|
"value" BLOB NOT NULL)`);
|
||||||
|
|
||||||
|
await this.knex.raw(`CREATE TABLE "event_service_instances" (
|
||||||
|
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||||
|
"event_id" INTEGER NOT NULL,
|
||||||
|
"service_id" INTEGER NOT NULL)`);
|
||||||
|
|
||||||
|
await this.knex.raw(`CREATE TABLE "events" (
|
||||||
|
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||||
|
"timestamp" BLOB NOT NULL)`);
|
||||||
|
|
||||||
|
await this.knex.raw(`CREATE TABLE "services" (
|
||||||
|
"id" INTEGER NOT NULL UNIQUE,
|
||||||
|
"uniqueId" TEXT NOT NULL UNIQUE,
|
||||||
|
"uuid" TEXT NOT NULL UNIQUE,
|
||||||
|
"type" TEXT NOT NULL,
|
||||||
|
"humanType" TEXT NOT NULL,
|
||||||
|
"serviceName" TEXT NOT NULL)`);
|
||||||
|
}
|
||||||
|
console.log();
|
||||||
|
};
|
||||||
|
|
||||||
|
private initDbFile = (path: string): Promise<Database> => {
|
||||||
|
return new Promise((resolve, reject): void => {
|
||||||
|
const db: Database = new Database(path, (err): void => {
|
||||||
|
if (err) {
|
||||||
|
return reject(err);
|
||||||
|
} else {
|
||||||
|
return resolve(db);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private syncDatabase = async (): Promise<void> => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private onServiceUpdated = (updatedServices: Array<IServiceType>): void => {
|
||||||
|
console.log("asdf");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user