-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add Core SiteWise Asset Module
Add Core SiteWise Asset Module that supports: * AssetSummary * AssetModel * AssetPropertyValue
- Loading branch information
1 parent
a50b31e
commit a3ffec2
Showing
16 changed files
with
560 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 96 additions & 0 deletions
96
packages/components/src/components/iot-asset-details/iot-asset-details.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import { Component, h, Prop, State, Watch } from '@stencil/core'; | ||
import { | ||
getSiteWiseAssetModule, | ||
SiteWiseAssetSession, | ||
AssetSummaryQuery, | ||
AssetModelQuery, | ||
AssetPropertyValueQuery, | ||
} from '@iot-app-kit/core'; | ||
import { AssetPropertyValue, AssetSummary, DescribeAssetModelResponse } from '@aws-sdk/client-iotsitewise'; | ||
import { AssetModelProperty } from '@aws-sdk/client-iotsitewise/dist-types/models/models_0'; | ||
|
||
@Component({ | ||
tag: 'iot-asset-details', | ||
shadow: false, | ||
}) | ||
export class IotAssetDetails { | ||
@Prop() query: AssetSummaryQuery; | ||
@State() assetSummary: AssetSummary | null = null; | ||
@State() assetModel: DescribeAssetModelResponse | null = null; | ||
@State() assetPropertyValues: Map<string, string> = new Map(); | ||
|
||
@State() assetSession: SiteWiseAssetSession; | ||
|
||
componentWillLoad() { | ||
this.assetSession = getSiteWiseAssetModule().startSession(); | ||
this.assetSession.addRequest(this.query, (summary: AssetSummary) => { | ||
this.assetSummary = summary; | ||
const assetId = this.assetSummary?.id as string; | ||
const modelQuery: AssetModelQuery = { assetModelId: this.assetSummary.assetModelId as string }; | ||
this.assetSession.addRequest(modelQuery, (assetModel: DescribeAssetModelResponse) => { | ||
this.assetModel = assetModel; | ||
assetModel.assetModelProperties?.forEach((prop) => { | ||
let propQuery: AssetPropertyValueQuery = { assetId: assetId, propertyId: prop.id as string }; | ||
this.assetSession.addRequest(propQuery, (propValue: AssetPropertyValue) => { | ||
const copy = new Map(this.assetPropertyValues); | ||
copy.set(prop.id as string, this.convertToString(propValue)); | ||
this.assetPropertyValues = copy; | ||
}); | ||
}); | ||
}); | ||
}); | ||
} | ||
|
||
convertToString(propValue: AssetPropertyValue): string { | ||
if (propValue == undefined) { | ||
return ''; | ||
} | ||
const value = propValue.value; | ||
return ( | ||
value?.stringValue || | ||
value?.booleanValue?.toString() || | ||
value?.doubleValue?.toString(10) || | ||
value?.integerValue?.toString(10) || | ||
'' | ||
); | ||
} | ||
|
||
componentDidUnmount() { | ||
this.assetSession.close(); | ||
} | ||
|
||
/** | ||
* Sync subscription to change in queried data | ||
*/ | ||
@Watch('query') | ||
onUpdateProp(newProp: unknown, oldProp: unknown) { | ||
/* TODO: | ||
if (!isEqual(newProp, oldProp) && this.update != null) { | ||
this.update({ | ||
query: this.query, | ||
requestInfo: this.requestInfo, | ||
}); | ||
} | ||
*/ | ||
} | ||
|
||
render() { | ||
return ( | ||
<div> | ||
<h2>{this.assetSummary?.name}</h2> | ||
<p>{this.assetSummary?.arn}</p> | ||
<p> | ||
<b>Model: </b> | ||
{this.assetModel?.assetModelName} | ||
</p> | ||
<ul> | ||
{this.assetModel?.assetModelProperties?.map((property) => ( | ||
<li> | ||
{property.name}: {this.assetPropertyValues.get(property?.id as string)} | ||
</li> | ||
))} | ||
</ul> | ||
</div> | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './sitewise/types'; | ||
export * from './sitewise/siteWiseAssetModule'; | ||
export * from './sitewise/session'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
import { SiteWiseAssetCache } from './cache'; | ||
import { | ||
AssetPropertyValue, | ||
AssetState, | ||
AssetSummary, | ||
DescribeAssetModelResponse, | ||
DescribeAssetResponse, | ||
Quality, | ||
} from '@aws-sdk/client-iotsitewise'; | ||
|
||
const ASSET_ID = 'assetABC123'; | ||
const ASSET_MODEL_ID = 'assetModelABC123'; | ||
const ASSET_PROPERTY_ID = 'assetPropertyIdAbc123'; | ||
const creationDate: Date = new Date(2000, 0, 0); | ||
const lastUpdatedDate: Date = new Date(2021, 0, 0); | ||
const sampleAssetSummary: AssetSummary = { | ||
id: ASSET_ID, | ||
assetModelId: ASSET_MODEL_ID, | ||
name: 'assetName', | ||
arn: 'arn:assetArn', | ||
creationDate: creationDate, | ||
lastUpdateDate: lastUpdatedDate, | ||
hierarchies: [], | ||
status: { | ||
error: { | ||
code: undefined, | ||
details: undefined, | ||
message: undefined, | ||
}, | ||
state: AssetState.ACTIVE, | ||
}, | ||
}; | ||
const sampleAssetDescription: DescribeAssetResponse = { | ||
assetId: ASSET_ID, | ||
assetModelId: ASSET_MODEL_ID, | ||
assetName: 'assetName', | ||
assetArn: 'arn:assetArn', | ||
assetCreationDate: creationDate, | ||
assetLastUpdateDate: lastUpdatedDate, | ||
assetHierarchies: [], | ||
assetStatus: { | ||
error: { | ||
code: undefined, | ||
details: undefined, | ||
message: undefined, | ||
}, | ||
state: AssetState.ACTIVE, | ||
}, | ||
assetCompositeModels: [], | ||
assetProperties: [], | ||
}; | ||
const sampleAssetModel: DescribeAssetModelResponse = { | ||
assetModelId: ASSET_MODEL_ID, | ||
assetModelName: 'Asset Model Name', | ||
assetModelDescription: 'a happy little asset model', | ||
assetModelArn: 'arn:assetModelArn', | ||
assetModelCreationDate: creationDate, | ||
assetModelLastUpdateDate: lastUpdatedDate, | ||
assetModelProperties: [], | ||
assetModelCompositeModels: [], | ||
assetModelHierarchies: [], | ||
assetModelStatus: { | ||
error: { | ||
code: undefined, | ||
details: undefined, | ||
message: undefined, | ||
}, | ||
state: AssetState.ACTIVE, | ||
}, | ||
}; | ||
const samplePropertyValue: AssetPropertyValue = { | ||
value: { stringValue: undefined, booleanValue: undefined, doubleValue: undefined, integerValue: 1234 }, | ||
quality: Quality.GOOD, | ||
timestamp: { | ||
timeInSeconds: 100, | ||
offsetInNanos: 100, | ||
}, | ||
}; | ||
|
||
describe('cacheAssetSummary', () => { | ||
const cache: SiteWiseAssetCache = new SiteWiseAssetCache(); | ||
it('returns empty when the asset summary is not in the cache', () => { | ||
expect(cache.getAssetSummary(ASSET_ID)).toBeUndefined(); | ||
}); | ||
|
||
it('returns the cached asset summary when one is stored', () => { | ||
cache.storeAssetSummary(sampleAssetSummary); | ||
expect(cache.getAssetSummary(ASSET_ID)).toEqual(sampleAssetSummary); | ||
}); | ||
}); | ||
|
||
describe('cacheDescribeAsset', () => { | ||
const cache: SiteWiseAssetCache = new SiteWiseAssetCache(); | ||
it('returns empty when the asset summary is not in the cache', () => { | ||
expect(cache.getAssetSummary(ASSET_ID)).toBeUndefined(); | ||
}); | ||
|
||
it('returns the cached asset summary when an Asset Description is stored', () => { | ||
cache.storeAssetSummary(sampleAssetDescription); | ||
expect(cache.getAssetSummary(ASSET_ID)).toEqual(sampleAssetSummary); | ||
}); | ||
}); | ||
|
||
describe('cacheAssetModel', () => { | ||
const cache: SiteWiseAssetCache = new SiteWiseAssetCache(); | ||
it('returns empty when the asset model is not in the cache', () => { | ||
expect(cache.getAssetModel(ASSET_MODEL_ID)).toBeUndefined(); | ||
}); | ||
|
||
it('returns the cached asset model when an Asset Model is stored', () => { | ||
cache.storeAssetModel(sampleAssetModel); | ||
expect(cache.getAssetModel(ASSET_MODEL_ID)).toEqual(sampleAssetModel); | ||
}); | ||
}); | ||
|
||
describe('cacheAssetPropertyValue', () => { | ||
const cache: SiteWiseAssetCache = new SiteWiseAssetCache(); | ||
it('returns empty when the asset property value is not in the cache', () => { | ||
expect(cache.getPropertyValue(ASSET_ID, ASSET_PROPERTY_ID)).toBeUndefined(); | ||
}); | ||
|
||
it('returns the cached asset property value when an AssetPropertyValue is stored', () => { | ||
cache.storePropertyValue(ASSET_ID, ASSET_PROPERTY_ID, samplePropertyValue); | ||
expect(cache.getPropertyValue(ASSET_ID, ASSET_PROPERTY_ID)).toEqual(samplePropertyValue); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { | ||
AssetPropertyValue, | ||
AssetSummary, | ||
DescribeAssetResponse, | ||
DescribeAssetModelResponse, | ||
} from '@aws-sdk/client-iotsitewise'; | ||
|
||
export class SiteWiseAssetCache { | ||
private assetCache: Record<string, AssetSummary> = {}; | ||
private assetModelCache: Record<string, DescribeAssetModelResponse> = {}; | ||
private propertyValueCache: Record<string, AssetPropertyValue> = {}; | ||
|
||
private convertToAssetSummary(assetDescription: DescribeAssetResponse): AssetSummary { | ||
return { | ||
id: assetDescription.assetId, | ||
arn: assetDescription.assetArn, | ||
name: assetDescription.assetName, | ||
assetModelId: assetDescription.assetModelId, | ||
creationDate: assetDescription.assetCreationDate, | ||
lastUpdateDate: assetDescription.assetLastUpdateDate, | ||
status: assetDescription.assetStatus, | ||
hierarchies: assetDescription.assetHierarchies, | ||
}; | ||
} | ||
|
||
private readonly isDescribeAssetResponse = ( | ||
assetAny: AssetSummary | DescribeAssetResponse | ||
): assetAny is DescribeAssetResponse => (assetAny as DescribeAssetResponse).assetId != undefined; | ||
|
||
private assetPropertyValueKey(assetId: string, propertyId: string): string { | ||
return assetId + ':' + propertyId; | ||
} | ||
|
||
public getAssetSummary(assetId: string): AssetSummary | undefined { | ||
return this.assetCache[assetId]; | ||
} | ||
|
||
public storeAssetSummary(assetAny: AssetSummary | DescribeAssetResponse): void { | ||
let assetSummary: AssetSummary = this.isDescribeAssetResponse(assetAny) | ||
? this.convertToAssetSummary(assetAny) | ||
: assetAny; | ||
if (assetSummary.id != undefined) { | ||
this.assetCache[assetSummary.id] = assetSummary; | ||
} | ||
} | ||
|
||
public getAssetModel(assetModelId: string): DescribeAssetModelResponse | undefined { | ||
return this.assetModelCache[assetModelId]; | ||
} | ||
|
||
public storeAssetModel(assetModel: DescribeAssetModelResponse) { | ||
if (assetModel.assetModelId != undefined) { | ||
this.assetModelCache[assetModel.assetModelId] = assetModel; | ||
} | ||
} | ||
|
||
public getPropertyValue(assetId: string, propertyId: string): AssetPropertyValue | undefined { | ||
return this.propertyValueCache[this.assetPropertyValueKey(assetId, propertyId)]; | ||
} | ||
|
||
public storePropertyValue(assetId: string, propertyId: string, assetPropertyValue: AssetPropertyValue) { | ||
this.propertyValueCache[this.assetPropertyValueKey(assetId, propertyId)] = assetPropertyValue; | ||
} | ||
} |
Oops, something went wrong.