@operato/twin-kernel 0.6.8 → 0.6.10

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.
@@ -854,8 +854,6 @@ export interface EquipmentState extends EffectivePeriod {
854
854
  * 여기 실린다. 지금까지 계약 밖으로 흘러 호스트까지 `any` 로 전달됐다(§ResourceProperty).
855
855
  */
856
856
  properties?: ResourceProperty[];
857
- /** 근무 캘린더 — 표준 `WorkCalendarEntry`(복수). 가동시간·정비창을 함께 표현한다. */
858
- workCalendar?: WorkCalendarEntry[];
859
857
  /** 적격을 검증한 시험 명세들 — 표준 `Equipment.TestSpecificationID`(§TestSpecificationRefs). */
860
858
  testSpecificationIds?: TestSpecificationRefs;
861
859
  /**
@@ -928,11 +926,6 @@ export interface PersonState extends EffectivePeriod {
928
926
  location?: string;
929
927
  /** 자원 속성 — 표준 `PersonProperty`. 자격증·숙련 등급 같은 사실이 여기 들어간다(§ResourceProperty). */
930
928
  properties?: ResourceProperty[];
931
- /**
932
- * 근무 캘린더 — 표준 `WorkCalendarEntry`(복수). 교대 여러 개와 휴게·휴일을 함께 표현한다.
933
- * 예전에는 하루에 창 하나뿐이어서 2교대·야간+주간 조합을 표현할 수 없었다.
934
- */
935
- workCalendar?: WorkCalendarEntry[];
936
929
  /** 자격을 검증한 시험 명세들 — 표준 `Person.TestSpecificationID`(§TestSpecificationRefs). */
937
930
  testSpecificationIds?: TestSpecificationRefs;
938
931
  /**
@@ -186,7 +186,16 @@ nowIso) {
186
186
  * 이벤트 누적기(근사)로 별도 공급해야 한다. 공식만 공유되고 입력원은 live 데이터-생산 결정.
187
187
  */
188
188
  export function computeOee(c, nowMs) {
189
- const planned = Math.max(0, nowMs - (c.metricsSinceMs ?? 0) - (c.holdMs ?? 0));
189
+ /*
190
+ * **계측 창을 모르면 잰 시간이 없다** — `?? 0` 으로 메우면 "1970년부터 재고 있었다" 가 된다.
191
+ *
192
+ * 그 결과가 화면까지 갔다: 갓 뜬 트윈의 절단기가 `idleMs 1767226603000`(약 56,000년) 유휴로 섰다.
193
+ * 시각을 소요시간 자리에 앉힌 것이고, 같은 값이 availability·overall 의 분모라 **성과 숫자 전체가
194
+ * 조용히 거짓**이 된다(가동률 100%, 성능 0%).
195
+ *
196
+ * 모르면 0 이 아니라 **없음**이다: 잰 구간이 없으면 유휴도 없다(아직 아무것도 재지 않았다).
197
+ */
198
+ const planned = c.metricsSinceMs == null ? 0 : Math.max(0, nowMs - c.metricsSinceMs - (c.holdMs ?? 0));
190
199
  const uptime = Math.max(0, planned - c.setupMs - c.downMs); // 가용시간(셋업·고장 제외)
191
200
  const availability = planned > 0 ? uptime / planned : 1;
192
201
  const performance = uptime > 0 ? Math.min(1, c.runMs / uptime) : (c.runMs > 0 ? 1 : 0);
@@ -369,7 +378,9 @@ export class FlowEngine {
369
378
  };
370
379
  }
371
380
  buildEquipment(m) {
372
- const eq = { id: m.id, kind: m.kind, location: m.homeLocation, homeLocation: m.homeLocation, ...(m.properties ? { properties: m.properties } : {}), ...(m.testSpecificationIds ? { testSpecificationIds: m.testSpecificationIds } : {}), ...(m.testResults ? { testResults: m.testResults } : {}), status: 'idle', taskId: null, runMs: 0, setupMs: 0, downMs: 0, goodCount: 0, scrapCount: 0, window: m.window, ...(m.workCalendar ? { workCalendar: m.workCalendar } : {}), ...effectiveOnly(m) };
381
+ /* **계측은 자원이 모델에 들어온 순간부터** 잰다(`metricsSinceMs`). 빠뜨리면 공식이 창을 모르고,
382
+ 예전에는 그것을 epoch 로 메워 갓 뜬 설비가 56,000년 유휴로 보였다(§computeOee). */
383
+ const eq = { id: m.id, kind: m.kind, location: m.homeLocation, homeLocation: m.homeLocation, ...(m.properties ? { properties: m.properties } : {}), ...(m.testSpecificationIds ? { testSpecificationIds: m.testSpecificationIds } : {}), ...(m.testResults ? { testResults: m.testResults } : {}), status: 'idle', taskId: null, runMs: 0, setupMs: 0, downMs: 0, goodCount: 0, scrapCount: 0, metricsSinceMs: this.clockMs, window: m.window, ...(m.workCalendar ? { workCalendar: m.workCalendar } : {}), ...effectiveOnly(m) };
373
384
  if (m.mtbfMs !== undefined) {
374
385
  eq.mtbfMs = m.mtbfMs;
375
386
  eq.mttrMs = m.mttrMs;
@@ -384,7 +395,7 @@ export class FlowEngine {
384
395
  addEquipment(m) {
385
396
  if (this.equipment.has(m.id))
386
397
  return;
387
- const eq = { id: m.id, kind: m.kind, location: m.homeLocation, homeLocation: m.homeLocation, ...(m.properties ? { properties: m.properties } : {}), ...(m.testSpecificationIds ? { testSpecificationIds: m.testSpecificationIds } : {}), ...(m.testResults ? { testResults: m.testResults } : {}), status: 'idle', taskId: null, runMs: 0, setupMs: 0, downMs: 0, goodCount: 0, scrapCount: 0 };
398
+ const eq = { id: m.id, kind: m.kind, location: m.homeLocation, homeLocation: m.homeLocation, ...(m.properties ? { properties: m.properties } : {}), ...(m.testSpecificationIds ? { testSpecificationIds: m.testSpecificationIds } : {}), ...(m.testResults ? { testResults: m.testResults } : {}), status: 'idle', taskId: null, runMs: 0, setupMs: 0, downMs: 0, goodCount: 0, scrapCount: 0, metricsSinceMs: this.clockMs };
388
399
  if (m.mtbfMs !== undefined) {
389
400
  eq.mtbfMs = m.mtbfMs;
390
401
  eq.mttrMs = m.mttrMs;
@@ -2370,7 +2370,7 @@ function deriveAttentions(view, acked, nowIso) {
2370
2370
  return out;
2371
2371
  }
2372
2372
  function computeOee(c, nowMs) {
2373
- const planned = Math.max(0, nowMs - (c.metricsSinceMs ?? 0) - (c.holdMs ?? 0));
2373
+ const planned = c.metricsSinceMs == null ? 0 : Math.max(0, nowMs - c.metricsSinceMs - (c.holdMs ?? 0));
2374
2374
  const uptime = Math.max(0, planned - c.setupMs - c.downMs);
2375
2375
  const availability = planned > 0 ? uptime / planned : 1;
2376
2376
  const performance = uptime > 0 ? Math.min(1, c.runMs / uptime) : c.runMs > 0 ? 1 : 0;
@@ -2555,7 +2555,7 @@ var FlowEngine = class {
2555
2555
  };
2556
2556
  }
2557
2557
  buildEquipment(m) {
2558
- const eq = { id: m.id, kind: m.kind, location: m.homeLocation, homeLocation: m.homeLocation, ...m.properties ? { properties: m.properties } : {}, ...m.testSpecificationIds ? { testSpecificationIds: m.testSpecificationIds } : {}, ...m.testResults ? { testResults: m.testResults } : {}, status: "idle", taskId: null, runMs: 0, setupMs: 0, downMs: 0, goodCount: 0, scrapCount: 0, window: m.window, ...m.workCalendar ? { workCalendar: m.workCalendar } : {}, ...effectiveOnly(m) };
2558
+ const eq = { id: m.id, kind: m.kind, location: m.homeLocation, homeLocation: m.homeLocation, ...m.properties ? { properties: m.properties } : {}, ...m.testSpecificationIds ? { testSpecificationIds: m.testSpecificationIds } : {}, ...m.testResults ? { testResults: m.testResults } : {}, status: "idle", taskId: null, runMs: 0, setupMs: 0, downMs: 0, goodCount: 0, scrapCount: 0, metricsSinceMs: this.clockMs, window: m.window, ...m.workCalendar ? { workCalendar: m.workCalendar } : {}, ...effectiveOnly(m) };
2559
2559
  if (m.mtbfMs !== void 0) {
2560
2560
  eq.mtbfMs = m.mtbfMs;
2561
2561
  eq.mttrMs = m.mttrMs;
@@ -2569,7 +2569,7 @@ var FlowEngine = class {
2569
2569
  */
2570
2570
  addEquipment(m) {
2571
2571
  if (this.equipment.has(m.id)) return;
2572
- const eq = { id: m.id, kind: m.kind, location: m.homeLocation, homeLocation: m.homeLocation, ...m.properties ? { properties: m.properties } : {}, ...m.testSpecificationIds ? { testSpecificationIds: m.testSpecificationIds } : {}, ...m.testResults ? { testResults: m.testResults } : {}, status: "idle", taskId: null, runMs: 0, setupMs: 0, downMs: 0, goodCount: 0, scrapCount: 0 };
2572
+ const eq = { id: m.id, kind: m.kind, location: m.homeLocation, homeLocation: m.homeLocation, ...m.properties ? { properties: m.properties } : {}, ...m.testSpecificationIds ? { testSpecificationIds: m.testSpecificationIds } : {}, ...m.testResults ? { testResults: m.testResults } : {}, status: "idle", taskId: null, runMs: 0, setupMs: 0, downMs: 0, goodCount: 0, scrapCount: 0, metricsSinceMs: this.clockMs };
2573
2573
  if (m.mtbfMs !== void 0) {
2574
2574
  eq.mtbfMs = m.mtbfMs;
2575
2575
  eq.mttrMs = m.mttrMs;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@operato/twin-kernel",
3
- "version": "0.6.8",
3
+ "version": "0.6.10",
4
4
  "type": "module",
5
5
  "description": "Twin Domain Kernel — framework-agnostic, zero-dep (domain + sim + 3-channel contract). WMS/YMS/MES, EPCIS 2.0 · ISA-95.",
6
6
  "publishConfig": {