बाहरी डिवाइसों को कंट्रोल करना

Android 11 और इसके बाद के वर्शन में, डिवाइसों को तुरंत ऐक्सेस करने की सुविधा मिलती है. इसकी मदद से उपयोगकर्ता, लाइट, थर्मोस्टैट, और कैमरे जैसे बाहरी डिवाइसों को तुरंत देख और कंट्रोल कर सकते हैं. इसके लिए, उन्हें डिफ़ॉल्ट लॉन्चर से तीन बार इंटरैक्ट करना होता है. डिवाइस बनाने वाली कंपनी यह तय करती है कि कौनसे लॉन्चर का इस्तेमाल किया जाएगा. डिवाइस एग्रीगेटर—उदाहरण के लिए, Google Home—और तीसरे पक्ष के वेंडर ऐप्लिकेशन, इस स्पेस में डिसप्ले के लिए डिवाइस उपलब्ध करा सकते हैं. इस पेज पर बताया गया है कि इस स्पेस में डिवाइस कंट्रोल कैसे दिखाए जाएं और उन्हें कंट्रोल करने वाले ऐप्लिकेशन से कैसे लिंक किया जाए.

पहली इमेज. Android यूज़र इंटरफ़ेस (यूआई) में डिवाइस कंट्रोल स्पेस.

इस सुविधा को जोड़ने के लिए, ControlsProviderService बनाएं और उसका एलान करें. पहले से तय किए गए कंट्रोल टाइप के आधार पर, अपने ऐप्लिकेशन के लिए कंट्रोल बनाएं. इसके बाद, इन कंट्रोल के लिए पब्लिशर बनाएं.

उपयोगकर्ता इंटरफ़ेस

डिवाइस, डिवाइस कंट्रोल में टेंप्लेट वाले विजेट के तौर पर दिखते हैं. डिवाइस कंट्रोल करने के लिए पांच विजेट उपलब्ध हैं. इन्हें इस इमेज में दिखाया गया है:

विजेट टॉगल करें
टॉगल करें
स्लाइडर विजेट की मदद से टॉगल करना
स्लाइडर के साथ टॉगल करें
रेंज विजेट
रेंज (इसे चालू या बंद नहीं किया जा सकता)
स्टेटलेस टॉगल विजेट
Stateless टॉगल
तापमान पैनल विजेट (बंद है)
तापमान पैनल (बंद)
दूसरी इमेज. टेंप्लेट वाले विजेट का कलेक्शन.

किसी विजेट को दबाकर रखने से, आपको ऐप्लिकेशन के ज़्यादा कंट्रोल मिलते हैं. हर विजेट पर आइकॉन और रंग को पसंद के मुताबिक बनाया जा सकता है. हालांकि, उपयोगकर्ता को बेहतर अनुभव देने के लिए, डिफ़ॉल्ट आइकॉन और रंग का इस्तेमाल करें. ऐसा तब करें, जब डिफ़ॉल्ट सेट डिवाइस से मेल खाता हो.

तापमान पैनल विजेट (खुला हुआ) दिखाने वाली इमेज
तीसरी इमेज. तापमान पैनल विजेट खुला है.

सेवा बनाना

इस सेक्शन में, ControlsProviderService बनाने का तरीका बताया गया है. यह सेवा, Android सिस्टम यूज़र इंटरफ़ेस (यूआई) को बताती है कि आपके ऐप्लिकेशन में डिवाइस कंट्रोल मौजूद हैं. इन्हें Android यूआई के डिवाइस कंट्रोल सेक्शन में दिखाना ज़रूरी है.

ControlsProviderService एपीआई, Reactive Streams GitHub प्रोजेक्ट में बताए गए और Java 9 Flow इंटरफ़ेस में लागू किए गए, रिएक्टिव स्ट्रीम के बारे में जानकारी देता है. यह एपीआई, इन कॉन्सेप्ट के आधार पर बनाया गया है:

  • पब्लिशर: आपका ऐप्लिकेशन पब्लिशर है.
  • सदस्य: सिस्टम यूज़र इंटरफ़ेस (यूआई) सदस्य होता है. यह पब्लिशर से कई तरह के कंट्रोल का अनुरोध कर सकता है.
  • सदस्यता: वह समयावधि जिसके दौरान पब्लिशर, सिस्टम यूज़र इंटरफ़ेस (यूआई) को अपडेट भेज सकता है. पब्लिशर या सदस्य, इस विंडो को बंद कर सकते हैं.

