Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Edistynyt mobiiliohjelmointi, 17.3.2023
- https://mqttx.app/
- https://test.mosquitto.org/
- MQTT X:
- yhdistetään testibrokeriin:
- client_id: ei väliä kunhan varmasti uniikki, koska kaksi samaa client id:tä pudottaa vanhemman yhteyden linjoilta
- host: test.mosquitto.org
- port: 8886
- SSL/TLS päälle, SLS Secure ja CA signed server certificate.
- Esimerkkidataa Ruotsin sääasemasta:
- {"d":{"1":{"v":-1.6},"2":{"v":1010.4},"3":{"v":61.4},"4":{"v":-9.1},"6":{"v":103},"7":{"v":0},"8":{"v":0},"9":{"v":302},"10":{"v":1},"11":{"v":12.7}},"ts":"2023-03-17T11:19:24.035Z"}
- Tehdään uusi fragment mobile_navigationin avulla: WeatherStationFragment.
- Lisätään WeatherStationFragment päävalikkoon.
- Otetaan WeatherStationFragmentiin binding layer käyttöön (kopioi pohja esim. DataReadFragmentista)
- Esim.
- class WeatherStationFragment : Fragment() {
- // change this to match your fragment name
- private var _binding: FragmentWeatherStationBinding? = null
- // This property is only valid between onCreateView and
- // onDestroyView.
- private val binding get() = _binding!!
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- _binding = FragmentWeatherStationBinding.inflate(inflater, container, false)
- val root: View = binding.root
- return root
- }
- override fun onDestroyView() {
- super.onDestroyView()
- _binding = null
- }
- }
- // jotta jsonschema2pojon tuottamat Java-luokat toimii projektissa, tarvitaan seuraava moduuli gradleen:
- implementation 'javax.annotation:javax.annotation-api:1.3.2'
- // MQTT:n käyttäminen Fragmentissa
- import mukaan:
- implementation("com.hivemq:hivemq-mqtt-client-shaded:1.3.0")
- // lisää local.propertiesiin seuraavat muuttujat, ja lisää tarvittavat yhteystiedot (ks. Harjoitus 4, sivu 1)
- MQTT_BROKER=brokerin_osoite
- MQTT_USERNAME=
- MQTT_PASSWORD=
- MQTT_TOPIC=ruotsin_aseman_topic
- MQTT_CLIENT_ID=pelkkä_alkuosa_ilman_omaa_uniikkia_osaa(tehdään koodissa myöhemmin)
- // WeatherStationFragment, raakadatan lataaminen ja näyttäminen konsolissa:
- class WeatherStationFragment : Fragment() {
- // change this to match your fragment name
- private var _binding: FragmentWeatherStationBinding? = null
- // This property is only valid between onCreateView and
- // onDestroyView.
- private val binding get() = _binding!!
- // HiveMQ MQTT ver 3 -client
- private lateinit var client: Mqtt3AsyncClient
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- _binding = FragmentWeatherStationBinding.inflate(inflater, container, false)
- val root: View = binding.root
- // version 3, IBM Cloud, weather station
- // identifier => lisätään local.propertiesissa olevaan alkuosaan satunnainen teksti
- // jotta saadaan uniikki osa myös mukaan (vaadittu IBM Cloudissa)
- client = MqttClient.builder()
- .useMqttVersion3()
- .sslWithDefaultConfig()
- .identifier(BuildConfig.MQTT_CLIENT_ID + UUID.randomUUID().toString())
- .serverHost(BuildConfig.MQTT_BROKER)
- .serverPort(8883)
- .buildAsync()
- client.connectWith()
- .simpleAuth()
- .username(BuildConfig.MQTT_USERNAME)
- .password(BuildConfig.MQTT_PASSWORD.toByteArray())
- .applySimpleAuth()
- .send()
- .whenComplete { connAck: Mqtt3ConnAck?, throwable: Throwable? ->
- if (throwable != null) {
- Log.d("ADVTECH", "Connection failure.")
- } else {
- // Setup subscribes or start publishing
- subscribeToTopic()
- }
- }
- return root
- }
- // apufunktio, jolla tehdään subscription Ruotsin sääasemaan, käytetään
- // ainoastaan silloin kun yhteys on saatu luotua onnistuneesti
- fun subscribeToTopic()
- {
- client.subscribeWith()
- .topicFilter(BuildConfig.MQTT_TOPIC)
- .callback { publish ->
- // this callback runs everytime your code receives new data payload
- var result = String(publish.getPayloadAsBytes())
- Log.d("ADVTECH", result)
- }
- .send()
- .whenComplete { subAck, throwable ->
- if (throwable != null) {
- // Handle failure to subscribe
- Log.d("ADVTECH", "Subscribe failed.")
- } else {
- // Handle successful subscription, e.g. logging or incrementing a metric
- Log.d("ADVTECH", "Subscribed!")
- }
- }
- }
- override fun onDestroyView() {
- super.onDestroyView()
- _binding = null
- // kannattaa myös katkaista MQTT-yhteys kun fragment suljetaan
- client.disconnect()
- }
- }
- // uusi versio subscribeToTopic -> asetetaan raakadata TextViewiin
- // apufunktio, jolla tehdään subscription Ruotsin sääasemaan, käytetään
- // ainoastaan silloin kun yhteys on saatu luotua onnistuneesti
- fun subscribeToTopic()
- {
- client.subscribeWith()
- .topicFilter(BuildConfig.MQTT_TOPIC)
- .callback { publish ->
- // this callback runs everytime your code receives new data payload
- var result = String(publish.getPayloadAsBytes())
- Log.d("ADVTECH", result)
- // ajetaan ulkoasuun liittyvät asiat UI-säikeessä
- // koska MQTT toimii itsessään taustasäikeessä
- // ilman tätä, ohjelma kaatuu
- // tämä myös olettaa että ulkoasussa on TextView tällä id:llä
- activity?.runOnUiThread(java.lang.Runnable {
- binding.textViewWeatherData.text = result
- })
- }
- .send()
- .whenComplete { subAck, throwable ->
- if (throwable != null) {
- // Handle failure to subscribe
- Log.d("ADVTECH", "Subscribe failed.")
- } else {
- // Handle successful subscription, e.g. logging or incrementing a metric
- Log.d("ADVTECH", "Subscribed!")
- }
- }
- }
- // uusi versio subscribeToTopic, GSON + try/catch:
- // apufunktio, jolla tehdään subscription Ruotsin sääasemaan, käytetään
- // ainoastaan silloin kun yhteys on saatu luotua onnistuneesti
- fun subscribeToTopic()
- {
- val gson = GsonBuilder().setPrettyPrinting().create()
- client.subscribeWith()
- .topicFilter(BuildConfig.MQTT_TOPIC)
- .callback { publish ->
- // this callback runs everytime your code receives new data payload
- var result = String(publish.getPayloadAsBytes())
- Log.d("ADVTECH", result)
- // try-catchin avulla voimme huolehtia ettei koodi tilttaa
- // kun sääasema lähettää diagnostiikka-payloadin (joka ei sisällä säädataa)
- try {
- var item : WeatherStation = gson.fromJson(result, WeatherStation::class.java)
- // haetaan lämpötila WeatherStation-objektin kautta
- // haetaan myös ilmanpaine
- var temperature = item.d.get1().v.toString()
- var pressure = item.d.get2().v.toString()
- // rakennetaan simppeli teksti ulkoasua varten
- var output = "Temp: ${temperature} C\nPressure:${pressure}"
- // ajetaan ulkoasuun liittyvät asiat UI-säikeessä
- // koska MQTT toimii itsessään taustasäikeessä
- // ilman tätä, ohjelma kaatuu
- activity?.runOnUiThread(java.lang.Runnable {
- binding.textViewWeatherData.text = output
- })
- }
- catch(e: Exception) {
- Log.d("ADVTECH", "Skipped diagnostics payload.")
- }
- }
- .send()
- .whenComplete { subAck, throwable ->
- if (throwable != null) {
- // Handle failure to subscribe
- Log.d("ADVTECH", "Subscribe failed.")
- } else {
- // Handle successful subscription, e.g. logging or incrementing a metric
- Log.d("ADVTECH", "Subscribed!")
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement