Generic Pelion Device Management example for various Nuvoton-based boards.

DEPRECATED

This example application is not maintained and not recommended. It uses an old version of Mbed OS, Pelion DM, and Arm toolchain. It doesn't work with Mbed Studio.

Please use: https://os.mbed.com/teams/mbed-os-examples/code/mbed-os-example-pelion/

This example is known to work great on the following platforms:

Follow the Quick-Start instructions: https://cloud.mbed.com/quick-start

https://os.mbed.com/media/cache/platforms/NuMaker-IoT-M487_board_front_small.jpg.250x250_q85.jpghttps://os.mbed.com/media/cache/platforms/NuMaker-PFM-M487.png.170x170_q85.png https://os.mbed.com/media/cache/platforms/NuMaker-PFM-NUC472Small.png.170x170_q85.png

Example functionality

This example showcases the following device functionality:

  • On timer button increment, simulate Pelion LWM2M button resource change

Use this example with Mbed CLI


1. Import the application into your desktop:

mbed import https://os.mbed.com/teams/Nuvoton/code/pelion-example-common
cd pelion-example-common


2. Install the CLOUD_SDK_API_KEY

mbed config -G CLOUD_SDK_API_KEY <PELION_DM_API_KEY>

For instructions on how to generate your API key, please see the documentation.

3. Initialize firmware credentials (done once per repository). You can use the following command:

mbed dm init -d "<your company name in Pelion DM>" --model-name "<product model identifier>" -q --force

If above command do not work for your Mbed CLI, please consider upgrading Mbed CLI to version 1.8.x or above.

4. Compile and program:

mbed compile -t <toolchain> -m <TARGET_BOARD>

(supported toolchains : GCC_ARM / ARM / IAR)

5. Copy the binary file pelion-example-common.bin to your mbed device.

Note

This platform and application is suitable for evaluation and initial development. For production purposes, we recommend to use a different variant with built-in security features

