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
|
||||
/dist
|
||||
/node_modules
|
||||
*.sqlite
|
||||
|
||||
# Logs
|
||||
logs
|
||||
@ -32,4 +33,4 @@ lerna-debug.log*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/extensions.json
|
||||
|
@ -25,9 +25,12 @@
|
||||
"@nestjs/core": "^10.0.0",
|
||||
"@nestjs/platform-express": "^10.0.0",
|
||||
"@nestjs/schedule": "^3.0.3",
|
||||
"@nestjs/typeorm": "^10.0.0",
|
||||
"cache-manager": "^5.2.3",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rxjs": "^7.8.1",
|
||||
"sqlite3": "^5.1.6",
|
||||
"typeorm": "^0.3.17",
|
||||
"usb": "^2.10.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
873
pnpm-lock.yaml
873
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,24 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ScheduleModule } from '@nestjs/schedule';
|
||||
import { AppController } from './app.controller';
|
||||
import { AppService } from './app.service';
|
||||
import { CacheModule } from '@nestjs/cache-manager';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { join } from 'path';
|
||||
import { WeatherEntity } from './entities/weather.entity';
|
||||
|
||||
@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],
|
||||
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 { Repository } from 'typeorm';
|
||||
import { WeatherEntity } from './entities/weather.entity';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Cron } from '@nestjs/schedule';
|
||||
|
||||
@Injectable()
|
||||
export class AppService implements OnApplicationShutdown {
|
||||
private logger = new Logger(AppService.name);
|
||||
public station?: WS1080;
|
||||
|
||||
constructor(
|
||||
@InjectRepository(WeatherEntity)
|
||||
private readonly weatherRepository: Repository<WeatherEntity>,
|
||||
) {}
|
||||
|
||||
async getWeather() {
|
||||
if (!this.station) this.station = WS1080.fromDevice();
|
||||
return this.station.read();
|
||||
try {
|
||||
// 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() {
|
||||
|
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