सेवा के बारे में जानकारी देना

आपके ऐप्लिकेशन को अपने मेनिफ़ेस्ट में, MyCustomControlService जैसी किसी सेवा के बारे में बताना होगा.

सेवा में ControlsProviderService के लिए इंटेंट फ़िल्टर शामिल होना चाहिए. इस फ़िल्टर की मदद से, ऐप्लिकेशन सिस्टम यूज़र इंटरफ़ेस (यूआई) में कंट्रोल जोड़ सकते हैं.

आपको एक ऐसे label की भी ज़रूरत होगी जो सिस्टम यूज़र इंटरफ़ेस (यूआई) में कंट्रोल के तौर पर दिखता हो.

यहां दिए गए उदाहरण में, किसी सेवा के बारे में जानकारी देने का तरीका बताया गया है:

<service
    android:name="MyCustomControlService"
    android:label="My Custom Controls"
    android:permission="android.permission.BIND_CONTROLS"
    android:exported="true"
    >
    <intent-filter>
      <action android:name="android.service.controls.ControlsProviderService" />
    </intent-filter>
</service>

इसके बाद, MyCustomControlService.kt नाम की एक नई Kotlin फ़ाइल बनाएं और उसे ControlsProviderService() से एक्सटेंड करें:

Kotlin

    class MyCustomControlService : ControlsProviderService() {
        ...
    }
    

Java

    public class MyCustomJavaControlService extends ControlsProviderService {
        ...
    }
    

कंट्रोल का सही टाइप चुनना

एपीआई, कंट्रोल बनाने के लिए बिल्डर के तरीके उपलब्ध कराता है. बिल्डर को भरने के लिए, उस डिवाइस का पता लगाएं जिसे आपको कंट्रोल करना है. साथ ही, यह तय करें कि उपयोगकर्ता उससे कैसे इंटरैक्ट करेगा. यह तरीका अपनाएं:

  1. चुनें कि कंट्रोल किस तरह के डिवाइस को दिखाता है. DeviceTypes क्लास, उन सभी डिवाइसों की गिनती करती है जिन पर यह सुविधा काम करती है. इस टाइप का इस्तेमाल, यूज़र इंटरफ़ेस (यूआई) में डिवाइस के आइकॉन और रंगों का पता लगाने के लिए किया जाता है.
  2. उपयोगकर्ता को दिखने वाला नाम, डिवाइस की जगह की जानकारी (उदाहरण के लिए, रसोई) और कंट्रोल से जुड़े अन्य यूज़र इंटरफ़ेस (यूआई) टेक्स्ट एलिमेंट तय करता है.
  3. उपयोगकर्ता के इंटरैक्शन को बेहतर बनाने के लिए, सबसे अच्छा टेंप्लेट चुनें. ऐप्लिकेशन से कंट्रोल को ControlTemplate असाइन किया जाता है. यह टेंप्लेट, उपयोगकर्ता को सीधे तौर पर कंट्रोल की स्थिति दिखाता है. साथ ही, उपलब्ध इनपुट के तरीके भी दिखाता है. इसका मतलब है कि यह ControlAction दिखाता है. यहां दी गई टेबल में, उपलब्ध कुछ टेंप्लेट और उनके साथ काम करने वाली कार्रवाइयों के बारे में बताया गया है:
