• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

telefonicaid / iotagent-json / 15191019223

22 May 2025 03:44PM UTC coverage: 79.555% (-0.5%) from 80.079%
15191019223

Pull #800

github

web-flow
Merge 605ff0463 into 5034c81f3
Pull Request #800: allow receive command notifications from CB

526 of 750 branches covered (70.13%)

Branch coverage included in aggregate %.

28 of 30 new or added lines in 2 files covered. (93.33%)

13 existing lines in 3 files now uncovered.

1120 of 1319 relevant lines covered (84.91%)

135.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

68.18
/lib/iotaUtils.js
1
/*
2
 * Copyright 2016 Telefonica Investigación y Desarrollo, S.A.U
3
 *
4
 * This file is part of iotagent-json
5
 *
6
 * iotagent-json is free software: you can redistribute it and/or
7
 * modify it under the terms of the GNU Affero General Public License as
8
 * published by the Free Software Foundation, either version 3 of the License,
9
 * or (at your option) any later version.
10
 *
11
 * iotagent-json is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
 * See the GNU Affero General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Affero General Public
17
 * License along with iotagent-json.
18
 * If not, seehttp://www.gnu.org/licenses/.
19
 *
20
 * For those usages not covered by the GNU Affero General Public License
21
 * please contact with::[contacto@tid.es]
22
 */
23

24
const iotAgentLib = require('iotagent-node-lib');
1✔
25
const errors = require('./errors');
1✔
26
const dateFormat = require('dateformat');
1✔
27
const async = require('async');
1✔
28
const apply = async.apply;
1✔
29
const constants = require('./constants');
1✔
30
const context = {
1✔
31
    op: 'IoTAgentJSON.Utils'
32
};
33
const config = require('./configService');
1✔
34

35
/**
36
 * Get the API Key for the selected service if there is any, or the default API Key if a specific one does not exist.
37
 *
38
 * @param {String} service          Name of the service whose API Key we are retrieving.
39
 * @param {String} subservice       Name of the subservice whose API Key we are retrieving.
40
 * @param {Json} device             Device object.
41
 */
42
function getEffectiveApiKey(service, subservice, device, callback) {
43
    config.getLogger().debug(context, 'Getting effective API Key');
29✔
44

45
    if (device && device.apikey) {
29✔
46
        config.getLogger().debug(context, 'Using device apikey: %s', device.apikey);
6✔
47
        callback(null, device.apikey);
6✔
48
    } else {
49
        const type = device.type ? device.type : null;
23!
50
        iotAgentLib.findConfiguration(service, subservice, type, function (error, group) {
23✔
51
            if (group) {
23✔
52
                config.getLogger().debug(context, 'Using found group: %j', group);
1✔
53
                callback(null, group.apikey);
1✔
54
            } else if (config.getConfig().defaultKey) {
22!
55
                config.getLogger().debug(context, 'Using default API Key: %s', config.getConfig().defaultKey);
22✔
56
                callback(null, config.getConfig().defaultKey);
22✔
57
            } else {
58
                config
×
59
                    .getLogger()
60
                    .error(
61
                        context,
62
                        'Could not find any APIKey information for device in service %s subservice %s and type %s',
63
                        service,
64
                        subservice,
65
                        type
66
                    );
67
                callback(new errors.GroupNotFound(service, subservice, type));
×
68
            }
69
        });
70
    }
71
}
72

