/**
* @typedef {import('../items').Item} Item
* @private
*/
/**
* Item channel link namespace.
* This namespace provides access to Item channel links.
*
* @namespace items.metadata.itemchannellink
*/
const osgi = require('../../osgi');
const utils = require('../../utils');
const log = require('../../log')('itemchannellink');
const { _getItemName } = require('../../helpers');
const itemChannelLinkRegistry = osgi.getService('org.openhab.core.thing.link.ItemChannelLinkRegistry');
const ItemChannelLink = Java.type('org.openhab.core.thing.link.ItemChannelLink');
const ChannelUID = Java.type('org.openhab.core.thing.ChannelUID');
const Configuration = Java.type('org.openhab.core.config.core.Configuration');
/**
* Creates a new ItemChannelLink object.
*
* @private
* @param {string} itemName the name of the Item
* @param {string} channelUID
* @param {object} [conf] channel configuration
* @returns {ItemChannelLink} ItemChannelLink object
*/
function _createItemChannelLink (itemName, channelUID, conf) {
log.debug(`Creating ItemChannelLink ${itemName} -> ${channelUID}...`);
if (typeof conf === 'object') {
log.debug(` .. with configuration ${conf}`);
return new ItemChannelLink(itemName, new ChannelUID(channelUID), new Configuration(conf));
} else {
return new ItemChannelLink(itemName, new ChannelUID(channelUID));
}
}
/**
* Gets a channel link of from an Item.
*
* @memberof items.metadata.itemchannellink
* @param {Item|string} itemOrName {@link Item} or the name of the Item
* @param {string} channelUID
* @returns {{itemName: string, configuration: *, channelUID: string}|null} the ItemChannelLink or `null` if none exists
*/
function getItemChannelLink (itemOrName, channelUID) {
const itemName = _getItemName(itemOrName);
log.debug(`Getting ItemChannelLink ${itemName} -> ${channelUID} from registry...`);
const itemChannelLink = itemChannelLinkRegistry.get(itemName + ' -> ' + channelUID);
if (itemChannelLink === null || itemChannelLink === undefined) return null;
return {
itemName: itemChannelLink.getItemName().toString(),
channelUID: itemChannelLink.getLinkedUID().toString(),
configuration: utils.javaMapToJsObj(itemChannelLink.getConfiguration().getProperties())
};
}
/**
* Adds a new channel link to an Item.
*
* @private
* @param {string} itemName the name of the Item
* @param {string} channelUID
* @param {object} [conf] channel configuration
* @returns {{itemName: string, configuration: *, channelUID: string}} the ItemChannelLink
*/
function _addItemChannelLink (itemName, channelUID, conf) {
log.debug(`Adding ItemChannelLink ${itemName} -> ${channelUID} to registry...`);
const itemChannelLink = _createItemChannelLink(itemName, channelUID, conf);
itemChannelLinkRegistry.add(itemChannelLink);
return {
itemName: itemChannelLink.getItemName().toString(),
channelUID: itemChannelLink.getLinkedUID().toString(),
configuration: utils.javaMapToJsObj(itemChannelLink.getConfiguration().getProperties())
};
}
/**
* Updates a channel link of an Item.
*
* @private
* @param {string} itemName the name of the Item
* @param {string} channelUID
* @param {object} [conf] channel configuration
* @returns {{itemName: string, configuration: object, channelUID: string}|null} the old ItemChannelLink or `null` if none exists
*/
function _updateItemChannelLink (itemName, channelUID, conf) {
log.debug(`Updating ItemChannelLink ${itemName} -> ${channelUID} in registry...`);
const itemChannelLink = _createItemChannelLink(itemName, channelUID, conf);
itemChannelLinkRegistry.update(itemChannelLink);
if (itemChannelLink === null || itemChannelLink === undefined) return null;
return {
itemName: itemChannelLink.getItemName().toString(),
channelUID: itemChannelLink.getLinkedUID().toString(),
configuration: utils.javaMapToJsObj(itemChannelLink.getConfiguration().getProperties())
};
}
/**
* Adds or updates a channel link of an Item.
*
* @memberof items.metadata.itemchannellink
* @param {Item|string} itemOrName {@link Item} or the name of the Item
* @param {string} channelUID
* @param {object} [conf] channel configuration
* @returns {{itemName: string, configuration: object, channelUID: string}|null} the old ItemChannelLink or `null` if it did not exist
*/
function replaceItemChannelLink (itemOrName, channelUID, conf) {
const itemName = _getItemName(itemOrName);
const existing = getItemChannelLink(itemName, channelUID);
if (existing === null) {
_addItemChannelLink(itemName, channelUID, conf);
} else {
_updateItemChannelLink(itemName, channelUID, conf);
}
return existing;
}
/**
* Removes a channel link from an Item.
*
* @memberof items.metadata.itemchannellink
* @param {Item|string} itemOrName {@link Item} or the name of the Item
* @param {string} channelUID
* @returns {{itemName: string, configuration: object, channelUID: string}|null} the removed ItemChannelLink or `null` if none exists
*/
function removeItemChannelLink (itemOrName, channelUID) {
const itemName = _getItemName(itemOrName);
log.debug(`Removing ItemChannelLink ${itemName} -> ${channelUID} from registry...`);
const itemChannelLink = itemChannelLinkRegistry.remove(itemName + ' -> ' + channelUID);
if (itemChannelLink === null || itemChannelLink === undefined) return null;
return {
itemName: itemChannelLink.getItemName().toString(),
channelUID: itemChannelLink.getLinkedUID().toString(),
configuration: utils.javaMapToJsObj(itemChannelLink.getConfiguration().getProperties())
};
}
/**
* Removes all channel links from the given Item.
*
* @memberof items.metadata.itemchannellink
* @param {string} itemName the name of the Item
* @returns {number} number of links removed
*/
function removeLinksForItem (itemName) {
return itemChannelLinkRegistry.removeLinksForItem(itemName);
}
/**
* Removes all orphaned (Item or channel missing) links.
*
* @memberof items.metadata.itemchannellink
* @returns {number} number of links removed
*/
function removeOrphanedItemChannelLinks () {
return itemChannelLinkRegistry.purge();
}
module.exports = {
getItemChannelLink,
replaceItemChannelLink,
removeItemChannelLink,
removeLinksForItem,
removeOrphanedItemChannelLinks
};