टेंप्लेट कार्रवाई ब्यौरा
ControlTemplate.getNoTemplateObject() None ऐप्लिकेशन इसका इस्तेमाल कंट्रोल के बारे में जानकारी देने के लिए कर सकता है. हालांकि, उपयोगकर्ता इससे इंटरैक्ट नहीं कर सकता.
ToggleTemplate BooleanAction यह एक ऐसे कंट्रोल को दिखाता है जिसे चालू और बंद किया जा सकता है. BooleanAction ऑब्जेक्ट में एक ऐसा फ़ील्ड होता है जो उपयोगकर्ता के कंट्रोल पर टैप करने पर, अनुरोध की गई नई स्थिति को दिखाता है.
RangeTemplate FloatAction यह स्लाइडर विजेट को दिखाता है. इसमें कम से कम, ज़्यादा से ज़्यादा, और चरण की वैल्यू तय की जाती हैं. जब उपयोगकर्ता स्लाइडर के साथ इंटरैक्ट करता है, तो अपडेट की गई वैल्यू के साथ एक नया FloatAction ऑब्जेक्ट वापस ऐप्लिकेशन को भेजें.
ToggleRangeTemplate BooleanAction, FloatAction यह टेंप्लेट, ToggleTemplate और RangeTemplate का कॉम्बिनेशन है. इसमें टच इवेंट के साथ-साथ स्लाइडर की सुविधा भी होती है. जैसे, डिम की जा सकने वाली लाइटों को कंट्रोल करने के लिए.
TemperatureControlTemplate ModeAction, BooleanAction, FloatAction इस टेंप्लेट में, ऊपर दी गई कार्रवाइयों के साथ-साथ, उपयोगकर्ता के लिए मोड सेट करने का विकल्प भी होता है. जैसे, गर्म, ठंडा, गर्म/ठंडा, ईको या बंद.
StatelessTemplate CommandAction इस कंट्रोल का इस्तेमाल, टच की सुविधा देने वाले कंट्रोल के लिए किया जाता है. हालांकि, इसकी स्थिति का पता नहीं लगाया जा सकता. जैसे, आईआर टेलीविज़न रिमोट. इस टेंप्लेट का इस्तेमाल करके, कोई रूटीन या मैक्रो तय की जा सकती है. यह कंट्रोल और स्टेट में होने वाले बदलावों का एग्रीगेशन होता है.

इस जानकारी की मदद से, कंट्रोल बनाया जा सकता है:

  • जब कंट्रोल की स्थिति के बारे में जानकारी न हो, तब बिल्डर क्लास Control.StatelessBuilder का इस्तेमाल करें.
  • जब कंट्रोल की स्थिति पता हो, तब बिल्डर क्लास Control.StatefulBuilder का इस्तेमाल करें.

उदाहरण के लिए, स्मार्ट लाइट बल्ब और थर्मोस्टैट को कंट्रोल करने के लिए, अपने MyCustomControlService में ये कॉन्स्टेंट जोड़ें:

Kotlin

    private const val LIGHT_ID = 1234
    private const val LIGHT_TITLE = "My fancy light"
    private const val LIGHT_TYPE = DeviceTypes.TYPE_LIGHT
    private const val THERMOSTAT_ID = 5678
    private const val THERMOSTAT_TITLE = "My fancy thermostat"
    private const val THERMOSTAT_TYPE = DeviceTypes.TYPE_THERMOSTAT
 
    class MyCustomControlService : ControlsProviderService() {
      ...
    }
    

Java

    public class MyCustomJavaControlService extends ControlsProviderService {
 
    private final int LIGHT_ID = 1337;
    private final String LIGHT_TITLE = "My fancy light";
    private final int LIGHT_TYPE = DeviceTypes.TYPE_LIGHT;
    private final int THERMOSTAT_ID = 1338;
    private final String THERMOSTAT_TITLE = "My fancy thermostat";
    private final int THERMOSTAT_TYPE = DeviceTypes.TYPE_THERMOSTAT;
 
    ...
    }
    

कंट्रोल के लिए पब्लिशर बनाना

कंट्रोल बनाने के बाद, इसे पब्लिशर की ज़रूरत होती है. पब्लिशर, सिस्टम यूज़र इंटरफ़ेस (यूआई) को कंट्रोल के बारे में बताता है. ControlsProviderService क्लास में पब्लिशर के दो तरीके होते हैं. आपको अपने ऐप्लिकेशन कोड में इन्हें बदलना होगा:

  • createPublisherForAllAvailable(): आपके ऐप्लिकेशन में उपलब्ध सभी कंट्रोल के लिए, Publisher बनाता है. इस पब्लिशर के लिए Control ऑब्जेक्ट बनाने के लिए, Control.StatelessBuilder() का इस्तेमाल करें.
  • createPublisherFor(): यह दिए गए कंट्रोल की सूची के लिए Publisher बनाता है. कंट्रोल की पहचान उनके स्ट्रिंग आइडेंटिफ़ायर से होती है. इन Control ऑब्जेक्ट को बनाने के लिए, Control.StatefulBuilder का इस्तेमाल करें. ऐसा इसलिए, क्योंकि पब्लिशर को हर कंट्रोल के लिए एक स्थिति असाइन करनी होती है.

पब्लिशर खाता बनाना