73
function manageConfiguration(apiKey, deviceId, device, objMessage, sendFunction, callback) {
74
    /* eslint-disable no-unused-vars */
75
    function handleSendConfigurationError(error, results) {
76
        if (error) {
6!
77
            config.getLogger().error(
×
78
                context,
79

80
                "CONFIG-001: Couldn't get the requested values from the Context Broker: %s",
81

82
                error
83
            );
84
        } else {
85
            config
6✔
86
                .getLogger()
87
                .debug(context, 'Configuration attributes sent to the device successfully.', deviceId, apiKey);
88
        }
89

90
        callback(error);
6✔
91
    }
92

93
    if (objMessage.type === 'configuration') {
6!
94
        async.waterfall(
6✔
95
            [
96
                apply(iotAgentLib.query, device.name, device.type, '', objMessage.fields, device),
97
                apply(sendFunction, apiKey, {}, deviceId)
98
            ],
99
            handleSendConfigurationError
100
        );
UNCOV
101
    } else if (objMessage.type === 'subscription') {
×
UNCOV
102
        iotAgentLib.subscribe(device, objMessage.fields, objMessage.fields, function (error) {
×
UNCOV
103
            if (error) {
×
104
                config
×
105
                    .getLogger()
106
                    .error(
107
                        context,
108
                        'CONFIG-002: There was an error subscribing device %s to attributes %j',
109
                        device.name,
110
                        objMessage.fields
111
                    );
112
            } else {
UNCOV
113
                config
×
114
                    .getLogger()
115
                    .debug(
116
                        context,
117
                        'Successfully subscribed device %s to attributes %j',
118
                        device.name,
119
                        objMessage.fields
120
                    );
121
            }
122

UNCOV
123
            callback(error);
×
124
        });
125
    } else {
126
        config.getLogger().error(context, 'CONFIG-003: Unknown command type from device %s', device.name);
×
127
        callback();
×
128
    }
129
}
130

131
function createConfigurationNotification(results) {
132
    const configurations = {};
6✔
133
    const now = new Date();
6✔
134

135
    // If it is the result of a subscription, results is an array
136
    if (Array.isArray(results)) {
6!
UNCOV
137
        for (let i = 0; i < results.length; i++) {
×
UNCOV
138
            configurations[results[i].name] = results[i].value;
×
139
        }
140
    } else {
141
        for (var att in results) {
6✔
142
            configurations[att] = results[att].value;
24✔
143
        }
144
    }
145

146
    configurations.dt = dateFormat(now, constants.DATE_FORMAT);
6✔
147
    return configurations;
6✔
148
}
149

150
/**
151
 * Retrieve a device from the device repository based on the given APIKey and DeviceID, creating one if none is
152
 * found for the given data.
153
 *
154
 * @param {String} deviceId         Device ID of the device that wants to be retrieved or created.
155
 * @param {String} apiKey           APIKey of the Device Group (or default APIKey).
156
 */
157
function retrieveDevice(deviceId, apiKey, callback) {
158
    if (apiKey === config.getConfig().defaultKey) {
222✔
159
        iotAgentLib.getDevicesByAttribute('id', deviceId, null, null, function (error, devices) {
97✔
160
            if (error) {
97!
161
                callback(error);
×
162
            } else if (devices && devices.length === 1) {
97!
163
                callback(null, devices[0]);
97✔
164
            } else {
165
                config.getLogger().error(
×
166
                    context,
167

168
                    "MEASURES-001: Couldn't find device data for APIKey %s and DeviceId %s",
169

170
                    apiKey,
171
                    deviceId
172
                );
173

174
                callback(new errors.DeviceNotFound(deviceId, { apikey: apiKey }));
×
175
            }
176
        });
177
    } else {
178
        async.waterfall(
125✔
179
            [
180
                apply(iotAgentLib.getConfigurationSilently, config.getConfig().iota.defaultResource || '', apiKey),
125!
181
                apply(iotAgentLib.findOrCreate, deviceId, apiKey), // group.apikey and apikey are the same
182
                apply(
183
                    iotAgentLib.mergeDeviceWithConfiguration,
184
                    ['lazy', 'active', 'staticAttributes', 'commands', 'subscriptions'],
185
                    [null, null, [], [], [], [], []]
186
                )
187
            ],
188
            callback
189
        );
190
    }
191
}
192

193
exports.createConfigurationNotification = createConfigurationNotification;
1✔
194
exports.getEffectiveApiKey = getEffectiveApiKey;
1✔
195
exports.manageConfiguration = manageConfiguration;
1✔
196
exports.retrieveDevice = retrieveDevice;
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc