homeweatherapi/src/app.service.ts

99 lines
2.4 KiB
TypeScript
Raw Normal View History

2023-09-17 06:54:01 +00:00
import {
Injectable,
InternalServerErrorException,
Logger,
OnApplicationShutdown,
} from '@nestjs/common';
2023-09-16 19:45:26 +00:00
import WS1080 from './module/ws1080';
2023-09-17 07:05:52 +00:00
import { MoreThan, Repository } from 'typeorm';
2023-09-17 06:54:01 +00:00
import { WeatherEntity } from './entities/weather.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { Cron } from '@nestjs/schedule';
2023-09-17 07:05:52 +00:00
import { HistoryQueryDto } from './dtos/history-query.dto';
2023-09-16 19:45:26 +00:00
@Injectable()
export class AppService implements OnApplicationShutdown {
2023-09-17 06:54:01 +00:00
private logger = new Logger(AppService.name);
2023-09-16 19:45:26 +00:00
public station?: WS1080;
2023-09-17 06:54:01 +00:00
constructor(
@InjectRepository(WeatherEntity)
private readonly weatherRepository: Repository<WeatherEntity>,
) {}
2023-09-16 19:45:26 +00:00
async getWeather() {
2023-09-17 06:54:01 +00:00
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;
}
}
2023-09-17 07:05:52 +00:00
async getWeatherHistory(query: HistoryQueryDto) {
const pageSize = Number(query.pageSize) || 100;
const page = Number(query.page) || 1;
const [list, rowCount] = await this.weatherRepository.findAndCount({
where: query.since
? { date: MoreThan(new Date(query.since)) }
: undefined,
order: { date: -1 },
take: pageSize,
skip: (page - 1) * pageSize,
});
const pageCount = Math.ceil(rowCount / pageSize);
return {
list,
pagination: {
page,
pageSize,
pageCount,
rowCount,
},
};
}
2023-09-17 06:54:01 +00:00
@Cron('0 * * * *')
scheduledPulls() {
this.getWeather().catch(() => {
// do nothing
});
2023-09-16 19:45:26 +00:00
}
onApplicationShutdown() {
this.station?.close();
}
}