जब आपका ऐप्लिकेशन पहली बार सिस्टम यूज़र इंटरफ़ेस (यूआई) में कंट्रोल पब्लिश करता है, तो ऐप्लिकेशन को हर कंट्रोल की स्थिति के बारे में पता नहीं होता. डिवाइस-प्रोवाइडर के नेटवर्क में कई हॉप शामिल होने की वजह से, स्थिति की जानकारी पाने में समय लग सकता है. सिस्टम को उपलब्ध कंट्रोल के बारे में बताने के लिए, createPublisherForAllAvailable() तरीके का इस्तेमाल करें. इस तरीके में Control.StatelessBuilder बिल्डर क्लास का इस्तेमाल किया जाता है, क्योंकि हर कंट्रोल की स्थिति के बारे में जानकारी नहीं होती.

Android के यूज़र इंटरफ़ेस (यूआई) में कंट्रोल दिखने के बाद , उपयोगकर्ता पसंदीदा कंट्रोल चुन सकता है.

ControlsProviderService बनाने के लिए Kotlin कोरूटीन का इस्तेमाल करने के लिए, अपनी build.gradle में नई डिपेंडेंसी जोड़ें:

Groovy

dependencies {
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-jdk9:1.6.4"
}

Kotlin

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk9:1.6.4")
}

Gradle फ़ाइलें सिंक करने के बाद, createPublisherForAllAvailable() को लागू करने के लिए, अपने Service में यह स्निपेट जोड़ें:

Kotlin

    class MyCustomControlService : ControlsProviderService() {
 
      override fun createPublisherForAllAvailable(): Flow.Publisher =
          flowPublish {
              send(createStatelessControl(LIGHT_ID, LIGHT_TITLE, LIGHT_TYPE))
              send(createStatelessControl(THERMOSTAT_ID, THERMOSTAT_TITLE, THERMOSTAT_TYPE))
          }
 
      private fun createStatelessControl(id: Int, title: String, type: Int): Control {
          val intent = Intent(this, MainActivity::class.java)
              .putExtra(EXTRA_MESSAGE, title)
              .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
          val action = PendingIntent.getActivity(
              this,
              id,
              intent,
              PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
          )
 
          return Control.StatelessBuilder(id.toString(), action)
              .setTitle(title)
              .setDeviceType(type)
              .build()
      }
 
          override fun createPublisherFor(controlIds: List): Flow.Publisher {
           TODO()
        }
 
        override fun performControlAction(
            controlId: String,
            action: ControlAction,
            consumer: Consumer
        ) {
            TODO()
        }
    }
    

Java

    public class MyCustomJavaControlService extends ControlsProviderService {
 
        private final int LIGHT_ID = 1337;
        private final String LIGHT_TITLE = "My fancy light";
        private final int LIGHT_TYPE = DeviceTypes.TYPE_LIGHT;
        private final int THERMOSTAT_ID = 1338;
        private final String THERMOSTAT_TITLE = "My fancy thermostat";
        private final int THERMOSTAT_TYPE = DeviceTypes.TYPE_THERMOSTAT;
 
        private boolean toggleState = false;
        private float rangeState = 18f;
        private final Map<String, ReplayProcessor> controlFlows = new HashMap<>();
 
        @NonNull
        @Override
        public Flow.Publisher createPublisherForAllAvailable() {
            List controls = new ArrayList<>();
            controls.add(createStatelessControl(LIGHT_ID, LIGHT_TITLE, LIGHT_TYPE));
            controls.add(createStatelessControl(THERMOSTAT_ID, THERMOSTAT_TITLE, THERMOSTAT_TYPE));
            return FlowAdapters.toFlowPublisher(Flowable.fromIterable(controls));
        }
 
        @NonNull
        @Override
        public Flow.Publisher createPublisherFor(@NonNull List controlIds) {
            ReplayProcessor updatePublisher = ReplayProcessor.create();
 
            controlIds.forEach(control -> {
                controlFlows.put(control, updatePublisher);
                updatePublisher.onNext(createLight());
                updatePublisher.onNext(createThermostat());
            });
 
            return FlowAdapters.toFlowPublisher(updatePublisher);
        }
    }
    

सिस्टम मेन्यू को नीचे की ओर स्वाइप करें और डिवाइस कंट्रोल बटन ढूंढें. यह बटन, चौथे फ़िगर में दिखाया गया है:

डिवाइस कंट्रोल के लिए सिस्टम यूज़र इंटरफ़ेस (यूआई) दिखाने वाली इमेज
चौथी इमेज. सिस्टम मेन्यू में डिवाइस कंट्रोल.

