Artik Cloud Connector Code Uploading Issue


#1

Hi, i have created an artik cloud connector device type. Our requirement is to have sub devices under the artik cloud connector. i have created sub device manifest and the cfg.json file and don’t know how to upload the groovy code + cfg.json + sub-device manifest. please help me and elaborate the steps for the same


#2

For each subdevice type, you should create a new device type and create its associated manifest. Then in the top device type that holds your cloud connector code, upload the groovy code and the config json file.
In this config file you should link your top DT to the subdevices DTs with this field

...
      "extSdtidsMapper": {
            "<name of the subdevice type>": "<device type ID>"
      }

In your groovy code every time you want to create a new sub-device, you should use the following API to create an event: http://artikcloud.github.io/artikcloud-cloudconnector-sdk/apidoc/#cloud.artik.cloudconnector.api_v1.Event

The EventType parameter should be EventType.createOrUpdateDevice and extSubDeviceTypeId should match the <name of the subdevice type> you entered in the config JSON file. This is how the cloud connector framework will match the subdevice you want to create and its device type, therefore its manifest.

The Netatmo CC is a good example of how to handle subdevices: https://github.com/artikcloud/artikcloud-cloudconnector-samples/blob/09d054f184fe0f0a63284ca7b405f2c8c88ac9f1/netatmo-thermostat/src/main/groovy/cloudconnector/MyCloudConnector.groovy#L177


#3

i have created the config.json file and also mapped all the sub devices. How can i upload the config.json file and also the individual sub-device manifest.json file to artik cloud. from my developer dashboard i could only upload the groovy code not the config.json.


#4

now i have a groovy code file plus 3 manifest file one for cloud connector and the other 2 for sub devices plus a config.json file. can i upload the whole files as a single zip? please help me with this


#5

The manifest files of the subdevices should be uploaded separately to each new device type you create to match your various types of subdevices. Just create a regular new device type and upload the manifest, or use the UI to recreate it.

There is no uploading of the config JSON file in the UI, all the parameters you may want to set in it are mapped and available to be changed in the “Cloud Authentication” (auth parameters) and “Connector Code” (custom parameters) tabs. As you noticed there is no way to enter the DTIDs in the extSdtidsMapper field, this is a missing feature that will be implemented later.

In the meantime you can use the API to send the config.json file manually without going through the UI, using this sample script:

#!/bin/sh
      
DT_ID=$1
VERSION=$2
BEARER=$3
 
REQ_DATA=/tmp/req0.json
 
function json_escape(){
  cat $1 | python -c 'import json,sys; print json.dumps(sys.stdin.read())'
}
 
FCTS_ENC=$(json_escape src/main/groovy/cloudconnector/MyCloudConnector.groovy)
CFG_ENC=$(json_escape src/main/groovy/cloudconnector/cfg_prod.json)
REQ_DATA=/tmp/req2.json
cat >$REQ_DATA <<EOF
{
    "config": $CFG_ENC,
    "sourceType": "groovy",
    "source": $FCTS_ENC
}
EOF
 
curl -i --request POST --header "Content-type: application/json" --header "Authorization: Bearer $BEARER" "https://api.artik.cloud/v1.1/cloudconnectors/$DT_ID" --data @$REQ_DATA
echo
 
curl -i --request POST --header "Content-type: application/json" --header "Authorization: Bearer $BEARER" "https://api.artik.cloud/v1.1/cloudconnectors/$DT_ID/$VERSION/status" --data '{"status": "PENDING"}'
echo

You need to run this script at the root of the CC SDK, with the following parameters in this respective order:
<Device Type ID> <version> <User token>

Note that version needs to be the latest version you published incremented by one. Also the config JSON file needs to be renamed into cfg_prod.json


#6

Thanks Gregory…let me try this and will revert back the status


#7

hi Gregory…This is my config.json file with extsids

