Preserve Flutter mirror-os codebase
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mirror_core/mirror_core.dart';
|
||||
import 'settings_provider.dart';
|
||||
|
||||
final haServiceProvider = Provider<HomeAssistantService?>((ref) {
|
||||
final settings = ref.watch(settingsProvider).valueOrNull;
|
||||
if (settings == null || settings.haBaseUrl == null || settings.haToken == null) {
|
||||
return null;
|
||||
}
|
||||
return HomeAssistantService(
|
||||
baseUrl: settings.haBaseUrl!,
|
||||
token: settings.haToken!,
|
||||
);
|
||||
});
|
||||
|
||||
final haEntitiesProvider =
|
||||
AsyncNotifierProvider<HaEntitiesNotifier, HaEntitiesState>(HaEntitiesNotifier.new);
|
||||
|
||||
class HaEntitiesState {
|
||||
final List<HaEntity> entities;
|
||||
final HaWeather? weather;
|
||||
final List<HaCalendarEvent> calendarEvents;
|
||||
final String? error;
|
||||
|
||||
const HaEntitiesState({
|
||||
this.entities = const [],
|
||||
this.weather,
|
||||
this.calendarEvents = const [],
|
||||
this.error,
|
||||
});
|
||||
}
|
||||
|
||||
class HaEntitiesNotifier extends AsyncNotifier<HaEntitiesState> {
|
||||
@override
|
||||
Future<HaEntitiesState> build() async {
|
||||
final service = ref.watch(haServiceProvider);
|
||||
if (service == null) {
|
||||
return const HaEntitiesState(error: 'Configure Home Assistant in Settings');
|
||||
}
|
||||
try {
|
||||
final entities = await service.getStates();
|
||||
// Find weather entity
|
||||
final weatherEntity = entities.firstWhere(
|
||||
(e) => e.entityId.startsWith('weather.'),
|
||||
orElse: () => HaEntity(entityId: '', state: '', attributes: {}, lastChanged: null),
|
||||
);
|
||||
HaWeather? weather;
|
||||
if (weatherEntity.entityId.isNotEmpty) {
|
||||
weather = HaWeather.fromEntity(weatherEntity);
|
||||
}
|
||||
return HaEntitiesState(
|
||||
entities: entities,
|
||||
weather: weather,
|
||||
);
|
||||
} catch (e) {
|
||||
return HaEntitiesState(error: 'HA connection failed: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> toggleEntity(String entityId) async {
|
||||
final service = ref.read(haServiceProvider);
|
||||
if (service == null) return;
|
||||
|
||||
final entity = state.valueOrNull?.entities.firstWhere(
|
||||
(e) => e.entityId == entityId,
|
||||
orElse: () => HaEntity(entityId: '', state: '', attributes: {}, lastChanged: null),
|
||||
);
|
||||
if (entity == null || entity.entityId.isEmpty) return;
|
||||
|
||||
final isOn = entity.state == 'on';
|
||||
if (isOn) {
|
||||
await service.turnOff(entityId);
|
||||
} else {
|
||||
await service.turnOn(entityId);
|
||||
}
|
||||
// Refresh state
|
||||
ref.invalidateSelf();
|
||||
}
|
||||
|
||||
Future<void> callScene(String entityId) async {
|
||||
final service = ref.read(haServiceProvider);
|
||||
if (service == null) return;
|
||||
await service.callService('scene', 'turn_on', entityId: entityId);
|
||||
ref.invalidateSelf();
|
||||
}
|
||||
|
||||
void refresh() => ref.invalidateSelf();
|
||||
}
|
||||
|
||||
class HaWeather {
|
||||
final double? temperature;
|
||||
final String? condition;
|
||||
final double? humidity;
|
||||
|
||||
const HaWeather({this.temperature, this.condition, this.humidity});
|
||||
|
||||
factory HaWeather.fromEntity(HaEntity entity) {
|
||||
final attrs = entity.attributes;
|
||||
return HaWeather(
|
||||
temperature: (attrs['temperature'] as num?)?.toDouble(),
|
||||
condition: entity.state,
|
||||
humidity: (attrs['humidity'] as num?)?.toDouble(),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user