डिवाइस कंट्रोल पर टैप करने से, आपको दूसरी स्क्रीन पर ले जाया जाता है. यहां आपको अपना ऐप्लिकेशन चुनने का विकल्प मिलता है. ऐप्लिकेशन चुनने के बाद, आपको दिखेगा कि पिछले स्निपेट से, कस्टम सिस्टम मेन्यू कैसे बनता है. इसमें आपके नए कंट्रोल दिखते हैं. इसे पांचवें डायग्राम में दिखाया गया है:

सिस्टम मेन्यू दिखाने वाली इमेज, जिसमें लाइट और थर्मोस्टैट कंट्रोल करने की सुविधा है
इमेज 5. लाइट और थर्मोस्टैट कंट्रोल जोड़ने की सुविधा.

अब createPublisherFor() तरीके को लागू करें. इसके लिए, अपनी Service में यह जानकारी जोड़ें:

Kotlin

    private val job = SupervisorJob()
    private val scope = CoroutineScope(Dispatchers.IO + job)
    private val controlFlows = mutableMapOf<String, MutableSharedFlow>()
 
    private var toggleState = false
    private var rangeState = 18f
 
    override fun createPublisherFor(controlIds: List): Flow.Publisher {
        val flow = MutableSharedFlow(replay = 2, extraBufferCapacity = 2)
 
        controlIds.forEach { controlFlows[it] = flow }
 
        scope.launch {
            delay(1000) // Retrieving the toggle state.
            flow.tryEmit(createLight())
 
            delay(1000) // Retrieving the range state.
            flow.tryEmit(createThermostat())
 
        }
        return flow.asPublisher()
    }
 
    private fun createLight() = createStatefulControl(
        LIGHT_ID,
        LIGHT_TITLE,
        LIGHT_TYPE,
        toggleState,
        ToggleTemplate(
            LIGHT_ID.toString(),
            ControlButton(
                toggleState,
                toggleState.toString().uppercase(Locale.getDefault())
            )
        )
    )
 
    private fun createThermostat() = createStatefulControl(
        THERMOSTAT_ID,
        THERMOSTAT_TITLE,
        THERMOSTAT_TYPE,
        rangeState,
        RangeTemplate(
            THERMOSTAT_ID.toString(),
            15f,
            25f,
            rangeState,
            0.1f,
            "%1.1f"
        )
    )
 
    private fun  createStatefulControl(id: Int, title: String, type: Int, state: T, template: ControlTemplate): Control {
        val intent = Intent(this, MainActivity::class.java)
            .putExtra(EXTRA_MESSAGE, "$title $state")
            .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        val action = PendingIntent.getActivity(
            this,
            id,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )
 
        return Control.StatefulBuilder(id.toString(), action)
            .setTitle(title)
            .setDeviceType(type)
            .setStatus(Control.STATUS_OK)
            .setControlTemplate(template)
            .build()
    }
 
    override fun onDestroy() {
        super.onDestroy()
        job.cancel()
    }
 
    

Java

    @NonNull
    @Override
    public Flow.Publisher createPublisherFor(@NonNull List controlIds) {
        ReplayProcessor updatePublisher = ReplayProcessor.create();
 
        controlIds.forEach(control -> {
            controlFlows.put(control, updatePublisher);
            updatePublisher.onNext(createLight());
            updatePublisher.onNext(createThermostat());
        });
 
        return FlowAdapters.toFlowPublisher(updatePublisher);
    }
 
    private Control createStatelessControl(int id, String title, int type) {
        Intent intent = new Intent(this, MainActivity.class)
                .putExtra(EXTRA_MESSAGE, title)
                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent action = PendingIntent.getActivity(
                this,
                id,
                intent,
                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
        );
 
        return new Control.StatelessBuilder(id + "", action)
                .setTitle(title)
                .setDeviceType(type)
                .build();
    }
 
    private Control createLight() {
        return createStatefulControl(
                LIGHT_ID,
                LIGHT_TITLE,
                LIGHT_TYPE,
                toggleState,
                new ToggleTemplate(
                        LIGHT_ID + "",
                        new ControlButton(
                                toggleState,
                                String.valueOf(toggleState).toUpperCase(Locale.getDefault())
                        )
                )
        );
    }
 
    private Control createThermostat() {
        return createStatefulControl(
                THERMOSTAT_ID,
                THERMOSTAT_TITLE,
                THERMOSTAT_TYPE,
                rangeState,
                new RangeTemplate(
                        THERMOSTAT_ID + "",
                        15f,
                        25f,
                        rangeState,
                        0.1f,
                        "%1.1f"
                )
        );
    }
 
    private  Control createStatefulControl(int id, String title, int type, T state, ControlTemplate template) {
        Intent intent = new Intent(this, MainActivity.class)
                .putExtra(EXTRA_MESSAGE, "$title $state")
                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent action = PendingIntent.getActivity(
                this,
                id,
                intent,
                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
        );
 
        return new Control.StatefulBuilder(id + "", action)
                .setTitle(title)
                .setDeviceType(type)
                .setStatus(Control.STATUS_OK)
                .setControlTemplate(template)
                .build();
    }
    