“extSdtidsMapper” : {
“lightBulbNormal” : “1001”,
“lightBulbTube” : “1002”,
“lightBulbLed” : “1003”,
“t5Tube” : “1005”,
“lightBulbCfl” : “1006”,
“lightBulbRgb” : “1007”,
“twoToneBulb” : “1008”,
“twoToneBulbRgb” : “1009”,
“twoToneBulbNew” : “1010”,
“lightBulbNormalNew”: “1012”,
“t5Tubenew” : “1013”,
“lightBulbRgbNew” : “1014”,
“rgbWNew” : “1018”,
“cctTube” : “1022”,
“rgbCct” : “1021”,
“cctRetrofit” : “1502”,
“ceilingFan” : “1501”,
“newBulb” : “1024”,
“newDimmableBulb” : “1023”,
“newRgbLed” : “1027”,
“wiseBulbNew” : “1025”,
“slmD” : “1029”,
“microsensorUwp” : “1503”
}

when running the script i need to provide Device Type ID, version, User token
"Device Type ID" means the cloud connector device type id ?? or the device type id for the newly created sub device through web ui??
And also how can i get the user token??


#8

just updating you… i have run the script file. Now the new version got uploaded and its in pending state.
will update you once its been approved


#9

It seems you finally managed to find the missing elements. However I’m not sure it’s going to work since your extSdtidsMapper does not seem right.

The device type IDs cannot be any customer ID you pick, they should match with each kind of device should be a full UUID provided by ARTIK Cloud. It should be the device type UUID that is generated by ARTIK Cloud when you create a new device type, just like you did for the cloud connector. The main difference between the cloud connector DT and the subdevices DT is that the subdevices should be configured with:

This device type sends data directly to ARTIK Cloud

where the CC DT should have:

This device type sends data to a cloud that ARTIK Cloud receives data from

You then have to create one device type for each of your 20+ kind of devices, and upload a manifest describing fields/actions for each one of them. After that you can take the Device Type UUIDs generated by ARTIK Cloud and copy them to the extSdtidsMapper structure.


#10

okay Gregory. Also one more question if in future we add 5 more deviceType in our company do i need to edit the config.json file and resubmit the hole thing again or is there any way i can dynamic addition of the new device type (programatically)


#11

There is no self-served way to add new device types to the JSON configuration at the moment, you’ll have to go through the submission process again. Note that this process is usually very quick (under 24h), especially for minor changes such as modifying the configuration.


#12

Thanks Gregory. i have done the modifications and submitted the code again…


#13

Hi Gregory…How are you?..They approved the code and its working fine now.
Next thing we want to test is

  1. Notification part
  2. integration with external smart devices/triggers to our
    devices.

#14

From the present state of the cloud connector can we operate our sub devices by creating a rule with Other Smart devices say like philips hue…etc
Present condition is as follows…
1 SECURE DEVICE REGISTRATION Not Enabled

2 Private Device Type
Visible only to users that are part of your organization

And about the notification…whether the artik cloud pushes notification to the third party cloud or Vice Versa??


#15

If I understand well you want to:

  • Trigger actions on your subdevices based on messages from other devices

You can do that from the rules engines. If your subdevices have actions defined in their manifest, you can trigger them depending on conditions based on messages sent by other devices (Philips Hue or else…).

  • Have your cloud connector push notifications to the external cloud

This should be doable in the groovy code. You can issue REST calls to the external cloud in some of the functions of the CC. Please provide more details if you need better insight on what you want to achieve.

Note that SDR and the fact your DT is private do not affect the two points above.


#16

okay…i’ll provide all the detailed requirement, but before that please send me a link which has the detailed documentation of the “Notification” part in CC


#17

I think it’s better to show an example: https://github.com/artikcloud/artikcloud-cloudconnector-samples/blob/master/netatmo-thermostat/src/main/groovy/cloudconnector/MyCloudConnector.groovy#L255

When an action is received, the CC checks if it belongs to a subdevice and will call and return the output of this function:

	def netatmoSetThermostatSetpointMode(relayId, moduleId, mode)
	{
		def req = new RequestDef(API_URL + "/setthermpoint")
				.withQueryParams(["device_id":relayId,
					"module_id":moduleId,
					"setpoint_mode":mode
				])
		return new Good(new ActionResponse([new ActionRequest([req])]))
	}