Committer:
Sam Chu
Date:
Tue Dec 18 00:07:56 2018 +0800
Revision:
0:e0138281f21d
Child:
2:f07ccb7164d3
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sam Chu 0:e0138281f21d 1 // ----------------------------------------------------------------------------
Sam Chu 0:e0138281f21d 2 // Copyright 2016-2018 ARM Ltd.
Sam Chu 0:e0138281f21d 3 //
Sam Chu 0:e0138281f21d 4 // SPDX-License-Identifier: Apache-2.0
Sam Chu 0:e0138281f21d 5 //
Sam Chu 0:e0138281f21d 6 // Licensed under the Apache License, Version 2.0 (the "License");
Sam Chu 0:e0138281f21d 7 // you may not use this file except in compliance with the License.
Sam Chu 0:e0138281f21d 8 // You may obtain a copy of the License at
Sam Chu 0:e0138281f21d 9 //
Sam Chu 0:e0138281f21d 10 // http://www.apache.org/licenses/LICENSE-2.0
Sam Chu 0:e0138281f21d 11 //
Sam Chu 0:e0138281f21d 12 // Unless required by applicable law or agreed to in writing, software
Sam Chu 0:e0138281f21d 13 // distributed under the License is distributed on an "AS IS" BASIS,
Sam Chu 0:e0138281f21d 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Sam Chu 0:e0138281f21d 15 // See the License for the specific language governing permissions and
Sam Chu 0:e0138281f21d 16 // limitations under the License.
Sam Chu 0:e0138281f21d 17 // ----------------------------------------------------------------------------
Sam Chu 0:e0138281f21d 18 #ifndef MBED_TEST_MODE
Sam Chu 0:e0138281f21d 19
Sam Chu 0:e0138281f21d 20 #include "mbed.h"
Sam Chu 0:e0138281f21d 21 #include "simple-mbed-cloud-client.h"
Sam Chu 0:e0138281f21d 22 #include "FATFileSystem.h"
Sam Chu 0:e0138281f21d 23
Sam Chu 0:e0138281f21d 24 //Test SAM
Sam Chu 0:e0138281f21d 25 // An event queue is a very useful structure to debounce information between contexts (e.g. ISR and normal threads)
Sam Chu 0:e0138281f21d 26 // This is great because things such as network operations are illegal in ISR, so updating a resource in a button's fall() function is not allowed
Sam Chu 0:e0138281f21d 27 EventQueue eventQueue;
Sam Chu 0:e0138281f21d 28
Sam Chu 0:e0138281f21d 29 // Default block device
Sam Chu 0:e0138281f21d 30 BlockDevice *bd = BlockDevice::get_default_instance();
Sam Chu 0:e0138281f21d 31 FATFileSystem fs("fs");
Sam Chu 0:e0138281f21d 32
Sam Chu 0:e0138281f21d 33 // Default network interface object
Sam Chu 0:e0138281f21d 34 NetworkInterface *net = NetworkInterface::get_default_instance();
Sam Chu 0:e0138281f21d 35
Sam Chu 0:e0138281f21d 36 // Declaring pointers for access to Pelion Device Management Client resources outside of main()
Sam Chu 0:e0138281f21d 37 MbedCloudClientResource *button_res;
Sam Chu 0:e0138281f21d 38 MbedCloudClientResource *pattern_res;
Sam Chu 0:e0138281f21d 39
Sam Chu 0:e0138281f21d 40 // This function gets triggered by the timer. It's easy to replace it by an InterruptIn and fall() mode on a real button
Sam Chu 0:e0138281f21d 41 void fake_button_press() {
Sam Chu 0:e0138281f21d 42 int v = button_res->get_value_int() + 1;
Sam Chu 0:e0138281f21d 43
Sam Chu 0:e0138281f21d 44 button_res->set_value(v);
Sam Chu 0:e0138281f21d 45
Sam Chu 0:e0138281f21d 46 printf("Simulated button clicked %d times\n", v);
Sam Chu 0:e0138281f21d 47 }
Sam Chu 0:e0138281f21d 48
Sam Chu 0:e0138281f21d 49 /**
Sam Chu 0:e0138281f21d 50 * PUT handler
Sam Chu 0:e0138281f21d 51 * @param resource The resource that triggered the callback
Sam Chu 0:e0138281f21d 52 * @param newValue Updated value for the resource
Sam Chu 0:e0138281f21d 53 */
Sam Chu 0:e0138281f21d 54 void pattern_updated(MbedCloudClientResource *resource, m2m::String newValue) {
Sam Chu 0:e0138281f21d 55 printf("PUT received, new value: %s\n", newValue.c_str());
Sam Chu 0:e0138281f21d 56 }
Sam Chu 0:e0138281f21d 57
Sam Chu 0:e0138281f21d 58 /**
Sam Chu 0:e0138281f21d 59 * POST handler
Sam Chu 0:e0138281f21d 60 * @param resource The resource that triggered the callback
Sam Chu 0:e0138281f21d 61 * @param buffer If a body was passed to the POST function, this contains the data.
Sam Chu 0:e0138281f21d 62 * Note that the buffer is deallocated after leaving this function, so copy it if you need it longer.
Sam Chu 0:e0138281f21d 63 * @param size Size of the body
Sam Chu 0:e0138281f21d 64 */
Sam Chu 0:e0138281f21d 65 void blink_callback(MbedCloudClientResource *resource, const uint8_t *buffer, uint16_t size) {
Sam Chu 0:e0138281f21d 66 printf("POST received. Going to blink LED pattern: %s\n", pattern_res->get_value().c_str());
Sam Chu 0:e0138281f21d 67
Sam Chu 0:e0138281f21d 68 static DigitalOut augmentedLed(LED1); // LED that is used for blinking the pattern
Sam Chu 0:e0138281f21d 69
Sam Chu 0:e0138281f21d 70 // Parse the pattern string, and toggle the LED in that pattern
Sam Chu 0:e0138281f21d 71 string s = std::string(pattern_res->get_value().c_str());
Sam Chu 0:e0138281f21d 72 size_t i = 0;
Sam Chu 0:e0138281f21d 73 size_t pos = s.find(':');
Sam Chu 0:e0138281f21d 74 while (pos != string::npos) {
Sam Chu 0:e0138281f21d 75 wait_ms(atoi(s.substr(i, pos - i).c_str()));
Sam Chu 0:e0138281f21d 76 augmentedLed = !augmentedLed;
Sam Chu 0:e0138281f21d 77
Sam Chu 0:e0138281f21d 78 i = ++pos;
Sam Chu 0:e0138281f21d 79 pos = s.find(':', pos);
Sam Chu 0:e0138281f21d 80
Sam Chu 0:e0138281f21d 81 if (pos == string::npos) {
Sam Chu 0:e0138281f21d 82 wait_ms(atoi(s.substr(i, s.length()).c_str()));
Sam Chu 0:e0138281f21d 83 augmentedLed = !augmentedLed;
Sam Chu 0:e0138281f21d 84 }
Sam Chu 0:e0138281f21d 85 }
Sam Chu 0:e0138281f21d 86 }
Sam Chu 0:e0138281f21d 87
Sam Chu 0:e0138281f21d 88 /**
Sam Chu 0:e0138281f21d 89 * Notification callback handler
Sam Chu 0:e0138281f21d 90 * @param resource The resource that triggered the callback
Sam Chu 0:e0138281f21d 91 * @param status The delivery status of the notification
Sam Chu 0:e0138281f21d 92 */
Sam Chu 0:e0138281f21d 93 void button_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status) {
Sam Chu 0:e0138281f21d 94 printf("Button notification, status %s (%d)\n", MbedCloudClientResource::delivery_status_to_string(status), status);
Sam Chu 0:e0138281f21d 95 }
Sam Chu 0:e0138281f21d 96
Sam Chu 0:e0138281f21d 97 /**
Sam Chu 0:e0138281f21d 98 * Registration callback handler
Sam Chu 0:e0138281f21d 99 * @param endpoint Information about the registered endpoint such as the name (so you can find it back in portal)
Sam Chu 0:e0138281f21d 100 */
Sam Chu 0:e0138281f21d 101 void registered(const ConnectorClientEndpointInfo *endpoint) {
Sam Chu 0:e0138281f21d 102 printf("Connected to Pelion Device Management. Endpoint Name: %s\n", endpoint->internal_endpoint_name.c_str());
Sam Chu 0:e0138281f21d 103 }
Sam Chu 0:e0138281f21d 104
Sam Chu 0:e0138281f21d 105 int main(void) {
Sam Chu 0:e0138281f21d 106 printf("Starting Simple Pelion Device Management Client example\n");
Sam Chu 0:e0138281f21d 107 printf("Connecting to the network...\n");
Sam Chu 0:e0138281f21d 108
Sam Chu 0:e0138281f21d 109 // Connect to the internet (DHCP is expected to be on)
Sam Chu 0:e0138281f21d 110 nsapi_error_t status = net->connect();
Sam Chu 0:e0138281f21d 111
Sam Chu 0:e0138281f21d 112 if (status != NSAPI_ERROR_OK) {
Sam Chu 0:e0138281f21d 113 printf("Connecting to the network failed %d!\n", status);
Sam Chu 0:e0138281f21d 114 return -1;
Sam Chu 0:e0138281f21d 115 }
Sam Chu 0:e0138281f21d 116
Sam Chu 0:e0138281f21d 117 printf("Connected to the network successfully. IP address: %s\n", net->get_ip_address());
Sam Chu 0:e0138281f21d 118
Sam Chu 0:e0138281f21d 119 // SimpleMbedCloudClient handles registering over LwM2M to Pelion Device Management
Sam Chu 0:e0138281f21d 120 SimpleMbedCloudClient client(net, bd, &fs);
Sam Chu 0:e0138281f21d 121 int client_status = client.init();
Sam Chu 0:e0138281f21d 122 if (client_status != 0) {
Sam Chu 0:e0138281f21d 123 printf("Pelion Client initialization failed (%d)\n", client_status);
Sam Chu 0:e0138281f21d 124 return -1;
Sam Chu 0:e0138281f21d 125 }
Sam Chu 0:e0138281f21d 126
Sam Chu 0:e0138281f21d 127 // Creating resources, which can be written or read from the cloud
Sam Chu 0:e0138281f21d 128 button_res = client.create_resource("3200/0/5501", "button_count");
Sam Chu 0:e0138281f21d 129 button_res->set_value(0);
Sam Chu 0:e0138281f21d 130 button_res->methods(M2MMethod::GET);
Sam Chu 0:e0138281f21d 131 button_res->observable(true);
Sam Chu 0:e0138281f21d 132 button_res->attach_notification_callback(button_callback);
Sam Chu 0:e0138281f21d 133
Sam Chu 0:e0138281f21d 134 pattern_res = client.create_resource("3201/0/5853", "blink_pattern");
Sam Chu 0:e0138281f21d 135 pattern_res->set_value("500:500:500:500:500:500:500:500");
Sam Chu 0:e0138281f21d 136 pattern_res->methods(M2MMethod::GET | M2MMethod::PUT);
Sam Chu 0:e0138281f21d 137 pattern_res->attach_put_callback(pattern_updated);
Sam Chu 0:e0138281f21d 138
Sam Chu 0:e0138281f21d 139 MbedCloudClientResource *blink_res = client.create_resource("3201/0/5850", "blink_action");
Sam Chu 0:e0138281f21d 140 blink_res->methods(M2MMethod::POST);
Sam Chu 0:e0138281f21d 141 blink_res->attach_post_callback(blink_callback);
Sam Chu 0:e0138281f21d 142
Sam Chu 0:e0138281f21d 143 printf("Initialized Pelion Client. Registering...\n");
Sam Chu 0:e0138281f21d 144
Sam Chu 0:e0138281f21d 145 // Callback that fires when registering is complete
Sam Chu 0:e0138281f21d 146 client.on_registered(&registered);
Sam Chu 0:e0138281f21d 147
Sam Chu 0:e0138281f21d 148 // Register with Pelion Device Management
Sam Chu 0:e0138281f21d 149 client.register_and_connect();
Sam Chu 0:e0138281f21d 150
Sam Chu 0:e0138281f21d 151 // Placeholder for callback to update local resource when GET comes.
Sam Chu 0:e0138281f21d 152 // The timer fires on an interrupt context, but debounces it to the eventqueue, so it's safe to do network operations
Sam Chu 0:e0138281f21d 153 Ticker timer;
Sam Chu 0:e0138281f21d 154 timer.attach(eventQueue.event(&fake_button_press), 5.0);
Sam Chu 0:e0138281f21d 155
Sam Chu 0:e0138281f21d 156 // You can easily run the eventQueue in a separate thread if required
Sam Chu 0:e0138281f21d 157 eventQueue.dispatch_forever();
Sam Chu 0:e0138281f21d 158 }
Sam Chu 0:e0138281f21d 159 #endif