Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for phone as a security camera #691

Merged
merged 6 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .idea/CBJ_App.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 33
compileSdkVersion 34

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
Expand All @@ -45,7 +45,7 @@ android {

defaultConfig {
applicationId "com.cybear_jinni.smart_home"
minSdkVersion 19
minSdkVersion 22
targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
Expand Down
39 changes: 35 additions & 4 deletions lib/application/hub_in_network/hub_in_network_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import 'dart:async';

import 'package:auto_route/auto_route.dart';
import 'package:bloc/bloc.dart';
import 'package:cybear_jinni/domain/device/devices_failures.dart';
import 'package:cbj_integrations_controller/infrastructure/generic_devices/abstract_device/device_entity_abstract.dart';
import 'package:cybear_jinni/domain/device/devices_failures.dart';
import 'package:cybear_jinni/domain/hub/hub_failures.dart';
import 'package:cybear_jinni/domain/hub/i_hub_connection_repository.dart';
import 'package:cybear_jinni/presentation/pages/routes/app_router.gr.dart';
import 'package:dartz/dartz.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:injectable/injectable.dart';
import 'package:kt_dart/kt.dart';
Expand All @@ -23,6 +24,7 @@ class HubInNetworkBloc extends Bloc<HubInNetworkEvent, HubInNetworkState> {
: super(HubInNetworkState.initial()) {
on<InitialEvent>(_initialEvent);
on<SearchHubInNetwork>(_searchHubInNetwork);
on<OpenSmartCameraPage>(_openSmartCameraPage);
on<SearchHubUsingAnyIpOnTheNetwork>(_searchHubUsingAnyIpOnTheNetwork);
on<IsHubIpCheckBoxChangedState>(_isHubIpCheckBoxChangedState);
}
Expand All @@ -32,6 +34,7 @@ class HubInNetworkBloc extends Bloc<HubInNetworkEvent, HubInNetworkState> {
_deviceStreamSubscription;

BuildContext? context;
static bool loading = false;

Future<void> _initialEvent(
InitialEvent event,
Expand All @@ -45,14 +48,24 @@ class HubInNetworkBloc extends Bloc<HubInNetworkEvent, HubInNetworkState> {
SearchHubInNetwork event,
Emitter<HubInNetworkState> emit,
) async {
loading = true;
emit(const HubInNetworkState.loadInProgress());
emit(
(await _hubConnectionRepository.searchForHub())
.fold((l) => HubInNetworkState.loadFailure(l), (r) {
await (await _hubConnectionRepository.searchForHub()).fold((l) async {
return (await _searchSmartDevices()).fold(
(HubFailures l) => HubInNetworkState.loadFailure(l),
(r) => HubInNetworkState.loadSuccessSecurityCamera(r),
);
}, (r) {
context?.router.replace(const HomeRoute());
return const HubInNetworkState.loadSuccess();
}),
);
loading = false;
}

Future<Either<HubFailures, String>> _searchSmartDevices() {
return _hubConnectionRepository.containsSmartDevice();
}

Future<void> _searchHubUsingAnyIpOnTheNetwork(
Expand All @@ -79,6 +92,24 @@ class HubInNetworkBloc extends Bloc<HubInNetworkEvent, HubInNetworkState> {
emit(HubInNetworkState.tryIpManually(event.ipOnTheNetwork, event.isHubIp));
}

Future<void> _openSmartCameraPage(
OpenSmartCameraPage event,
Emitter<HubInNetworkState> emit,
) async {
if (loading) {
Fluttertoast.showToast(
msg: 'Wait until search completes',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
backgroundColor: Colors.blueGrey,
textColor: Theme.of(event.context).textTheme.bodyLarge!.color,
fontSize: 16.0,
);
return;
}
event.context.router.push(const SmartCameraContainerRoute());
}

@override
Future<void> close() async {
await _deviceStreamSubscription?.cancel();
Expand Down
3 changes: 3 additions & 0 deletions lib/application/hub_in_network/hub_in_network_event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ class HubInNetworkEvent with _$HubInNetworkEvent {

const factory HubInNetworkEvent.searchHubInNetwork() = SearchHubInNetwork;

const factory HubInNetworkEvent.openSmartCameraPage(BuildContext context) =
OpenSmartCameraPage;

const factory HubInNetworkEvent.searchHubUsingAnyIpOnTheNetwork(
String ipOnTheNetwork,
bool isHubIp,
Expand Down
3 changes: 3 additions & 0 deletions lib/application/hub_in_network/hub_in_network_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ class HubInNetworkState with _$HubInNetworkState {

const factory HubInNetworkState.loadSuccess() = _loadSuccess;

const factory HubInNetworkState.loadSuccessSecurityCamera(String address) =
loadSuccessSecurityCamera;

const factory HubInNetworkState.tryIpManually(
String ipOnTheNetwork,
bool isHubIp,
Expand Down
1 change: 0 additions & 1 deletion lib/domain/device/i_device_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import 'dart:async';
import 'package:cbj_integrations_controller/domain/room/room_entity.dart';
import 'package:cbj_integrations_controller/infrastructure/generic_devices/abstract_device/device_entity_abstract.dart';
import 'package:cybear_jinni/domain/device/devices_failures.dart';
import 'package:cbj_integrations_controller/infrastructure/generic_devices/abstract_device/device_entity_abstract.dart';
import 'package:dartz/dartz.dart';
import 'package:flutter/widgets.dart';
import 'package:kt_dart/kt.dart';
Expand Down
2 changes: 2 additions & 0 deletions lib/domain/hub/i_hub_connection_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,7 @@ abstract class IHubConnectionRepository {
bool? isThatTheIpOfTheHub,
});

Future<Either<HubFailures, String>> containsSmartDevice();

Future<void> saveHubIP(String hubIP);
}
2 changes: 1 addition & 1 deletion lib/infrastructure/devices/device/device_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class DeviceRepository implements IDeviceRepository {

@override
Future<void> initiateHubConnection() async {
AppRequestsToHub.lisenToApp();
AppRequestsToHub.listenToApp();
HubRequestsToApp.lisenToApp();

HubRequestRouting.navigateRequest();
Expand Down
2 changes: 1 addition & 1 deletion lib/infrastructure/hub_client/hub_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class AppRequestsToHub {
static final appRequestsToHubStreamController =
StreamController<ClientStatusRequests>();

static Future<void> lisenToApp() async {
static Future<void> listenToApp() async {
if (boolListenWorking) {
return;
}
Expand Down
90 changes: 86 additions & 4 deletions lib/infrastructure/hub_client/hub_connection_repository.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import 'dart:async';
import 'dart:io';

import 'package:cbj_integrations_controller/domain/local_db/i_local_devices_db_repository.dart';
import 'package:cbj_integrations_controller/domain/local_db/local_db_failures.dart';
import 'package:cbj_integrations_controller/infrastructure/gen/cbj_hub_server/protoc_as_dart/cbj_hub_server.pbgrpc.dart';
import 'package:cbj_integrations_controller/utils.dart';
import 'package:cbj_smart_device/application/usecases/smart_server_u/smart_server_u.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:cybear_jinni/domain/hub/hub_entity.dart';
import 'package:cybear_jinni/domain/hub/hub_failures.dart';
Expand Down Expand Up @@ -84,7 +86,6 @@ class HubConnectionRepository extends IHubConnectionRepository {
} catch (e) {
logger.w("Can't get WiFi BSSID");
}
;
final Either<LocalDbFailures, String> remotePipesInformation =
await ILocalDbRepository.instance.getRemotePipesDnsName();

Expand All @@ -103,7 +104,7 @@ class HubConnectionRepository extends IHubConnectionRepository {
connectivityResult == ConnectivityResult.ethernet &&
savedWifiBssidWithoutLastNumber == 'no:Network:Bssid') ||
(kIsWeb && savedWifiBssidWithoutLastNumber == 'no:Network:Bssid')) {
(await OpenAndroidWifiSettingIfPosiible()).fold(
(await openAndroidWifiSettingIfPossible()).fold(
(l) {
logger
.w('No way to establish connection with the Hub, WiFi or location'
Expand Down Expand Up @@ -529,7 +530,7 @@ class HubConnectionRepository extends IHubConnectionRepository {
Future<void> connectionUsingRemotePipes() async {
(await ILocalDbRepository.instance.getRemotePipesDnsName()).fold(
(l) async {
(await OpenAndroidWifiSettingIfPosiible()).fold(
(await openAndroidWifiSettingIfPossible()).fold(
(l) {
logger.w(
'No way to establish connection with the Hub, WiFi or location'
Expand All @@ -548,7 +549,7 @@ class HubConnectionRepository extends IHubConnectionRepository {
);
}

Future<Either<HubFailures, Unit>> OpenAndroidWifiSettingIfPosiible() async {
Future<Either<HubFailures, Unit>> openAndroidWifiSettingIfPossible() async {
final bool wifiEnabled = await WiFiForIoTPlugin.isEnabled();
final Location location = Location();

Expand Down Expand Up @@ -602,4 +603,85 @@ class HubConnectionRepository extends IHubConnectionRepository {
}
return const Left(HubFailures.unexpected());
}

@override
Future<Either<HubFailures, String>> containsSmartDevice() async {
String? currentDeviceIP;
try {
final NetworkInfo networkInfo = NetworkInfo();
currentDeviceIP = await networkInfo.getWifiIP();

if (currentDeviceIP == null) {
return left(const HubFailures.cantFindHubInNetwork());
}

final String subnet =
currentDeviceIP.substring(0, currentDeviceIP.lastIndexOf('.'));

logger.i('CBJ smart camera search subnet IP $subnet');

final Stream<ActiveHost> devicesWithPort =
HostScanner.scanDevicesForSinglePort(
subnet,
CbjSmartDeviceServerU.port,

/// TODO: return this settings when can use with the await for loop
// resultsInIpAscendingOrder: false,
timeout: const Duration(milliseconds: 600),
);

await for (final ActiveHost activeHost in devicesWithPort) {
logger.i('Found CBJ Smart security camera: ${activeHost.address}');
return right(activeHost.address);
}
} catch (e) {
logger.w('Exception searchForHub\n$e');
}

// TODO: Create support for all types
// final Future<List<ActiveHost>> mdnsDevices =
// CompaniesConnectorConjector.searchMdnsDevices();
//
// final Future<List<ActiveHost>> pingableDevices =
// CompaniesConnectorConjector.searchPingableDevices();

// final List<Stream<dynamic>> socketBindingsList =
// CompaniesConnectorConjector.findDevicesByBindingIntoSockets();
//
// final List<StreamSubscription> listenToSocketBinding = [];
// for (final Stream<dynamic> socketBinding in socketBindingsList) {
// listenToSocketBinding.add(
// socketBinding.listen((switcherApiObject) {
// // TODO: Make it work with all types and not just SwitcherApiObject
// getIt<SwitcherConnectorConjector>()
// .addOnlyNewSwitcherDevice(switcherApiObject as SwitcherApiObject);
// }),
// );
// }
//
// for (final StreamSubscription socketBindingSubscription
// in listenToSocketBinding) {
// await socketBindingSubscription.cancel();
// }

// try {
// for (final ActiveHost activeHost in await mdnsDevices) {
// CompaniesConnectorConjector.setMdnsDeviceByCompany(activeHost);
// }
// } catch (e) {
// logger.e('Mdns search error\n$e');
// }
//
// for (final ActiveHost activeHost in await pingableDevices) {
// try {
// CompaniesConnectorConjector.setHostNameDeviceByCompany(
// activeHost: activeHost,
// );
// } catch (e) {
// continue;
// }
// } r

return left(const HubFailures.cantFindHubInNetwork());
}
}
4 changes: 4 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:network_tools/network_tools.dart';
import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart';

Expand Down Expand Up @@ -48,6 +50,8 @@ Future<Unit> main() async {
configureInjection(Env.devPc);

WidgetsFlutterBinding.ensureInitialized();
final appDocDirectory = await getApplicationDocumentsDirectory();
await configureNetworkTools(appDocDirectory.path, enableDebugging: true);
HiveRepository();
getIt<ILocalDbRepository2>();
getIt.registerSingleton<AppRouter>(AppRouter());
Expand Down
Loading