@operato/twin-kernel 0.7.7 → 0.7.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/capability.d.ts +30 -1
- package/dist/capability.js +37 -5
- package/dist/ems-profile.js +2 -2
- package/dist-cjs/index.cjs +35 -9
- package/package.json +1 -1
package/dist/capability.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type CapabilityKey = 'operable' | 'storable' | 'mobile' | 'processable' | 'trackable' | 'switching' | 'metered' | 'curtailable' | '
|
|
1
|
+
export type CapabilityKey = 'operable' | 'storable' | 'mobile' | 'processable' | 'trackable' | 'switching' | 'metered' | 'curtailable' | 'energyGenerating' | 'energyStoring';
|
|
2
2
|
/** 이동 관측 — Mobile 이 노출. */
|
|
3
3
|
export interface Motion {
|
|
4
4
|
fromNode: string;
|
|
@@ -74,6 +74,28 @@ export interface CapabilitySpec {
|
|
|
74
74
|
semantics: string;
|
|
75
75
|
/** 관측 상태 필드(데이터 형식). 직교 — 어느 필드도 두 능력에 중복 없음(원칙 ②). */
|
|
76
76
|
stateFields: string[];
|
|
77
|
+
/**
|
|
78
|
+
* 이 능력을 가진 자원이 **받는 명령** — 나가는 사실(`results`)의 짝.
|
|
79
|
+
*
|
|
80
|
+
* ── 계약이 반쪽이었다 (2026-08-15) ────────────────────────────────────────
|
|
81
|
+
* 능력은 「무슨 값을 내보내는가」만 선언하고 있었다. 그런데 저작면이 알아야 할 것이 하나 더 있다:
|
|
82
|
+
* 「여기에 제어를 붙여도 되는가」. 적을 자리가 없어서 **능력 이름으로 눈치껏** 판단했다 —
|
|
83
|
+
* `operable` 이면 제어를 권하고 아니면 안 권했다.
|
|
84
|
+
*
|
|
85
|
+
* 차단기에서 그 방식이 막혔다. 상태는 보여주고 싶은데 `operable` 을 주면 화면이 우리가 하지 않기로
|
|
86
|
+
* 한 조작을 권한다. 그래서 능력을 새로 만들었고(`switching`), 능력은 상태 필드로 정의되므로 새
|
|
87
|
+
* 필드가 필요했는데 마침 표준이 `position` 이라는 이름을 줘서 됐다 — **그건 운이었다.**
|
|
88
|
+
*
|
|
89
|
+
* 없던 것은 참/거짓 하나가 아니라 **대칭**이다: 나가는 것은 선언돼 있고 들어오는 것은 없었다.
|
|
90
|
+
* 명령 어휘(`CMD`)는 이미 능력별로 묶여 있었지만 그 묶임이 **주석에만** 있었다 — 여기로 옮긴다.
|
|
91
|
+
*
|
|
92
|
+
* 비어 있다는 것이 곧 「조작하지 않는다」이다. 「명령을 받나」는 이 목록에서 **파생**된다 —
|
|
93
|
+
* 그래서 형용사를 새로 만들지 않는다.
|
|
94
|
+
*
|
|
95
|
+
* 트윈 수준 명령(`attention.ack`·`resource.add`)은 특정 자원의 능력이 아니므로 여기 넣지 않는다.
|
|
96
|
+
* 모든 명령이 능력에 속해야 한다는 규칙을 만들면 그것이 다음 땜빵이 된다.
|
|
97
|
+
*/
|
|
98
|
+
commands: string[];
|
|
77
99
|
/** 교환 데이터 모델 이름. */
|
|
78
100
|
models?: string[];
|
|
79
101
|
/** 불변식(모두 준수·신뢰). */
|
|
@@ -85,3 +107,10 @@ export declare const CAPABILITIES: Record<CapabilityKey, CapabilitySpec>;
|
|
|
85
107
|
export declare const CAPABILITY_KEYS: CapabilityKey[];
|
|
86
108
|
/** 능력 집합이 관측 노출하는 상태 필드 합집합(직교이므로 단순 병합). */
|
|
87
109
|
export declare function stateFieldsOf(caps: CapabilityKey[]): string[];
|
|
110
|
+
/**
|
|
111
|
+
* 능력 집합이 **받는 명령**의 합집합 — `stateFieldsOf` 의 짝.
|
|
112
|
+
*
|
|
113
|
+
* 「이 자원에 제어를 붙여도 되는가」는 이 목록이 비었는지로 **파생**한다. 그래서 `controllable` 같은
|
|
114
|
+
* 형용사를 따로 두지 않는다 — 형용사를 두면 목록과 형용사가 언젠가 어긋나고, 어긋난 쪽이 화면이 된다.
|
|
115
|
+
*/
|
|
116
|
+
export declare function commandsOf(caps: CapabilityKey[]): string[];
|
package/dist/capability.js
CHANGED
|
@@ -19,18 +19,22 @@
|
|
|
19
19
|
export const CAPABILITIES = {
|
|
20
20
|
operable: {
|
|
21
21
|
key: 'operable', label: 'twin.capability.operable', semantics: '능동 자원의 운영 상태(유휴/가동/고장). status 교차 관심사를 여기 하나로.',
|
|
22
|
+
commands: ['resource.hold', 'resource.resume', 'resource.down', 'resource.repair', 'resource.reset-metrics'],
|
|
22
23
|
stateFields: ['status'], results: ['statusChanged']
|
|
23
24
|
},
|
|
24
25
|
storable: {
|
|
25
26
|
key: 'storable', label: 'twin.capability.storable', semantics: '아이템을 보유하는 위치 — 점유/용량. (씬 기제: Capacity)',
|
|
27
|
+
commands: [],
|
|
26
28
|
stateFields: ['occupancy', 'capacity'], invariants: ['0 <= occupancy <= capacity (capacity>0)'], results: ['occupancyChanged']
|
|
27
29
|
},
|
|
28
30
|
mobile: {
|
|
29
31
|
key: 'mobile', label: 'twin.capability.mobile', semantics: '자원 자신이 자리 간 이동. Transferable(아이템 이동)과 다름. (씬 기제: CarrierLine)',
|
|
32
|
+
commands: [],
|
|
30
33
|
stateFields: ['location', 'motion'], models: ['Motion'], results: ['moved', 'motionTick']
|
|
31
34
|
},
|
|
32
35
|
processable: {
|
|
33
36
|
key: 'processable', label: 'twin.capability.processable', semantics: '변환/가공 수행 — 산출(양품/불량). 운영 status 는 Operable 조합. progress 방출은 후속.',
|
|
37
|
+
commands: [],
|
|
34
38
|
stateFields: ['output'], results: ['completed']
|
|
35
39
|
},
|
|
36
40
|
/*
|
|
@@ -47,10 +51,12 @@ export const CAPABILITIES = {
|
|
|
47
51
|
*/
|
|
48
52
|
switching: {
|
|
49
53
|
key: 'switching', label: 'twin.capability.switching', semantics: '회로를 열고 닫는 기기의 **위치를 읽는다** — 우리는 조작하지 않는다(명령 없음). IEC 61850 XCBR/XSWI Pos.',
|
|
54
|
+
commands: [],
|
|
50
55
|
stateFields: ['position'], models: ['SwitchingState'], results: ['positionChanged']
|
|
51
56
|
},
|
|
52
57
|
trackable: {
|
|
53
58
|
key: 'trackable', label: 'twin.capability.trackable', semantics: '오더/아이템 생애 추적 — 생애단계(도메인 라벨, 무방언)·진행·보류.',
|
|
59
|
+
commands: ['order.hold', 'order.resume', 'order.release'],
|
|
54
60
|
stateFields: ['lifecycle', 'progress', 'held'], results: ['lifecycleChanged']
|
|
55
61
|
},
|
|
56
62
|
/*
|
|
@@ -61,22 +67,35 @@ export const CAPABILITIES = {
|
|
|
61
67
|
*/
|
|
62
68
|
metered: {
|
|
63
69
|
key: 'metered', label: 'twin.capability.metered', semantics: '자기 소비를 잰다 — 유효전력·누적량·역률. 값이 없으면 모르는 것이다(0 이 아니다).',
|
|
70
|
+
commands: [],
|
|
64
71
|
stateFields: ['kW', 'kWh', 'powerFactor'], models: ['MeteredState'], results: ['measured']
|
|
65
72
|
},
|
|
66
73
|
curtailable: {
|
|
67
74
|
key: 'curtailable', label: 'twin.capability.curtailable', semantics: '줄일 수 있다 — 최소 유지 아래로는 내리지 않는다. 판정만 하고 집행은 사람과 그 시스템의 몫이다.',
|
|
75
|
+
commands: [],
|
|
68
76
|
stateFields: ['curtailable', 'minKW'], models: ['CurtailableState'], invariants: ['minKW >= 0'], results: ['drSuggested']
|
|
69
77
|
},
|
|
70
|
-
|
|
71
|
-
key: '
|
|
78
|
+
energyGenerating: {
|
|
79
|
+
key: 'energyGenerating', label: 'twin.capability.energyGenerating', semantics: '전기를 만든다 — 역송은 소비의 음수가 아니라 별개 사실이다.',
|
|
80
|
+
commands: [],
|
|
72
81
|
stateFields: ['generatedKW', 'exportKW'], models: ['GeneratingState'], results: ['generated']
|
|
73
82
|
},
|
|
74
|
-
|
|
75
|
-
|
|
83
|
+
/*
|
|
84
|
+
* ── 왜 `storing` 이 아니라 `energyStoring` 인가 (2026-08-15) ────────────────
|
|
85
|
+
* 같은 카탈로그에 `storable`(물건을 담는 자리)이 있다. 전기를 담는 것과 물건을 담는 것이 한 글자
|
|
86
|
+
* 차이로 붙어 있어서, 컴포넌트를 만들 때 `twin-storage` 를 피해 `twin-storage-energy` 로 도망쳤다 —
|
|
87
|
+
* 한 이름을 두 번 피해 갔다면 그 이름이 틀린 것이다.
|
|
88
|
+
*
|
|
89
|
+
* 도메인(EMS)이 아니라 **양(에너지)** 을 이름에 넣는다. 그래서 MES 트윈 안의 디젤 발전기도 그대로
|
|
90
|
+
* `energyGenerating` 이다 — 능력은 도메인이 아니라 관측의 면이다(방언 없음).
|
|
91
|
+
*/
|
|
92
|
+
energyStoring: {
|
|
93
|
+
key: 'energyStoring', label: 'twin.capability.energyStoring', semantics: '담고 낸다 — 충전과 방전을 나눈다(손실·수명 판단이 둘을 구별해야 한다).',
|
|
94
|
+
commands: [],
|
|
76
95
|
stateFields: ['soc', 'chargeKW', 'dischargeKW'], models: ['StoringState'], invariants: ['0 <= soc <= 100'], results: ['stored', 'discharged']
|
|
77
96
|
}
|
|
78
97
|
};
|
|
79
|
-
export const CAPABILITY_KEYS = ['operable', 'storable', 'mobile', 'processable', 'trackable', 'switching', 'metered', 'curtailable', '
|
|
98
|
+
export const CAPABILITY_KEYS = ['operable', 'storable', 'mobile', 'processable', 'trackable', 'switching', 'metered', 'curtailable', 'energyGenerating', 'energyStoring'];
|
|
80
99
|
/** 능력 집합이 관측 노출하는 상태 필드 합집합(직교이므로 단순 병합). */
|
|
81
100
|
export function stateFieldsOf(caps) {
|
|
82
101
|
const out = new Set();
|
|
@@ -85,3 +104,16 @@ export function stateFieldsOf(caps) {
|
|
|
85
104
|
out.add(f);
|
|
86
105
|
return [...out];
|
|
87
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* 능력 집합이 **받는 명령**의 합집합 — `stateFieldsOf` 의 짝.
|
|
109
|
+
*
|
|
110
|
+
* 「이 자원에 제어를 붙여도 되는가」는 이 목록이 비었는지로 **파생**한다. 그래서 `controllable` 같은
|
|
111
|
+
* 형용사를 따로 두지 않는다 — 형용사를 두면 목록과 형용사가 언젠가 어긋나고, 어긋난 쪽이 화면이 된다.
|
|
112
|
+
*/
|
|
113
|
+
export function commandsOf(caps) {
|
|
114
|
+
const out = new Set();
|
|
115
|
+
for (const c of caps)
|
|
116
|
+
for (const cmd of CAPABILITIES[c]?.commands ?? [])
|
|
117
|
+
out.add(cmd);
|
|
118
|
+
return [...out];
|
|
119
|
+
}
|
package/dist/ems-profile.js
CHANGED
|
@@ -96,7 +96,7 @@ export const EMS_TYPES = [
|
|
|
96
96
|
/* 태양광 어레이 — IEC 61850-7-420(분산자원)의 `DPVA`. 발전과 계량은 다른 능력이다. */
|
|
97
97
|
standardClass: { iec61850: 'DPVA', iso55000: 'Asset', iso50001: 'RenewableSupply' },
|
|
98
98
|
identity: { scheme: 'kernel:id' },
|
|
99
|
-
capabilities: ['
|
|
99
|
+
capabilities: ['energyGenerating', 'metered', 'operable']
|
|
100
100
|
},
|
|
101
101
|
{
|
|
102
102
|
key: 'battery',
|
|
@@ -105,7 +105,7 @@ export const EMS_TYPES = [
|
|
|
105
105
|
/* 축전지(ESS) — `ZBAT`. 충전·방전을 나눠 재고, 저장은 보관(`storable`)이 아니다(물건이 아니다). */
|
|
106
106
|
standardClass: { iec61850: 'ZBAT', iso55000: 'Asset' },
|
|
107
107
|
identity: { scheme: 'kernel:id' },
|
|
108
|
-
capabilities: ['
|
|
108
|
+
capabilities: ['energyStoring', 'metered', 'operable']
|
|
109
109
|
},
|
|
110
110
|
{
|
|
111
111
|
key: 'utility',
|
package/dist-cjs/index.cjs
CHANGED
|
@@ -85,6 +85,7 @@ __export(index_exports, {
|
|
|
85
85
|
capabilitiesForType: () => capabilitiesForType,
|
|
86
86
|
capabilityOf: () => capabilityOf,
|
|
87
87
|
classClosure: () => classClosure,
|
|
88
|
+
commandsOf: () => commandsOf,
|
|
88
89
|
compareStates: () => compareStates,
|
|
89
90
|
computeOee: () => computeOee,
|
|
90
91
|
constantDuration: () => constantDuration,
|
|
@@ -1700,7 +1701,7 @@ var EMS_TYPES = [
|
|
|
1700
1701
|
/* 태양광 어레이 — IEC 61850-7-420(분산자원)의 `DPVA`. 발전과 계량은 다른 능력이다. */
|
|
1701
1702
|
standardClass: { iec61850: "DPVA", iso55000: "Asset", iso50001: "RenewableSupply" },
|
|
1702
1703
|
identity: { scheme: "kernel:id" },
|
|
1703
|
-
capabilities: ["
|
|
1704
|
+
capabilities: ["energyGenerating", "metered", "operable"]
|
|
1704
1705
|
},
|
|
1705
1706
|
{
|
|
1706
1707
|
key: "battery",
|
|
@@ -1709,7 +1710,7 @@ var EMS_TYPES = [
|
|
|
1709
1710
|
/* 축전지(ESS) — `ZBAT`. 충전·방전을 나눠 재고, 저장은 보관(`storable`)이 아니다(물건이 아니다). */
|
|
1710
1711
|
standardClass: { iec61850: "ZBAT", iso55000: "Asset" },
|
|
1711
1712
|
identity: { scheme: "kernel:id" },
|
|
1712
|
-
capabilities: ["
|
|
1713
|
+
capabilities: ["energyStoring", "metered", "operable"]
|
|
1713
1714
|
},
|
|
1714
1715
|
{
|
|
1715
1716
|
key: "utility",
|
|
@@ -1756,6 +1757,7 @@ var CAPABILITIES = {
|
|
|
1756
1757
|
key: "operable",
|
|
1757
1758
|
label: "twin.capability.operable",
|
|
1758
1759
|
semantics: "\uB2A5\uB3D9 \uC790\uC6D0\uC758 \uC6B4\uC601 \uC0C1\uD0DC(\uC720\uD734/\uAC00\uB3D9/\uACE0\uC7A5). status \uAD50\uCC28 \uAD00\uC2EC\uC0AC\uB97C \uC5EC\uAE30 \uD558\uB098\uB85C.",
|
|
1760
|
+
commands: ["resource.hold", "resource.resume", "resource.down", "resource.repair", "resource.reset-metrics"],
|
|
1759
1761
|
stateFields: ["status"],
|
|
1760
1762
|
results: ["statusChanged"]
|
|
1761
1763
|
},
|
|
@@ -1763,6 +1765,7 @@ var CAPABILITIES = {
|
|
|
1763
1765
|
key: "storable",
|
|
1764
1766
|
label: "twin.capability.storable",
|
|
1765
1767
|
semantics: "\uC544\uC774\uD15C\uC744 \uBCF4\uC720\uD558\uB294 \uC704\uCE58 \u2014 \uC810\uC720/\uC6A9\uB7C9. (\uC52C \uAE30\uC81C: Capacity)",
|
|
1768
|
+
commands: [],
|
|
1766
1769
|
stateFields: ["occupancy", "capacity"],
|
|
1767
1770
|
invariants: ["0 <= occupancy <= capacity (capacity>0)"],
|
|
1768
1771
|
results: ["occupancyChanged"]
|
|
@@ -1771,6 +1774,7 @@ var CAPABILITIES = {
|
|
|
1771
1774
|
key: "mobile",
|
|
1772
1775
|
label: "twin.capability.mobile",
|
|
1773
1776
|
semantics: "\uC790\uC6D0 \uC790\uC2E0\uC774 \uC790\uB9AC \uAC04 \uC774\uB3D9. Transferable(\uC544\uC774\uD15C \uC774\uB3D9)\uACFC \uB2E4\uB984. (\uC52C \uAE30\uC81C: CarrierLine)",
|
|
1777
|
+
commands: [],
|
|
1774
1778
|
stateFields: ["location", "motion"],
|
|
1775
1779
|
models: ["Motion"],
|
|
1776
1780
|
results: ["moved", "motionTick"]
|
|
@@ -1779,6 +1783,7 @@ var CAPABILITIES = {
|
|
|
1779
1783
|
key: "processable",
|
|
1780
1784
|
label: "twin.capability.processable",
|
|
1781
1785
|
semantics: "\uBCC0\uD658/\uAC00\uACF5 \uC218\uD589 \u2014 \uC0B0\uCD9C(\uC591\uD488/\uBD88\uB7C9). \uC6B4\uC601 status \uB294 Operable \uC870\uD569. progress \uBC29\uCD9C\uC740 \uD6C4\uC18D.",
|
|
1786
|
+
commands: [],
|
|
1782
1787
|
stateFields: ["output"],
|
|
1783
1788
|
results: ["completed"]
|
|
1784
1789
|
},
|
|
@@ -1798,6 +1803,7 @@ var CAPABILITIES = {
|
|
|
1798
1803
|
key: "switching",
|
|
1799
1804
|
label: "twin.capability.switching",
|
|
1800
1805
|
semantics: "\uD68C\uB85C\uB97C \uC5F4\uACE0 \uB2EB\uB294 \uAE30\uAE30\uC758 **\uC704\uCE58\uB97C \uC77D\uB294\uB2E4** \u2014 \uC6B0\uB9AC\uB294 \uC870\uC791\uD558\uC9C0 \uC54A\uB294\uB2E4(\uBA85\uB839 \uC5C6\uC74C). IEC 61850 XCBR/XSWI Pos.",
|
|
1806
|
+
commands: [],
|
|
1801
1807
|
stateFields: ["position"],
|
|
1802
1808
|
models: ["SwitchingState"],
|
|
1803
1809
|
results: ["positionChanged"]
|
|
@@ -1806,6 +1812,7 @@ var CAPABILITIES = {
|
|
|
1806
1812
|
key: "trackable",
|
|
1807
1813
|
label: "twin.capability.trackable",
|
|
1808
1814
|
semantics: "\uC624\uB354/\uC544\uC774\uD15C \uC0DD\uC560 \uCD94\uC801 \u2014 \uC0DD\uC560\uB2E8\uACC4(\uB3C4\uBA54\uC778 \uB77C\uBCA8, \uBB34\uBC29\uC5B8)\xB7\uC9C4\uD589\xB7\uBCF4\uB958.",
|
|
1815
|
+
commands: ["order.hold", "order.resume", "order.release"],
|
|
1809
1816
|
stateFields: ["lifecycle", "progress", "held"],
|
|
1810
1817
|
results: ["lifecycleChanged"]
|
|
1811
1818
|
},
|
|
@@ -1819,6 +1826,7 @@ var CAPABILITIES = {
|
|
|
1819
1826
|
key: "metered",
|
|
1820
1827
|
label: "twin.capability.metered",
|
|
1821
1828
|
semantics: "\uC790\uAE30 \uC18C\uBE44\uB97C \uC7B0\uB2E4 \u2014 \uC720\uD6A8\uC804\uB825\xB7\uB204\uC801\uB7C9\xB7\uC5ED\uB960. \uAC12\uC774 \uC5C6\uC73C\uBA74 \uBAA8\uB974\uB294 \uAC83\uC774\uB2E4(0 \uC774 \uC544\uB2C8\uB2E4).",
|
|
1829
|
+
commands: [],
|
|
1822
1830
|
stateFields: ["kW", "kWh", "powerFactor"],
|
|
1823
1831
|
models: ["MeteredState"],
|
|
1824
1832
|
results: ["measured"]
|
|
@@ -1827,35 +1835,52 @@ var CAPABILITIES = {
|
|
|
1827
1835
|
key: "curtailable",
|
|
1828
1836
|
label: "twin.capability.curtailable",
|
|
1829
1837
|
semantics: "\uC904\uC77C \uC218 \uC788\uB2E4 \u2014 \uCD5C\uC18C \uC720\uC9C0 \uC544\uB798\uB85C\uB294 \uB0B4\uB9AC\uC9C0 \uC54A\uB294\uB2E4. \uD310\uC815\uB9CC \uD558\uACE0 \uC9D1\uD589\uC740 \uC0AC\uB78C\uACFC \uADF8 \uC2DC\uC2A4\uD15C\uC758 \uBAAB\uC774\uB2E4.",
|
|
1838
|
+
commands: [],
|
|
1830
1839
|
stateFields: ["curtailable", "minKW"],
|
|
1831
1840
|
models: ["CurtailableState"],
|
|
1832
1841
|
invariants: ["minKW >= 0"],
|
|
1833
1842
|
results: ["drSuggested"]
|
|
1834
1843
|
},
|
|
1835
|
-
|
|
1836
|
-
key: "
|
|
1837
|
-
label: "twin.capability.
|
|
1844
|
+
energyGenerating: {
|
|
1845
|
+
key: "energyGenerating",
|
|
1846
|
+
label: "twin.capability.energyGenerating",
|
|
1838
1847
|
semantics: "\uC804\uAE30\uB97C \uB9CC\uB4E0\uB2E4 \u2014 \uC5ED\uC1A1\uC740 \uC18C\uBE44\uC758 \uC74C\uC218\uAC00 \uC544\uB2C8\uB77C \uBCC4\uAC1C \uC0AC\uC2E4\uC774\uB2E4.",
|
|
1848
|
+
commands: [],
|
|
1839
1849
|
stateFields: ["generatedKW", "exportKW"],
|
|
1840
1850
|
models: ["GeneratingState"],
|
|
1841
1851
|
results: ["generated"]
|
|
1842
1852
|
},
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1853
|
+
/*
|
|
1854
|
+
* ── 왜 `storing` 이 아니라 `energyStoring` 인가 (2026-08-15) ────────────────
|
|
1855
|
+
* 같은 카탈로그에 `storable`(물건을 담는 자리)이 있다. 전기를 담는 것과 물건을 담는 것이 한 글자
|
|
1856
|
+
* 차이로 붙어 있어서, 컴포넌트를 만들 때 `twin-storage` 를 피해 `twin-storage-energy` 로 도망쳤다 —
|
|
1857
|
+
* 한 이름을 두 번 피해 갔다면 그 이름이 틀린 것이다.
|
|
1858
|
+
*
|
|
1859
|
+
* 도메인(EMS)이 아니라 **양(에너지)** 을 이름에 넣는다. 그래서 MES 트윈 안의 디젤 발전기도 그대로
|
|
1860
|
+
* `energyGenerating` 이다 — 능력은 도메인이 아니라 관측의 면이다(방언 없음).
|
|
1861
|
+
*/
|
|
1862
|
+
energyStoring: {
|
|
1863
|
+
key: "energyStoring",
|
|
1864
|
+
label: "twin.capability.energyStoring",
|
|
1846
1865
|
semantics: "\uB2F4\uACE0 \uB0B8\uB2E4 \u2014 \uCDA9\uC804\uACFC \uBC29\uC804\uC744 \uB098\uB208\uB2E4(\uC190\uC2E4\xB7\uC218\uBA85 \uD310\uB2E8\uC774 \uB458\uC744 \uAD6C\uBCC4\uD574\uC57C \uD55C\uB2E4).",
|
|
1866
|
+
commands: [],
|
|
1847
1867
|
stateFields: ["soc", "chargeKW", "dischargeKW"],
|
|
1848
1868
|
models: ["StoringState"],
|
|
1849
1869
|
invariants: ["0 <= soc <= 100"],
|
|
1850
1870
|
results: ["stored", "discharged"]
|
|
1851
1871
|
}
|
|
1852
1872
|
};
|
|
1853
|
-
var CAPABILITY_KEYS = ["operable", "storable", "mobile", "processable", "trackable", "switching", "metered", "curtailable", "
|
|
1873
|
+
var CAPABILITY_KEYS = ["operable", "storable", "mobile", "processable", "trackable", "switching", "metered", "curtailable", "energyGenerating", "energyStoring"];
|
|
1854
1874
|
function stateFieldsOf(caps) {
|
|
1855
1875
|
const out = /* @__PURE__ */ new Set();
|
|
1856
1876
|
for (const c of caps) for (const f of CAPABILITIES[c]?.stateFields ?? []) out.add(f);
|
|
1857
1877
|
return [...out];
|
|
1858
1878
|
}
|
|
1879
|
+
function commandsOf(caps) {
|
|
1880
|
+
const out = /* @__PURE__ */ new Set();
|
|
1881
|
+
for (const c of caps) for (const cmd of CAPABILITIES[c]?.commands ?? []) out.add(cmd);
|
|
1882
|
+
return [...out];
|
|
1883
|
+
}
|
|
1859
1884
|
|
|
1860
1885
|
// src/yms-profile.ts
|
|
1861
1886
|
var YARD_BIZSTEP = {
|
|
@@ -6446,6 +6471,7 @@ function retiredVocabularyIn(line) {
|
|
|
6446
6471
|
capabilitiesForType,
|
|
6447
6472
|
capabilityOf,
|
|
6448
6473
|
classClosure,
|
|
6474
|
+
commandsOf,
|
|
6449
6475
|
compareStates,
|
|
6450
6476
|
computeOee,
|
|
6451
6477
|
constantDuration,
|
package/package.json
CHANGED