Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Edistynyt mobiiliohjelmointi, 24.4.2023
- Kokeillaan MQTTX:llä julkista MQTT brokeria:
- https://test.mosquitto.org/
- Tehdään uusi Connection MQTT X:llä, seuraavilla tiedoilla:
- Name: mikä vain itse haluat, lähinnä itseäsi varten että tiedät mistä yhteydestä on kyse
- Client ID: tämän tulee olla kaikilla käyttäjillä uniikki teksti (esim. 98af7sd98fyhw4ui5t79), koska jos kaksi laitetta yhdistää samalla client id:llä, vanhempi yhteys tippuu pois linjoilta
- Host: test.mosquitto.org
- Port: 8886
- SSL/TLS päälle, SSL Secure päällä, ja CA signed server päällä
- Yhdistetään luennolla topiciin: test/lapinamk
- // Kokeillaan IBM Cloud / TEQU -sääasemaa, MQTT X:n uusi Connection:
- Name: mikä vain, esim. WeatherStationTest
- Client ID: alkuosa on aina (ks. ohjeesta alkuosa) ---> a:xxxxxx: ja tähän perään oma uniikki osa, eli esim
- a:xxxxxx:asgf9d87549hrajh
- Host: ks. Harjoitus 4 ohje, broker address
- Username: ks. Harjoitus 4 ohje, API-key / username
- Password: ks. Harjoitus 4 ohje, Authentication token / password
- SSL/TLS päälle, SSL Secure päälle, CA signed server päälle
- topic:
- ks. ohje, kokeile ensin Ruotsin dataa (selkeää JSONia), pitäisi tulla seuraavanlaista dataa:
- {"d":{"temperature":{"v":6.6},"pressure":{"v":1006.9},"relative_humidity":{"v":38.4},"dewpoint":{"v":-8.4},"wind_speed":{"v":2},"wind_direction":{"v":91},"rain_type":{"v":0},"rain_intensity":{"v":0},"global_radiation":{"v":397},"uv_index":{"v":2},"brightness":{"v":13.9},"latitude":{"v":65.56221605},"longitude":{"v":22.099477417},"altitude":{"v":17.9}},"ts":"2023-04-24T14:54:44.410Z"}
- ... ja sen jälkeen Ounasvaaran dataa, josta pitäisi tulla haastavampaa dataa (huom: kaikki kentät ovat nyt vain numeroita):
- {"d":{"1":{"v":6.8},"2":{"v":1006.9},"3":{"v":37.8},"4":{"v":-8.5},"5":{"v":0.6},"6":{"v":73},"7":{"v":0},"8":{"v":0},"9":{"v":403},"10":{"v":2},"11":{"v":13.7}},"ts":"2023-04-24T14:59:05.640Z"}
- // Ounasvaaran dataa ei voi käyttää json2kt.comissa, koska se yrittää tehdä luokkia, joiden nimenä on pelkkä numero (esim. data class 1). tämä ei ole syntaksin näkökulmasta oikeanlaista koodia, ja tällaiset luokat eivät käytännössä toimi.
- // käytetään tämän sijasta työkalua:
- https://www.jsonschema2pojo.org/
- // ks. ohje tai luentovideo miten työkalua käytetään
- // tehdään uusi kansio (package) Android-projektiin datatypes-kansion alle -> weatherstation
- // kopioi työkalusta tulevat Java-tiedostot juuri tehtyyn weatherstation -kansioon.
- // tarkista että paketti on varmasti oikein työkalussa
- // eli jos projektisi paketti on com.example.testi2023, ja siellä on datatypes -kansio jossa on weatherstation -kansio, paketti on silloin:
- com.example.testi2023.datatypes.weatherstation
- // lisää seuraava import build.gradle / moduleen:
- implementation 'javax.annotation:javax.annotation-api:1.3.2'
- Tämän jälkeen @Generated-virhe poistuu tiedostoista.
- // tehdään uusi Fragment (mobile_navigationin kautta), lisätään se päävalikkoon ja otetaan binding-layer käyttöön, esim:
- WeatherStationFragment.kt:
- class WeatherStationFragment : Fragment() {
- 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
- }
- }
- // lisätään HiveMQ-plugin projektiin, build.gradle / module:
- implementation("com.hivemq:hivemq-mqtt-client-shaded:1.3.0")
- // lisätään local.propertiesiin MQTT-muuttujat, ja sitten käynnistetään projekti, jotta saadaan BuildConfig päivitettyä:
- MQTT_BROKER=OSOITETÄHÄNOHJEISTA
- MQTT_CLIENT_ID=CLIENT_IDN_ALKUOSA_TOISEEN_KAKSOISPISTEESEEN_ASTI
- MQTT_USERNAME=KSOHJEISTA
- MQTT_PASSWORD=OHJEISTA
- MQTT_TOPIC=OUNASVAARANLAITETOPIC
- // kun kaikki Moodlen esimerkit kytketään samaksi koodiksi:
- class WeatherStationFragment : Fragment() {
- private var _binding: FragmentWeatherStationBinding? = null
- // This property is only valid between onCreateView and
- // onDestroyView.
- // remember to update your local.properties with values of the MQTT connection
- // client-olio, jolla voidaan yhdistää MQTT-brokeriin koodin avulla
- private lateinit var client: Mqtt3AsyncClient
- // apufunktio/metodi jolla yhdistetään sääaseman topiciin
- // JOS yhteys onnistui aiemmin
- fun subscribeToTopic()
- {
- client.subscribeWith()
- .topicFilter(BuildConfig.MQTT_TOPIC)
- .callback { publish ->
- // this callback runs everytime your code receives new data payload
- // muutetaan raakadata tekstiksi (tässä tapauksessa JSONia)
- 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!")
- }
- }
- }
- 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
- // version 3, IBM Cloud, weather station
- // Huomaa identifier eli Client ID => vain alkuosa toiseen kaksoispisteeseen
- // laitetaan local.propertiesiin, ja satunnainen tekstihäntä liitetään
- // perään UUID-kirjaston avulla
- client = MqttClient.builder()
- .useMqttVersion3()
- .sslWithDefaultConfig()
- .identifier(BuildConfig.MQTT_CLIENT_ID + UUID.randomUUID().toString())
- .serverHost(BuildConfig.MQTT_BROKER)
- .serverPort(8883)
- .buildAsync()
- // yhdistetään käyttäjätiedoilla (username/password)
- 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
- }
- override fun onDestroyView() {
- super.onDestroyView()
- _binding = null
- // suljetaan MQTT-yhteys mikäli fragment suljetaan
- client.disconnect()
- }
- }
- kokeillaan käyttää hieman GSONia:
- fun subscribeToTopic()
- {
- // alustetaan GSON
- val gson = GsonBuilder().setPrettyPrinting().create()
- client.subscribeWith()
- .topicFilter(BuildConfig.MQTT_TOPIC)
- .callback { publish ->
- // this callback runs everytime your code receives new data payload
- // muutetaan raakadata tekstiksi (tässä tapauksessa JSONia)
- var result = String(publish.getPayloadAsBytes())
- // Log.d("ADVTECH", result)
- // muutetaan vastaanotettu data JSONista -> WeatherStation -luokan olioksi
- var item : WeatherStation = gson.fromJson(result, WeatherStation::class.java)
- Log.d("ADVTECH", item.d.get1().v.toString() + "C")
- } jne ...
- Tässä tulee ongelma, koska välillä datan mukanaa tulee ns. diagnostiikkadataa, mikä ei toimi WeatherStation-luokan kanssa, ja GSON tilttaa
- käytetään try-catchia ettei koodi tilttaa:
- .callback { publish ->
- // this callback runs everytime your code receives new data payload
- // muutetaan raakadata tekstiksi (tässä tapauksessa JSONia)
- var result = String(publish.getPayloadAsBytes())
- // Log.d("ADVTECH", result)
- // try/catch => koodi joka saattaa tiltata laitetaan tryn sisälle:
- // catch hoitaa virhetilanteet
- // nyt MQTT:stä tulee välillä diagnostiikkadataa, mikä rikkoo GSON-koodin
- // try/catch estää ohjelman tilttaamisen
- try {
- // muutetaan vastaanotettu data JSONista -> WeatherStation -luokan olioksi
- var item : WeatherStation = gson.fromJson(result, WeatherStation::class.java)
- Log.d("ADVTECH", item.d.get1().v.toString() + "C")
- }
- catch(e : Exception) {
- Log.d("ADVTECH", e.message.toString())
- Log.d("ADVTECH", "Saattaa olla diagnostiikkadataa.")
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement