diff --git a/assets/icons/1gang.svg b/assets/icons/1gang.svg
new file mode 100644
index 0000000..23dee22
--- /dev/null
+++ b/assets/icons/1gang.svg
@@ -0,0 +1,5 @@
+
diff --git a/lib/features/devices/bloc/one_gang_bloc/one_gang_bloc.dart b/lib/features/devices/bloc/one_gang_bloc/one_gang_bloc.dart
new file mode 100644
index 0000000..b92717d
--- /dev/null
+++ b/lib/features/devices/bloc/one_gang_bloc/one_gang_bloc.dart
@@ -0,0 +1,179 @@
+import 'dart:async';
+import 'package:firebase_database/firebase_database.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_state.dart';
+import 'package:syncrow_app/features/devices/model/device_control_model.dart';
+import 'package:syncrow_app/features/devices/model/device_model.dart';
+import 'package:syncrow_app/features/devices/model/one_gang_model.dart';
+import 'package:syncrow_app/features/devices/model/status_model.dart';
+import 'package:syncrow_app/services/api/devices_api.dart';
+import 'one_gang_event.dart';
+
+class OneGangBloc extends Bloc {
+ final String oneGangId;
+ OneGangModel deviceStatus = OneGangModel(
+ firstSwitch: false,
+ firstCountDown: 0,
+ );
+ Timer? _timer;
+
+ bool oneGangGroup = false;
+ List devicesList = [];
+ bool allSwitchesOn = true;
+
+ OneGangBloc({required this.oneGangId}) : super(InitialState()) {
+ on(_fetchTwoGangStatus);
+ on(_oneGangUpdated);
+ on(_changeFirstSwitch);
+ on(_changeSliding);
+ on(_setCounterValue);
+ on(_getCounterValue);
+ on(_onTickTimer);
+ on(_onClose);
+ }
+
+ void _fetchTwoGangStatus(InitialEvent event, Emitter emit) async {
+ emit(LoadingInitialState());
+ try {
+ var response = await DevicesAPI.getDeviceStatus(oneGangId);
+ List statusModelList = [];
+ for (var status in response['status']) {
+ statusModelList.add(StatusModel.fromJson(status));
+ }
+ deviceStatus = OneGangModel.fromJson(statusModelList);
+ emit(UpdateState(oneGangModel: deviceStatus));
+ _listenToChanges();
+ } catch (e) {
+ emit(FailedState(error: e.toString()));
+ return;
+ }
+ }
+
+ _listenToChanges() {
+ try {
+ DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$oneGangId');
+ Stream stream = ref.onValue;
+
+ stream.listen((DatabaseEvent event) async {
+ if (_timer != null) {
+ await Future.delayed(const Duration(seconds: 2));
+ }
+ Map usersMap = event.snapshot.value as Map;
+ List statusList = [];
+
+ usersMap['status'].forEach((element) {
+ statusList.add(StatusModel(code: element['code'], value: element['value']));
+ });
+
+ deviceStatus = OneGangModel.fromJson(statusList);
+ if (!isClosed) {
+ add(OneGangUpdated());
+ }
+ });
+ } catch (_) {}
+ }
+
+ _oneGangUpdated(OneGangUpdated event, Emitter emit) {
+ emit(UpdateState(oneGangModel: deviceStatus));
+ }
+
+ void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter emit) async {
+ emit(LoadingNewSate(oneGangModel: deviceStatus));
+ try {
+ deviceStatus.firstSwitch = !event.value;
+ emit(UpdateState(oneGangModel: deviceStatus));
+ if (_timer != null) {
+ _timer!.cancel();
+ }
+ _timer = Timer(const Duration(milliseconds: 500), () async {
+ final response = await DevicesAPI.controlDevice(
+ DeviceControlModel(
+ deviceId: oneGangGroup ? event.deviceId : oneGangId,
+ code: 'switch_1',
+ value: !event.value),
+ oneGangGroup ? event.deviceId : oneGangId);
+
+ if (!response['success']) {
+ add(InitialEvent(groupScreen: oneGangGroup));
+ }
+ });
+ } catch (_) {
+ add(InitialEvent(groupScreen: oneGangGroup));
+ }
+ }
+
+
+ void _changeSliding(ChangeSlidingSegment event, Emitter emit) async {
+ emit(ChangeSlidingSegmentState(value: event.value));
+ }
+
+ void _setCounterValue(SetCounterValue event, Emitter emit) async {
+ emit(LoadingNewSate(oneGangModel: deviceStatus));
+ int seconds = 0;
+ try {
+ seconds = event.duration.inSeconds;
+ final response = await DevicesAPI.controlDevice(
+ DeviceControlModel(deviceId: oneGangId, code: event.deviceCode, value: seconds),
+ oneGangId);
+
+ if (response['success'] ?? false) {
+ if (event.deviceCode == 'countdown_1') {
+ deviceStatus.firstCountDown = seconds;
+ }
+ } else {
+ emit(const FailedState(error: 'Something went wrong'));
+ return;
+ }
+ } catch (e) {
+ emit(FailedState(error: e.toString()));
+ return;
+ }
+ if (seconds > 0) {
+ _onStartTimer(seconds);
+ } else {
+ _timer?.cancel();
+ emit(TimerRunComplete());
+ }
+ }
+
+ void _getCounterValue(GetCounterEvent event, Emitter emit) async {
+ emit(LoadingInitialState());
+ try {
+ var response = await DevicesAPI.getDeviceStatus(oneGangId);
+ List statusModelList = [];
+ for (var status in response['status']) {
+ statusModelList.add(StatusModel.fromJson(status));
+ }
+ deviceStatus = OneGangModel.fromJson(statusModelList);
+
+ if (event.deviceCode == 'countdown_1') {
+ deviceStatus.firstCountDown > 0
+ ? _onStartTimer(deviceStatus.firstCountDown)
+ : emit(UpdateTimerState(seconds: deviceStatus.firstCountDown));
+ }
+ } catch (e) {
+ emit(FailedState(error: e.toString()));
+ return;
+ }
+ }
+
+ void _onClose(OnClose event, Emitter emit) {
+ _timer?.cancel();
+ }
+
+ void _onStartTimer(int seconds) {
+ _timer?.cancel();
+ _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
+ add(TickTimer(seconds - timer.tick));
+ });
+ }
+
+ void _onTickTimer(TickTimer event, Emitter emit) {
+ if (event.remainingTime > 0) {
+ emit(TimerRunInProgress(event.remainingTime));
+ } else {
+ _timer?.cancel();
+ emit(TimerRunComplete());
+ }
+ }
+}
diff --git a/lib/features/devices/bloc/one_gang_bloc/one_gang_event.dart b/lib/features/devices/bloc/one_gang_bloc/one_gang_event.dart
new file mode 100644
index 0000000..e245b39
--- /dev/null
+++ b/lib/features/devices/bloc/one_gang_bloc/one_gang_event.dart
@@ -0,0 +1,88 @@
+import 'package:equatable/equatable.dart';
+
+abstract class OneGangEvent extends Equatable {
+ const OneGangEvent();
+
+ @override
+ List