The returned ActionRequest object contains a HTTP request to the external cloud that will be performed by ARTIK cloud. You can put any request you need here to call an API (notification or else) on the external cloud. This way when a rule triggers an action on one of your subdevice, you can translate that into an actual action or notification to the external cloud.

I hope this is what your are trying to achieve here.


#18

sorry if i am annoying you with my questions…

onNotification(Context ctx, RequestDef req)
{
	if (!req.content?.trim() || req.content == "AnyContentAsEmpty")
		return new Good(new NotificationResponse([]))

	if (req.url.endsWith("thirdpartynotifications/postsubscription"))
	{
		def json = slurper.parseText(req.content())

		return new Good(new NotificationResponse([
			new ThirdPartyNotification(new ByDid(json.did), [netatmoGetThermostatsData()])
		]))
	}

	return new Good(new NotificationResponse([]))
}

i am not sure aware the use of the above callback.

We have the following actions for devices
"setOn", “setOff”, “setIntensity”, “setCool”,"setColor"
in each of this action i’m returning this

def reqst = new RequestDef(endpoint+"/operate")
.withMethod(HttpMethod.Post).withContent(json,“application/json”)
return new Good(new ActionResponse([new ActionRequest([reqst])]))

Should i add a notification action like “sendNotification” and call the notification url when needed??
Because in each of the action mentioned above we have a specific url to be called for device operation and we can make only one api call at a time right?


#19

First let me clear something up:

onNotification => called when the external cloud sends a HTTP request on the ARTIK Cloud endpoint you configured. This is usually where you have to translate the external notification into a message that your subdevice sends to ARTIK Cloud.

onAction => Called when the user or a rule sends an action to the subdevice on ARTIK Cloud, and where you should issue a request to the external cloud to forward whatever action was requested and let the external cloud take the appropriate action.

The example you detailed above needs to be implemented in onAction. In this function you should parse the subdevice ID to know what to target in the external cloud, and parse the actions in the JSON to generate appropriate requests to the external cloud. You are allowed to return more than one request in an array as follows:

def reqst1 = new RequestDef(endpoint+"/operate")
.withMethod(HttpMethod.Post).withContent(json,“application/json”)

def reqst2 = new RequestDef(endpoint+"/whatever")
.withMethod(HttpMethod.Post).withContent(json,“application/json”)

return new Good(new ActionResponse([new ActionRequest([reqst1, reqst2])]))

#21

Yes you can do that. The URL you set seems right, you need to make sure this one is configured in your external cloud whenever it needs to make a notification to ARTIK Cloud. If the external cloud makes a request on this address, you will receive it to be processed in the onNotification function of your CC. You can parse the notification there and take appropriate actions as explained here (“Notification” chapter): https://developer.artik.cloud/documentation/cloud-connectors/implement-a-cloud-connector.html

If you want to translate the notification into an ARTIK Cloud message, you need to return a ThirdPartyNotification object, that will be processed and then call the onNotificationData callback. In this function you need to return a new Event object with the JSON data of the AKC message to create. Note that if the information sent by the external cloud is not enough to generate the data of the message, you can issue a request to the external cloud to fetch more data before ending up in onNotificationData.

Two examples:

Foursquare, no need for an additional request: https://github.com/artikcloud/artikcloud-cloudconnector-samples/blob/master/foursquare/src/main/groovy/cloudconnector/MyCloudConnector.groovy#L72

new ThirdPartyNotification(new ByExtId(eid), [], [dataToPush])

Fitbit, additional request to do: https://github.com/artikcloud/artikcloud-cloudconnector-samples/blob/master/fitbit/src/main/groovy/cloudconnector/MyCloudConnector.groovy#L182

def requestsToDo = apiEndpoint(ctx, collectionType, date).collect {ep -> new RequestDef(ep).withHeaders(["remember_date": date])}
new ThirdPartyNotification(new ByExtId(extId), requestsToDo)