save data to sqlite
This commit is contained in:
parent
11e1d1b468
commit
53d7efc20a
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,6 +1,7 @@
|
|||||||
# compiled output
|
# compiled output
|
||||||
/dist
|
/dist
|
||||||
/node_modules
|
/node_modules
|
||||||
|
*.sqlite
|
||||||
|
|
||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
@ -32,4 +33,4 @@ lerna-debug.log*
|
|||||||
!.vscode/settings.json
|
!.vscode/settings.json
|
||||||
!.vscode/tasks.json
|
!.vscode/tasks.json
|
||||||
!.vscode/launch.json
|
!.vscode/launch.json
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
|
@ -25,9 +25,12 @@
|
|||||||
"@nestjs/core": "^10.0.0",
|
"@nestjs/core": "^10.0.0",
|
||||||
"@nestjs/platform-express": "^10.0.0",
|
"@nestjs/platform-express": "^10.0.0",
|
||||||
"@nestjs/schedule": "^3.0.3",
|
"@nestjs/schedule": "^3.0.3",
|
||||||
|
"@nestjs/typeorm": "^10.0.0",
|
||||||
"cache-manager": "^5.2.3",
|
"cache-manager": "^5.2.3",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1",
|
||||||
|
"sqlite3": "^5.1.6",
|
||||||
|
"typeorm": "^0.3.17",
|
||||||
"usb": "^2.10.0"
|
"usb": "^2.10.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
873
pnpm-lock.yaml
generated
873
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,24 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
import { ScheduleModule } from '@nestjs/schedule';
|
||||||
import { AppController } from './app.controller';
|
import { AppController } from './app.controller';
|
||||||
import { AppService } from './app.service';
|
import { AppService } from './app.service';
|
||||||
import { CacheModule } from '@nestjs/cache-manager';
|
import { CacheModule } from '@nestjs/cache-manager';
|
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
import { join } from 'path';
|
||||||
|
import { WeatherEntity } from './entities/weather.entity';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [CacheModule.register()],
|
imports: [
|
||||||
|
CacheModule.register(),
|
||||||
|
TypeOrmModule.forRoot({
|
||||||
|
type: 'sqlite',
|
||||||
|
database: join(process.cwd(), 'data.sqlite'),
|
||||||
|
entities: [WeatherEntity],
|
||||||
|
synchronize: true,
|
||||||
|
}),
|
||||||
|
TypeOrmModule.forFeature([WeatherEntity]),
|
||||||
|
ScheduleModule.forRoot(),
|
||||||
|
],
|
||||||
controllers: [AppController],
|
controllers: [AppController],
|
||||||
providers: [AppService],
|
providers: [AppService],
|
||||||
})
|
})
|
||||||
|
@ -1,13 +1,70 @@
|
|||||||
import { Injectable, OnApplicationShutdown } from '@nestjs/common';
|
import {
|
||||||
|
Injectable,
|
||||||
|
InternalServerErrorException,
|
||||||
|
Logger,
|
||||||
|
OnApplicationShutdown,
|
||||||
|
} from '@nestjs/common';
|
||||||
import WS1080 from './module/ws1080';
|
import WS1080 from './module/ws1080';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import { WeatherEntity } from './entities/weather.entity';
|
||||||
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
import { Cron } from '@nestjs/schedule';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AppService implements OnApplicationShutdown {
|
export class AppService implements OnApplicationShutdown {
|
||||||
|
private logger = new Logger(AppService.name);
|
||||||
public station?: WS1080;
|
public station?: WS1080;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(WeatherEntity)
|
||||||
|
private readonly weatherRepository: Repository<WeatherEntity>,
|
||||||
|
) {}
|
||||||
|
|
||||||
async getWeather() {
|
async getWeather() {
|
||||||
if (!this.station) this.station = WS1080.fromDevice();
|
try {
|
||||||
return this.station.read();
|
// Retrieve from USB
|
||||||
|
if (!this.station) this.station = WS1080.fromDevice();
|
||||||
|
const data = await this.station.read();
|
||||||
|
|
||||||
|
// Save weather data to database
|
||||||
|
const entity = this.weatherRepository.create({
|
||||||
|
date: new Date(),
|
||||||
|
...data,
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.weatherRepository.save(entity);
|
||||||
|
entity.fresh = true;
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
} catch (error) {
|
||||||
|
// USB errors likely mean we are not connected anymore
|
||||||
|
if (error.message?.includes('USB')) {
|
||||||
|
try {
|
||||||
|
this.station?.close();
|
||||||
|
} catch {}
|
||||||
|
this.station = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.error('Failed to retrieve weather data:', error.stack);
|
||||||
|
|
||||||
|
// Retrieve previous entry on error
|
||||||
|
const [previous] = await this.weatherRepository.find({
|
||||||
|
order: { date: -1 },
|
||||||
|
take: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!previous) throw new InternalServerErrorException();
|
||||||
|
|
||||||
|
previous.fresh = false;
|
||||||
|
return previous;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Cron('0 * * * *')
|
||||||
|
scheduledPulls() {
|
||||||
|
this.getWeather().catch(() => {
|
||||||
|
// do nothing
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onApplicationShutdown() {
|
onApplicationShutdown() {
|
||||||
|
48
src/entities/weather.entity.ts
Normal file
48
src/entities/weather.entity.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
export class WeatherEntity {
|
||||||
|
@PrimaryGeneratedColumn()
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
@Column({ type: Date })
|
||||||
|
date: Date;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
indoorHumidity: number;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
outdoorHumidity: number;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
indoorTemperature: number;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
outdoorTemperature: number;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
outdoorDewPoint: number;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
windChillTemp: number;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
windSpeed: number;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
gustSpeed: number;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
windDirection: string;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
rainDiff: number;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
totalRain: number;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
absPressure: number;
|
||||||
|
|
||||||
|
fresh?: boolean;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user