इस उदाहरण में, createPublisherFor() तरीके में, आपके ऐप्लिकेशन को क्या करना चाहिए, इसके बारे में एक फ़र्ज़ी जानकारी दी गई है: डिवाइस की स्थिति पाने के लिए, उससे कम्यूनिकेट करना और उस स्थिति को सिस्टम को भेजना.

createPublisherFor() तरीके में, Kotlin कोरूटीन और फ़्लो का इस्तेमाल किया जाता है. इससे, Reactive Streams API की ज़रूरी शर्तें पूरी की जा सकती हैं. इसके लिए, यह तरीका अपनाएं:

  1. Flow बनाता है.
  2. यह एक सेकंड तक इंतज़ार करता है.
  3. यह कुकी, स्मार्ट लाइट की स्थिति को बनाती है और उसे भेजती है.
  4. एक और सेकंड इंतज़ार करता है.
  5. यह कुकी, थर्मोस्टैट की स्थिति को बनाती और भेजती है.

कार्रवाइयों को मैनेज करना

performControlAction() तरीका, यह सिग्नल देता है कि उपयोगकर्ता ने पब्लिश किए गए कंट्रोल के साथ इंटरैक्ट किया है. भेजे गए ControlAction के टाइप के आधार पर कार्रवाई तय होती है. दिए गए कंट्रोल के लिए ज़रूरी कार्रवाई करें. इसके बाद, Android के यूज़र इंटरफ़ेस (यूआई) में डिवाइस की स्थिति अपडेट करें.

उदाहरण को पूरा करने के लिए, Service में यह जानकारी जोड़ें:

Kotlin

    override fun performControlAction(
        controlId: String,
        action: ControlAction,
        consumer: Consumer
    ) {
        controlFlows[controlId]?.let { flow ->
            when (controlId) {
                LIGHT_ID.toString() -> {
                    consumer.accept(ControlAction.RESPONSE_OK)
                    if (action is BooleanAction) toggleState = action.newState
                    flow.tryEmit(createLight())
                }
                THERMOSTAT_ID.toString() -> {
                    consumer.accept(ControlAction.RESPONSE_OK)
                    if (action is FloatAction) rangeState = action.newValue
                    flow.tryEmit(createThermostat())
                }
                else -> consumer.accept(ControlAction.RESPONSE_FAIL)
            }
        } ?: consumer.accept(ControlAction.RESPONSE_FAIL)
    }
    

Java

    @Override
    public void performControlAction(@NonNull String controlId, @NonNull ControlAction action, @NonNull Consumer consumer) {
        ReplayProcessor processor = controlFlows.get(controlId);
        if (processor == null) return;
 
        if (controlId.equals(LIGHT_ID + "")) {
            consumer.accept(ControlAction.RESPONSE_OK);
            if (action instanceof BooleanAction) toggleState = ((BooleanAction) action).getNewState();
            processor.onNext(createLight());
        }
        if (controlId.equals(THERMOSTAT_ID + "")) {
            consumer.accept(ControlAction.RESPONSE_OK);
            if (action instanceof FloatAction) rangeState = ((FloatAction) action).getNewValue()
            processor.onNext(createThermostat());
        }
    }
    

ऐप्लिकेशन खोलें और डिवाइस कंट्रोल मेन्यू ऐक्सेस करें. इसके बाद, लाइट और थर्मोस्टैट कंट्रोल देखें.

लाइट और थर्मोस्टैट को कंट्रोल करने की सुविधा दिखाने वाली इमेज
छठी इमेज. लाइट और थर्मोस्टैट को कंट्रोल करने की सुविधा.