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