Settings loading refactored. WIP #338
This commit is contained in:
parent
d70ba0a55a
commit
ccb88884a7
@ -15,7 +15,8 @@
|
||||
<application
|
||||
android:name="io.flutter.app.FlutterApplication"
|
||||
android:label="HA Client"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:launchMode="singleTop"
|
||||
|
6
android/app/src/main/res/xml/network_security_config.xml
Normal file
6
android/app/src/main/res/xml/network_security_config.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<domain includeSubdomains="true">homemade.systems</domain>
|
||||
</domain-config>
|
||||
</network-security-config>
|
@ -1,7 +1,8 @@
|
||||
part of '../main.dart';
|
||||
|
||||
class AlarmControlPanelEntity extends Entity {
|
||||
AlarmControlPanelEntity(Map rawData) : super(rawData);
|
||||
AlarmControlPanelEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
|
||||
|
||||
@override
|
||||
Widget _buildAdditionalControlsForPage(BuildContext context) {
|
||||
|
@ -1,7 +1,8 @@
|
||||
part of '../main.dart';
|
||||
|
||||
class AutomationEntity extends Entity {
|
||||
AutomationEntity(Map rawData) : super(rawData);
|
||||
AutomationEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
|
||||
|
||||
@override
|
||||
Widget _buildStatePart(BuildContext context) {
|
||||
|
@ -1,7 +1,8 @@
|
||||
part of '../main.dart';
|
||||
|
||||
class ButtonEntity extends Entity {
|
||||
ButtonEntity(Map rawData) : super(rawData);
|
||||
ButtonEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
|
||||
|
||||
@override
|
||||
Widget _buildStatePart(BuildContext context) {
|
||||
|
@ -4,7 +4,7 @@ class CameraEntity extends Entity {
|
||||
|
||||
static const SUPPORT_ON_OFF = 1;
|
||||
|
||||
CameraEntity(Map rawData) : super(rawData);
|
||||
CameraEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
|
||||
bool get supportOnOff => ((supportedFeatures &
|
||||
CameraEntity.SUPPORT_ON_OFF) ==
|
||||
|
@ -23,6 +23,8 @@ class ClimateEntity extends Entity {
|
||||
static const SUPPORT_AUX_HEAT = 2048;
|
||||
static const SUPPORT_ON_OFF = 4096;
|
||||
|
||||
ClimateEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
|
||||
bool get supportTargetTemperature => ((supportedFeatures &
|
||||
ClimateEntity.SUPPORT_TARGET_TEMPERATURE) ==
|
||||
ClimateEntity.SUPPORT_TARGET_TEMPERATURE);
|
||||
@ -88,11 +90,9 @@ class ClimateEntity extends Entity {
|
||||
bool get isOff => state == EntityState.off;
|
||||
bool get auxHeat => attributes['aux_heat'] == "on";
|
||||
|
||||
ClimateEntity(Map rawData) : super(rawData);
|
||||
|
||||
@override
|
||||
void update(Map rawData) {
|
||||
super.update(rawData);
|
||||
void update(Map rawData, String webHost) {
|
||||
super.update(rawData, webHost);
|
||||
if (supportTargetTemperature) {
|
||||
historyConfig.numericAttributesToShow.add("temperature");
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ class CoverEntity extends Entity {
|
||||
static const SUPPORT_STOP_TILT = 64;
|
||||
static const SUPPORT_SET_TILT_POSITION = 128;
|
||||
|
||||
CoverEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
|
||||
bool get supportOpen => ((supportedFeatures &
|
||||
CoverEntity.SUPPORT_OPEN) ==
|
||||
CoverEntity.SUPPORT_OPEN);
|
||||
@ -45,8 +47,6 @@ class CoverEntity extends Entity {
|
||||
bool get canTiltBeOpened => currentTiltPosition < 100;
|
||||
bool get canTiltBeClosed => currentTiltPosition > 0;
|
||||
|
||||
CoverEntity(Map rawData) : super(rawData);
|
||||
|
||||
@override
|
||||
Widget _buildStatePart(BuildContext context) {
|
||||
return CoverStateWidget();
|
||||
|
@ -1,6 +1,8 @@
|
||||
part of '../main.dart';
|
||||
|
||||
class DateTimeEntity extends Entity {
|
||||
DateTimeEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
|
||||
bool get hasDate => attributes["has_date"] ?? false;
|
||||
bool get hasTime => attributes["has_time"] ?? false;
|
||||
int get year => attributes["year"] ?? 1970;
|
||||
@ -12,8 +14,6 @@ class DateTimeEntity extends Entity {
|
||||
String get formattedState => _getFormattedState();
|
||||
DateTime get dateTimeState => _getDateTimeState();
|
||||
|
||||
DateTimeEntity(Map rawData) : super(rawData);
|
||||
|
||||
@override
|
||||
Widget _buildStatePart(BuildContext context) {
|
||||
return DateTimeStateWidget();
|
||||
|
@ -73,6 +73,7 @@ class Entity {
|
||||
Map attributes;
|
||||
String domain;
|
||||
String entityId;
|
||||
String entityPicture;
|
||||
String state;
|
||||
String displayState;
|
||||
DateTime _lastUpdated;
|
||||
@ -94,7 +95,6 @@ class Entity {
|
||||
bool get isBadge => Entity.badgeDomains.contains(domain);
|
||||
String get icon => attributes["icon"] ?? "";
|
||||
bool get isOn => state == EntityState.on;
|
||||
String get entityPicture => _getEntityPictureUrl();
|
||||
String get unitOfMeasurement => attributes["unit_of_measurement"] ?? "";
|
||||
List get childEntityIds => attributes["entity_id"] ?? [];
|
||||
String get lastUpdated => _getLastUpdatedFormatted();
|
||||
@ -102,21 +102,21 @@ class Entity {
|
||||
double get doubleState => double.tryParse(state) ?? 0.0;
|
||||
int get supportedFeatures => attributes["supported_features"] ?? 0;
|
||||
|
||||
String _getEntityPictureUrl() {
|
||||
String _getEntityPictureUrl(String webHost) {
|
||||
String result = attributes["entity_picture"];
|
||||
if (result == null) return result;
|
||||
if (!result.startsWith("http")) {
|
||||
if (result.startsWith("/")) {
|
||||
result = "$homeAssistantWebHost$result";
|
||||
result = "$webHost$result";
|
||||
} else {
|
||||
result = "$homeAssistantWebHost/$result";
|
||||
result = "$webHost/$result";
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Entity(Map rawData) {
|
||||
update(rawData);
|
||||
Entity(Map rawData, String webHost) {
|
||||
update(rawData, webHost);
|
||||
}
|
||||
|
||||
Entity.missed(String entityId) {
|
||||
@ -148,7 +148,7 @@ class Entity {
|
||||
attributes = {"hidden": false, "friendly_name": "${name ?? url}", "icon": "${icon ?? 'mdi:link'}"};
|
||||
}
|
||||
|
||||
void update(Map rawData) {
|
||||
void update(Map rawData, String webHost) {
|
||||
attributes = rawData["attributes"] ?? {};
|
||||
domain = rawData["entity_id"].split(".")[0];
|
||||
entityId = rawData["entity_id"];
|
||||
@ -156,6 +156,7 @@ class Entity {
|
||||
state = rawData["state"];
|
||||
displayState = Entity.StateByDeviceClass["$deviceClass.$state"] ?? state;
|
||||
_lastUpdated = DateTime.tryParse(rawData["last_updated"]);
|
||||
entityPicture = _getEntityPictureUrl(webHost);
|
||||
}
|
||||
|
||||
double _getDoubleAttributeValue(String attributeName) {
|
||||
|
@ -6,7 +6,7 @@ class FanEntity extends Entity {
|
||||
static const SUPPORT_OSCILLATE = 2;
|
||||
static const SUPPORT_DIRECTION = 4;
|
||||
|
||||
FanEntity(Map rawData) : super(rawData);
|
||||
FanEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
|
||||
bool get supportSetSpeed => ((supportedFeatures &
|
||||
FanEntity.SUPPORT_SET_SPEED) ==
|
||||
|
@ -1,12 +1,13 @@
|
||||
part of '../main.dart';
|
||||
|
||||
class GroupEntity extends Entity {
|
||||
GroupEntity(Map rawData) : super(rawData);
|
||||
|
||||
final List<String> _domainsForSwitchableGroup = ["switch", "light", "automation", "input_boolean"];
|
||||
String mutualDomain;
|
||||
bool switchable = false;
|
||||
|
||||
GroupEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
|
||||
@override
|
||||
Widget _buildStatePart(BuildContext context) {
|
||||
if (switchable) {
|
||||
@ -19,8 +20,8 @@ class GroupEntity extends Entity {
|
||||
}
|
||||
|
||||
@override
|
||||
void update(Map rawData) {
|
||||
super.update(rawData);
|
||||
void update(Map rawData, String webHost) {
|
||||
super.update(rawData, webHost);
|
||||
if (_isOneDomain()) {
|
||||
mutualDomain = attributes['entity_id'][0].split(".")[0];
|
||||
switchable = _domainsForSwitchableGroup.contains(mutualDomain);
|
||||
|
@ -42,7 +42,7 @@ class LightEntity extends Entity {
|
||||
bool get isAdditionalControls => ((supportedFeatures != null) && (supportedFeatures != 0));
|
||||
List<String> get effectList => getStringListAttributeValue("effect_list");
|
||||
|
||||
LightEntity(Map rawData) : super(rawData);
|
||||
LightEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
|
||||
HSVColor _getColor() {
|
||||
List hs = attributes["hs_color"];
|
||||
|
@ -1,7 +1,7 @@
|
||||
part of '../main.dart';
|
||||
|
||||
class LockEntity extends Entity {
|
||||
LockEntity(Map rawData) : super(rawData);
|
||||
LockEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
|
||||
bool get isLocked => state == "locked";
|
||||
|
||||
|
@ -20,7 +20,7 @@ class MediaPlayerEntity extends Entity {
|
||||
static const SUPPORT_SHUFFLE_SET = 32768;
|
||||
static const SUPPORT_SELECT_SOUND_MODE = 65536;
|
||||
|
||||
MediaPlayerEntity(Map rawData) : super(rawData);
|
||||
MediaPlayerEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
|
||||
bool get supportPause => ((supportedFeatures &
|
||||
MediaPlayerEntity.SUPPORT_PAUSE) ==
|
||||
|
@ -1,7 +1,7 @@
|
||||
part of '../main.dart';
|
||||
|
||||
class SunEntity extends Entity {
|
||||
SunEntity(Map rawData) : super(rawData);
|
||||
SunEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
}
|
||||
|
||||
class SensorEntity extends Entity {
|
||||
@ -12,6 +12,6 @@ class SensorEntity extends Entity {
|
||||
numericState: true
|
||||
);
|
||||
|
||||
SensorEntity(Map rawData) : super(rawData);
|
||||
SensorEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
|
||||
}
|
@ -5,7 +5,7 @@ class SelectEntity extends Entity {
|
||||
? (attributes["options"] as List).cast<String>()
|
||||
: [];
|
||||
|
||||
SelectEntity(Map rawData) : super(rawData);
|
||||
SelectEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
|
||||
@override
|
||||
Widget _buildStatePart(BuildContext context) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
part of '../main.dart';
|
||||
|
||||
class SliderEntity extends Entity {
|
||||
SliderEntity(Map rawData) : super(rawData);
|
||||
SliderEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
|
||||
double get minValue => _getDoubleAttributeValue("min") ?? 0.0;
|
||||
double get maxValue =>_getDoubleAttributeValue("max") ?? 100.0;
|
||||
|
@ -1,7 +1,7 @@
|
||||
part of '../main.dart';
|
||||
|
||||
class SwitchEntity extends Entity {
|
||||
SwitchEntity(Map rawData) : super(rawData);
|
||||
SwitchEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
|
||||
@override
|
||||
Widget _buildStatePart(BuildContext context) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
part of '../main.dart';
|
||||
|
||||
class TextEntity extends Entity {
|
||||
TextEntity(Map rawData) : super(rawData);
|
||||
TextEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
|
||||
int get valueMinLength => attributes["min"] ?? -1;
|
||||
int get valueMaxLength => attributes["max"] ?? -1;
|
||||
|
@ -1,13 +1,13 @@
|
||||
part of '../main.dart';
|
||||
|
||||
class TimerEntity extends Entity {
|
||||
TimerEntity(Map rawData) : super(rawData);
|
||||
TimerEntity(Map rawData, String webHost) : super(rawData, webHost);
|
||||
|
||||
Duration duration;
|
||||
|
||||
@override
|
||||
void update(Map rawData) {
|
||||
super.update(rawData);
|
||||
void update(Map rawData, String webHost) {
|
||||
super.update(rawData, webHost);
|
||||
String durationSource = "${attributes["duration"]}";
|
||||
if (durationSource != null && durationSource.isNotEmpty) {
|
||||
try {
|
||||
|
@ -2,13 +2,15 @@ part of 'main.dart';
|
||||
|
||||
class EntityCollection {
|
||||
|
||||
final homeAssistantWebHost;
|
||||
|
||||
Map<String, Entity> _allEntities;
|
||||
//Map<String, Entity> views;
|
||||
|
||||
bool get isEmpty => _allEntities.isEmpty;
|
||||
List<Entity> get viewEntities => _allEntities.values.where((entity) => entity.isView).toList();
|
||||
|
||||
EntityCollection() {
|
||||
EntityCollection(this.homeAssistantWebHost) {
|
||||
_allEntities = {};
|
||||
//views = {};
|
||||
}
|
||||
@ -36,67 +38,67 @@ class EntityCollection {
|
||||
Entity _createEntityInstance(rawEntityData) {
|
||||
switch (rawEntityData["entity_id"].split(".")[0]) {
|
||||
case 'sun': {
|
||||
return SunEntity(rawEntityData);
|
||||
return SunEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
case "media_player": {
|
||||
return MediaPlayerEntity(rawEntityData);
|
||||
return MediaPlayerEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
case 'sensor': {
|
||||
return SensorEntity(rawEntityData);
|
||||
return SensorEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
case 'lock': {
|
||||
return LockEntity(rawEntityData);
|
||||
return LockEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
case "automation": {
|
||||
return AutomationEntity(rawEntityData);
|
||||
return AutomationEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
|
||||
case "input_boolean":
|
||||
case "switch": {
|
||||
return SwitchEntity(rawEntityData);
|
||||
return SwitchEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
case "light": {
|
||||
return LightEntity(rawEntityData);
|
||||
return LightEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
case "group": {
|
||||
return GroupEntity(rawEntityData);
|
||||
return GroupEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
case "script":
|
||||
case "scene": {
|
||||
return ButtonEntity(rawEntityData);
|
||||
return ButtonEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
case "input_datetime": {
|
||||
return DateTimeEntity(rawEntityData);
|
||||
return DateTimeEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
case "input_select": {
|
||||
return SelectEntity(rawEntityData);
|
||||
return SelectEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
case "input_number": {
|
||||
return SliderEntity(rawEntityData);
|
||||
return SliderEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
case "input_text": {
|
||||
return TextEntity(rawEntityData);
|
||||
return TextEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
case "climate": {
|
||||
return ClimateEntity(rawEntityData);
|
||||
return ClimateEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
case "cover": {
|
||||
return CoverEntity(rawEntityData);
|
||||
return CoverEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
case "fan": {
|
||||
return FanEntity(rawEntityData);
|
||||
return FanEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
case "camera": {
|
||||
return CameraEntity(rawEntityData);
|
||||
return CameraEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
case "alarm_control_panel": {
|
||||
return AlarmControlPanelEntity(rawEntityData);
|
||||
return AlarmControlPanelEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
case "timer": {
|
||||
return TimerEntity(rawEntityData);
|
||||
return TimerEntity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
default: {
|
||||
return Entity(rawEntityData);
|
||||
return Entity(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -121,7 +123,7 @@ class EntityCollection {
|
||||
}
|
||||
|
||||
void updateFromRaw(Map rawEntityData) {
|
||||
get("${rawEntityData["entity_id"]}")?.update(rawEntityData);
|
||||
get("${rawEntityData["entity_id"]}")?.update(rawEntityData, homeAssistantWebHost);
|
||||
}
|
||||
|
||||
Entity get(String entityId) {
|
||||
|
@ -16,6 +16,7 @@ class _CameraStreamViewState extends State<CameraStreamView> {
|
||||
}
|
||||
|
||||
CameraEntity _entity;
|
||||
String _webHost;
|
||||
|
||||
http.Client client;
|
||||
http.StreamedResponse response;
|
||||
@ -28,7 +29,7 @@ class _CameraStreamViewState extends State<CameraStreamView> {
|
||||
void _connect() async {
|
||||
started = true;
|
||||
timeToStop = false;
|
||||
String streamUrl = '$homeAssistantWebHost/api/camera_proxy_stream/${_entity.entityId}?token=${_entity.attributes['access_token']}';
|
||||
String streamUrl = '$_webHost/api/camera_proxy_stream/${_entity.entityId}?token=${_entity.attributes['access_token']}';
|
||||
client = new http.Client(); // create a client to make api calls
|
||||
http.Request request = new http.Request("GET", Uri.parse(streamUrl)); // create get request
|
||||
Logger.d("[Sending] ==> $streamUrl");
|
||||
@ -130,6 +131,7 @@ class _CameraStreamViewState extends State<CameraStreamView> {
|
||||
.of(context)
|
||||
.entityWrapper
|
||||
.entity;
|
||||
_webHost = HomeAssistantModel.of(context).homeAssistant.httpAPIEndpoint;
|
||||
_connect();
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ class MediaPlayerWidget extends StatelessWidget {
|
||||
|
||||
Widget _buildImage(MediaPlayerEntity entity) {
|
||||
String state = entity.state;
|
||||
if (homeAssistantWebHost != null && entity.entityPicture != null && state != EntityState.off && state != EntityState.unavailable && state != EntityState.idle) {
|
||||
if (entity.entityPicture != null && state != EntityState.off && state != EntityState.unavailable && state != EntityState.idle) {
|
||||
return Container(
|
||||
color: Colors.black,
|
||||
child: Row(
|
||||
|
@ -2,8 +2,10 @@ part of 'main.dart';
|
||||
|
||||
class HomeAssistant {
|
||||
String _webSocketAPIEndpoint;
|
||||
String httpAPIEndpoint;
|
||||
String _password;
|
||||
bool _useLovelace = false;
|
||||
bool isSettingsLoaded = false;
|
||||
|
||||
IOWebSocketChannel _hassioChannel;
|
||||
SendMessageQueue _messageQueue;
|
||||
@ -15,6 +17,7 @@ class HomeAssistant {
|
||||
HomeAssistantUI ui;
|
||||
Map _instanceConfig = {};
|
||||
String _userName;
|
||||
String hostname;
|
||||
HSVColor savedColor;
|
||||
|
||||
Map _rawLovelaceData;
|
||||
@ -45,10 +48,27 @@ class HomeAssistant {
|
||||
//int get viewsCount => entities.views.length ?? 0;
|
||||
|
||||
HomeAssistant() {
|
||||
entities = EntityCollection();
|
||||
_messageQueue = SendMessageQueue(messageExpirationTime);
|
||||
}
|
||||
|
||||
Future loadConnectionSettings() async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
String domain = prefs.getString('hassio-domain');
|
||||
String port = prefs.getString('hassio-port');
|
||||
hostname = "$domain:$port";
|
||||
_webSocketAPIEndpoint = "${prefs.getString('hassio-protocol')}://$domain:$port/api/websocket";
|
||||
httpAPIEndpoint = "${prefs.getString('hassio-res-protocol')}://$domain:$port";
|
||||
_password = prefs.getString('hassio-password');
|
||||
_useLovelace = prefs.getBool('use-lovelace') ?? true;
|
||||
if ((domain == null) || (port == null) || (_password == null) ||
|
||||
(domain.length == 0) || (port.length == 0) || (_password.length == 0)) {
|
||||
throw("Check connection settings");
|
||||
} else {
|
||||
isSettingsLoaded = true;
|
||||
entities = EntityCollection(httpAPIEndpoint);
|
||||
}
|
||||
}
|
||||
|
||||
void updateSettings(String url, String password, bool useLovelace) {
|
||||
_webSocketAPIEndpoint = url;
|
||||
_password = password;
|
||||
@ -555,7 +575,7 @@ class HomeAssistant {
|
||||
}
|
||||
}
|
||||
|
||||
Widget buildViews(BuildContext context, bool lovelace, TabController tabController) {
|
||||
Widget buildViews(BuildContext context, TabController tabController) {
|
||||
return ui.build(context, tabController);
|
||||
}
|
||||
|
||||
@ -563,7 +583,7 @@ class HomeAssistant {
|
||||
DateTime now = DateTime.now();
|
||||
//String endTime = formatDate(now, [yyyy, '-', mm, '-', dd, 'T', HH, ':', nn, ':', ss, z]);
|
||||
String startTime = formatDate(now.subtract(Duration(hours: 24)), [yyyy, '-', mm, '-', dd, 'T', HH, ':', nn, ':', ss, z]);
|
||||
String url = "$homeAssistantWebHost/api/history/period/$startTime?&filter_entity_id=$entityId";
|
||||
String url = "$httpAPIEndpoint/api/history/period/$startTime?&filter_entity_id=$entityId";
|
||||
Logger.d("[Sending] ==> $url");
|
||||
http.Response historyResponse;
|
||||
historyResponse = await http.get(url, headers: {
|
||||
@ -580,7 +600,7 @@ class HomeAssistant {
|
||||
}
|
||||
|
||||
Future sendHTTPRequest(String data) async {
|
||||
String url = "$homeAssistantWebHost/api/notify.fcm-android";
|
||||
String url = "$httpAPIEndpoint/api/notify.fcm-android";
|
||||
Logger.d("[Sending] ==> $url");
|
||||
http.Response response;
|
||||
response = await http.post(
|
||||
|
@ -18,6 +18,7 @@ import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:flutter_custom_tabs/flutter_custom_tabs.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
|
||||
|
||||
part 'entity_class/const.dart';
|
||||
part 'entity_class/entity.class.dart';
|
||||
@ -103,7 +104,7 @@ EventBus eventBus = new EventBus();
|
||||
const String appName = "HA Client";
|
||||
const appVersion = "0.5.2";
|
||||
|
||||
String homeAssistantWebHost;
|
||||
//String homeAssistantWebHost;
|
||||
|
||||
void main() {
|
||||
FlutterError.onError = (errorDetails) {
|
||||
@ -156,29 +157,28 @@ class MainPage extends StatefulWidget {
|
||||
class _MainPageState extends State<MainPage> with WidgetsBindingObserver, TickerProviderStateMixin {
|
||||
HomeAssistant _homeAssistant;
|
||||
//Map _instanceConfig;
|
||||
String _webSocketApiEndpoint;
|
||||
String _password;
|
||||
//String _webSocketApiEndpoint;
|
||||
//String _password;
|
||||
//int _uiViewsCount = 0;
|
||||
String _instanceHost;
|
||||
//String _instanceHost;
|
||||
StreamSubscription _stateSubscription;
|
||||
StreamSubscription _settingsSubscription;
|
||||
StreamSubscription _serviceCallSubscription;
|
||||
StreamSubscription _showEntityPageSubscription;
|
||||
StreamSubscription _showErrorSubscription;
|
||||
bool _settingsLoaded = false;
|
||||
//bool _settingsLoaded = false;
|
||||
bool _accountMenuExpanded = false;
|
||||
bool _useLovelaceUI;
|
||||
//bool _useLovelaceUI;
|
||||
int _previousViewCount;
|
||||
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_settingsLoaded = false;
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
|
||||
Logger.d("<!!!> Creating new HomeAssistant instance");
|
||||
_homeAssistant = HomeAssistant();
|
||||
//_settingsLoaded = false;
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
|
||||
_settingsSubscription = eventBus.on<SettingsChangedEvent>().listen((event) {
|
||||
Logger.d("Settings change event: reconnect=${event.reconnect}");
|
||||
@ -193,7 +193,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
}
|
||||
|
||||
void _initialLoad() {
|
||||
_loadConnectionSettings().then((_){
|
||||
_homeAssistant.loadConnectionSettings().then((_){
|
||||
_subscribe();
|
||||
_refreshData();
|
||||
}, onError: (_) {
|
||||
@ -203,13 +203,13 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
Logger.d("$state");
|
||||
if (state == AppLifecycleState.resumed && _settingsLoaded) {
|
||||
//Logger.d("$state");
|
||||
if (state == AppLifecycleState.resumed && _homeAssistant.isSettingsLoaded) {
|
||||
_refreshData();
|
||||
}
|
||||
}
|
||||
|
||||
_loadConnectionSettings() async {
|
||||
/*_loadConnectionSettings() async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
String domain = prefs.getString('hassio-domain');
|
||||
String port = prefs.getString('hassio-port');
|
||||
@ -224,7 +224,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
} else {
|
||||
_settingsLoaded = true;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
_subscribe() {
|
||||
if (_stateSubscription == null) {
|
||||
@ -258,7 +258,8 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
});
|
||||
}
|
||||
|
||||
/*_firebaseMessaging.getToken().then((String token) {
|
||||
_firebaseMessaging.getToken().then((String token) {
|
||||
//Logger.d("FCM token: $token");
|
||||
_homeAssistant.sendHTTPRequest('{"token": "$token"}');
|
||||
});
|
||||
_firebaseMessaging.configure(
|
||||
@ -271,11 +272,11 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
onResume: (data) {
|
||||
Logger.d("Notification [onResume]: $data");
|
||||
}
|
||||
);*/
|
||||
);
|
||||
}
|
||||
|
||||
_refreshData() async {
|
||||
_homeAssistant.updateSettings(_webSocketApiEndpoint, _password, _useLovelaceUI);
|
||||
//_homeAssistant.updateSettings(_webSocketApiEndpoint, _password, _useLovelaceUI);
|
||||
_hideBottomBar();
|
||||
_showInfoBottomBar(progress: true,);
|
||||
await _homeAssistant.fetch().then((result) {
|
||||
@ -342,7 +343,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
menuItems.add(
|
||||
UserAccountsDrawerHeader(
|
||||
accountName: Text(_homeAssistant.userName),
|
||||
accountEmail: Text(_instanceHost ?? "Not configured"),
|
||||
accountEmail: Text(_homeAssistant.hostname ?? "Not configured"),
|
||||
onDetailsPressed: () {
|
||||
setState(() {
|
||||
_accountMenuExpanded = !_accountMenuExpanded;
|
||||
@ -387,7 +388,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
new ListTile(
|
||||
leading: Icon(MaterialDesignIcons.getIconDataFromIconName("mdi:home-assistant")),
|
||||
title: Text("Open Web UI"),
|
||||
onTap: () => HAUtils.launchURL(homeAssistantWebHost),
|
||||
onTap: () => HAUtils.launchURL(_homeAssistant.httpAPIEndpoint),
|
||||
),
|
||||
Divider()
|
||||
]);
|
||||
@ -631,7 +632,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
||||
),
|
||||
)
|
||||
:
|
||||
_homeAssistant.buildViews(context, _useLovelaceUI, _viewsTabController),
|
||||
_homeAssistant.buildViews(context, _viewsTabController),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,21 @@ class _ConnectionSettingsPageState extends State<ConnectionSettingsPage> {
|
||||
bool _useLovelace = true;
|
||||
bool _newUseLovelace = true;
|
||||
|
||||
String oauthUrl;
|
||||
final flutterWebviewPlugin = new FlutterWebviewPlugin();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadSettings();
|
||||
flutterWebviewPlugin.onUrlChanged.listen((String url) {
|
||||
Logger.d("Launched url: $url");
|
||||
if (url.startsWith("http://ha-client.homemade.systems/service/auth_callback.html")) {
|
||||
String authCode = url.split("=")[1];
|
||||
Logger.d("Auth code: $authCode");
|
||||
flutterWebviewPlugin.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_loadSettings() async {
|
||||
@ -40,6 +51,8 @@ class _ConnectionSettingsPageState extends State<ConnectionSettingsPage> {
|
||||
} catch (e) {
|
||||
_useLovelace = _newUseLovelace = true;
|
||||
}
|
||||
oauthUrl = "${ _newSocketProtocol == "wss" ? "https" : "http"}://$_newHassioDomain:${_newHassioPort ?? ''}/auth/authorize?client_id=${Uri.encodeComponent('http://ha-client.homemade.systems/')}&redirect_uri=${Uri.encodeComponent('http://ha-client.homemade.systems/service/auth_callback.html')}";
|
||||
Logger.d("OAuth url: $oauthUrl");
|
||||
});
|
||||
}
|
||||
|
||||
@ -67,6 +80,24 @@ class _ConnectionSettingsPageState extends State<ConnectionSettingsPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget webViewButton;
|
||||
if (oauthUrl != null) {
|
||||
webViewButton = FlatButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) => WebviewScaffold(
|
||||
url: oauthUrl,
|
||||
appBar: new AppBar(
|
||||
title: new Text("Login"),
|
||||
)
|
||||
)
|
||||
));
|
||||
},
|
||||
child: Text("Login with Home Assistant")
|
||||
);
|
||||
} else {
|
||||
webViewButton = Container(height: 0.0,);
|
||||
}
|
||||
return new Scaffold(
|
||||
appBar: new AppBar(
|
||||
leading: IconButton(icon: Icon(Icons.arrow_back), onPressed: (){
|
||||
@ -149,6 +180,7 @@ class _ConnectionSettingsPageState extends State<ConnectionSettingsPage> {
|
||||
"Try ports 80 and 443 if default is not working and you don't know why.",
|
||||
style: TextStyle(color: Colors.grey),
|
||||
),
|
||||
webViewButton,
|
||||
new TextField(
|
||||
decoration: InputDecoration(
|
||||
labelText: "Access token"
|
||||
|
@ -36,7 +36,8 @@ class Panel {
|
||||
)
|
||||
);
|
||||
} else {
|
||||
String url = "$homeAssistantWebHost/$urlPath";
|
||||
HomeAssistantModel haModel = HomeAssistantModel.of(context);
|
||||
String url = "${haModel.homeAssistant.httpAPIEndpoint}/$urlPath";
|
||||
Logger.d("Launching custom tab with $url");
|
||||
HAUtils.launchURLInCustomTab(context, url);
|
||||
}
|
||||
|
@ -153,6 +153,13 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_webview_plugin:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_webview_plugin
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.1"
|
||||
http:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -21,6 +21,7 @@ dependencies:
|
||||
flutter_svg: ^0.10.3
|
||||
flutter_custom_tabs: ^0.6.0
|
||||
firebase_messaging: ^4.0.0+1
|
||||
flutter_webview_plugin: ^0.3.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
Reference in New Issue
Block a user