Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,12 @@ This module provides common external URLs.
## DB API: DB types and enums.
This module provides mappings between database columns and JS keys.

<a name="module_DB API_ DB types and enums..warnings"></a>

### DB API: DB types and enums..warnings
Text fragments shared by warning messages

**Kind**: static property of [<code>DB API: DB types and enums.</code>](#module_DB API_ DB types and enums.)
<a name="module_Renderer API_ Renderer API."></a>

## Renderer API: Renderer API.
Expand Down Expand Up @@ -15247,6 +15253,7 @@ This module provides the API to access zcl specific information.
* [~httpPostSaveSessionKeyValue(db)](#module_REST API_ user data..httpPostSaveSessionKeyValue) ⇒
* [~httpPostCluster(db)](#module_REST API_ user data..httpPostCluster) ⇒
* [~httpPostForcedExternal(db)](#module_REST API_ user data..httpPostForcedExternal) ⇒ <code>function</code>
* [~handleAttributeStorageNotification(db, sessionId, endpointTypeId, clusterRef, attributeId, storageValue)](#module_REST API_ user data..handleAttributeStorageNotification)
* [~httpPostAttributeUpdate(db)](#module_REST API_ user data..httpPostAttributeUpdate) ⇒
* [~httpPostCommandUpdate(db)](#module_REST API_ user data..httpPostCommandUpdate) ⇒
* [~httpPostEventUpdate(db)](#module_REST API_ user data..httpPostEventUpdate) ⇒
Expand Down Expand Up @@ -15483,6 +15490,22 @@ options for the identified package. The results are sent back to the client as a
| --- | --- | --- |
| db | <code>Object</code> | The database connection object. |

<a name="module_REST API_ user data..handleAttributeStorageNotification"></a>

### REST API: user data~handleAttributeStorageNotification(db, sessionId, endpointTypeId, clusterRef, attributeId, storageValue)
Set or delete external storage warnings when the user changes attribute storage.

**Kind**: inner method of [<code>REST API: user data</code>](#module_REST API_ user data)

| Param | Type |
| --- | --- |
| db | <code>\*</code> |
| sessionId | <code>\*</code> |
| endpointTypeId | <code>\*</code> |
| clusterRef | <code>\*</code> |
| attributeId | <code>\*</code> |
| storageValue | <code>\*</code> |

<a name="module_REST API_ user data..httpPostAttributeUpdate"></a>

### REST API: user data~httpPostAttributeUpdate(db) ⇒
Expand Down Expand Up @@ -16599,6 +16622,7 @@ This module provides the REST API to the user specific data.
* [~httpPostSaveSessionKeyValue(db)](#module_REST API_ user data..httpPostSaveSessionKeyValue) ⇒
* [~httpPostCluster(db)](#module_REST API_ user data..httpPostCluster) ⇒
* [~httpPostForcedExternal(db)](#module_REST API_ user data..httpPostForcedExternal) ⇒ <code>function</code>
* [~handleAttributeStorageNotification(db, sessionId, endpointTypeId, clusterRef, attributeId, storageValue)](#module_REST API_ user data..handleAttributeStorageNotification)
* [~httpPostAttributeUpdate(db)](#module_REST API_ user data..httpPostAttributeUpdate) ⇒
* [~httpPostCommandUpdate(db)](#module_REST API_ user data..httpPostCommandUpdate) ⇒
* [~httpPostEventUpdate(db)](#module_REST API_ user data..httpPostEventUpdate) ⇒
Expand Down Expand Up @@ -16835,6 +16859,22 @@ options for the identified package. The results are sent back to the client as a
| --- | --- | --- |
| db | <code>Object</code> | The database connection object. |

<a name="module_REST API_ user data..handleAttributeStorageNotification"></a>

### REST API: user data~handleAttributeStorageNotification(db, sessionId, endpointTypeId, clusterRef, attributeId, storageValue)
Set or delete external storage warnings when the user changes attribute storage.

**Kind**: inner method of [<code>REST API: user data</code>](#module_REST API_ user data)

| Param | Type |
| --- | --- |
| db | <code>\*</code> |
| sessionId | <code>\*</code> |
| endpointTypeId | <code>\*</code> |
| clusterRef | <code>\*</code> |
| attributeId | <code>\*</code> |
| storageValue | <code>\*</code> |

<a name="module_REST API_ user data..httpPostAttributeUpdate"></a>

### REST API: user data~httpPostAttributeUpdate(db) ⇒
Expand Down
3 changes: 2 additions & 1 deletion src-electron/db/query-attribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -1301,7 +1301,8 @@ async function selectAttributesByEndpointTypeClusterId(
ATTRIBUTE.REPORT_MIN_INTERVAL,
ATTRIBUTE.REPORT_MAX_INTERVAL,
ATTRIBUTE.REPORTABLE_CHANGE,
ENDPOINT_TYPE_ATTRIBUTE.INCLUDED
ENDPOINT_TYPE_ATTRIBUTE.INCLUDED,
ENDPOINT_TYPE_ATTRIBUTE.STORAGE_OPTION
FROM
ATTRIBUTE
JOIN
Expand Down
33 changes: 33 additions & 0 deletions src-electron/db/query-endpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,37 @@ async function deleteEndpoint(db, id) {
return dbApi.dbRemove(db, 'DELETE FROM ENDPOINT WHERE ENDPOINT_ID = ?', [id])
}

/**
* Retrieves endpoint identifiers for a session and endpoint type.
*
* @param {*} db
* @param {*} sessionId
* @param {*} endpointTypeId
* @returns Promise that resolves into an array of endpoint identifiers.
*/
async function selectEndpointIdentifiersBySessionAndEndpointType(
db,
sessionId,
endpointTypeId
) {
let rows = await dbApi.dbAll(
db,
`
SELECT
ENDPOINT_IDENTIFIER
FROM
ENDPOINT
WHERE
SESSION_REF = ?
AND ENDPOINT_TYPE_REF = ?
ORDER BY
ENDPOINT_IDENTIFIER
`,
[sessionId, endpointTypeId]
)
return rows.map((r) => r.ENDPOINT_IDENTIFIER)
}

/**
* Returns ENDPOINT_ID of the Endpoint's Parent Endpoint
*
Expand Down Expand Up @@ -667,3 +698,5 @@ exports.getParentEndpointIdentifier = getParentEndpointIdentifier
exports.selectAllEndpointsBasedOnTemplateCategory =
selectAllEndpointsBasedOnTemplateCategory
exports.getRootNode = getRootNode
exports.selectEndpointIdentifiersBySessionAndEndpointType =
selectEndpointIdentifiersBySessionAndEndpointType
86 changes: 82 additions & 4 deletions src-electron/db/query-session-notification.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const dbApi = require('./db-api.js')
const dbMapping = require('./db-mapping.js')
const wsServer = require('../server/ws-server.js')
const dbEnum = require('../../src-shared/db-enum.js')

/**
* Sets a notification in the SESSION_NOTICE table
*
Expand Down Expand Up @@ -212,10 +213,12 @@ async function setNotificationOnFeatureChange(db, sessionId, result) {
}
} else {
await deleteNotificationWithPatterns(db, sessionId, outdatedWarningPatterns)
if (displayWarning) {
await setNotification(db, 'WARNING', warningMessage, sessionId, 2, 0)
} else {
await searchNotificationByMessageAndDelete(db, sessionId, warningMessage)
for (const message of warningMessage) {
Comment thread
ethanzhouyc marked this conversation as resolved.
if (displayWarning) {
await setNotification(db, 'WARNING', message, sessionId, 2, 0)
} else {
await searchNotificationByMessageAndDelete(db, sessionId, message)
}
}
}
}
Expand Down Expand Up @@ -306,6 +309,77 @@ async function getNotificationMessagesWithPattern(db, sessionId, pattern) {
return rows.reverse().map((row) => row.NOTICE_MESSAGE)
}

/**
* True if the notice mentions this endpoint, cluster, attribute, and the external-storage warning phrase.
*
* @param {string} message
* @param {string} endpointDisplay
* @param {string} clusterName
* @param {string} attributeName
* @returns {boolean}
*/
function messageIsExternalAttributeStorageNoticeForAttribute(
message,
endpointDisplay,
clusterName,
attributeName
) {
let phrase = dbEnum.warnings.externalStorageControl
let endpointStr = String(endpointDisplay)
let clusterStr = String(clusterName)
let attrStr = String(attributeName)
return (
message.includes(phrase) &&
message.includes(`endpoint: ${endpointStr},`) &&
message.includes(`cluster: ${clusterStr},`) &&
message.includes(attrStr)
)
}

/**
* Remove external-attribute-storage session notices for a given attribute.
*
* @param {*} db
* @param {*} sessionId
* @param {*} endpointDisplay
* @param {*} clusterName
* @param {*} attributeName
* @returns {Promise<boolean|Promise[]>}
*/
async function deleteExternalAttributeStorageNotificationsForAttribute(
db,
sessionId,
endpointDisplay,
clusterName,
attributeName
) {
let likePattern = `%${dbEnum.warnings.externalStorageControl}%`
let rows = await dbApi.dbAll(
db,
`SELECT NOTICE_ID, NOTICE_MESSAGE FROM SESSION_NOTICE
WHERE SESSION_REF = ? AND NOTICE_MESSAGE LIKE ?`,
[sessionId, likePattern]
)
let endpointStr = String(endpointDisplay)
let clusterStr = String(clusterName)
let attrStr = String(attributeName)
let ids = []
for (let row of rows) {
if (
messageIsExternalAttributeStorageNoticeForAttribute(
row.NOTICE_MESSAGE,
endpointStr,
clusterStr,
attrStr
)
) {
ids.push(row.NOTICE_ID)
}
}
if (ids.length === 0) return false
return Promise.all(ids.map((id) => deleteNotification(db, id)))
}

// exports
exports.setNotification = setNotification
exports.deleteNotification = deleteNotification
Expand All @@ -319,3 +393,7 @@ exports.setNotificationOnFeatureChange = setNotificationOnFeatureChange
exports.setRequiredElementWarning = setRequiredElementWarning
exports.deleteNotificationWithPatterns = deleteNotificationWithPatterns
exports.getNotificationMessagesWithPattern = getNotificationMessagesWithPattern
exports.deleteExternalAttributeStorageNotificationsForAttribute =
deleteExternalAttributeStorageNotificationsForAttribute
exports.messageIsExternalAttributeStorageNoticeForAttribute =
messageIsExternalAttributeStorageNoticeForAttribute
73 changes: 72 additions & 1 deletion src-electron/rest/user-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ function httpPostCheckConformOnFeatureUpdate(db) {
clusterFeatures,
endpointId,
endpointTypeId,
storageOption,
changeConfirmed
} = request.body

Expand All @@ -135,7 +136,8 @@ function httpPostCheckConformOnFeatureUpdate(db) {
featureMap,
featureData,
endpointId,
clusterFeatures
clusterFeatures,
storageOption
)

if (changeConfirmed || result.disableChange) {
Expand Down Expand Up @@ -421,6 +423,63 @@ function httpPostForcedExternal(db) {
}
}

/**
* Set or delete external storage warnings when the user changes attribute storage.
*
* @param {*} db
* @param {*} sessionId
* @param {*} endpointTypeId
* @param {*} clusterRef
* @param {*} attributeId
* @param {*} storageValue
*/
async function handleAttributeStorageNotification(
db,
sessionId,
endpointTypeId,
clusterRef,
attributeId,
storageValue
) {
let attr = await queryZcl.selectAttributeById(db, attributeId)
let cluster = await queryZcl.selectClusterById(db, clusterRef)
let endpointIdentifiers =
await queryEndpoint.selectEndpointIdentifiersBySessionAndEndpointType(
db,
sessionId,
endpointTypeId
)
let endpointDisplay =
endpointIdentifiers.length > 0
? String(endpointIdentifiers[0])
: String(endpointTypeId)
let attributeName = attr?.name || attr?.label || 'Unknown'
let clusterName = cluster?.name || 'Unknown'
let userMessage = env.formatEmojiMessage(
'⚠️',
`On endpoint: ${endpointDisplay}, cluster: ${clusterName}, attribute ${attributeName} has ${dbEnum.warnings.externalStorageControl}`
)

if (storageValue === dbEnum.storageOption.external) {
await querySessionNotification.setWarningIfMessageNotExists(
db,
sessionId,
userMessage
)
} else if (
storageValue === dbEnum.storageOption.ram ||
storageValue === dbEnum.storageOption.nvm
) {
await querySessionNotification.deleteExternalAttributeStorageNotificationsForAttribute(
db,
sessionId,
endpointDisplay,
clusterName,
attributeName
)
}
}

/**
* HTTP POST attribute update
*
Expand Down Expand Up @@ -476,6 +535,18 @@ function httpPostAttributeUpdate(db) {
)
)
)

if (listType === restApi.updateKey.attributeStorage) {
await handleAttributeStorageNotification(
db,
request.zapSessionId,
selectedEndpoint,
clusterRef,
id,
value
)
}

// send latest value to frontend to update UI
let eptAttr = await queryZcl.selectEndpointTypeAttribute(
db,
Expand Down
Loading
Loading