1414 ********************************************************************************/
1515
1616/* eslint no-console: "off" */
17-
17+ import util from "util" ;
1818import { Servient } from "@node-wot/core" ;
1919import { OPCUAClientFactory } from "@node-wot/binding-opcua" ;
2020import { thingDescription } from "./opcua-coffee-machine-thing-description" ;
@@ -25,37 +25,192 @@ const pause = async (ms: number) => new Promise((resolve) => setTimeout(resolve,
2525 servient . addClientFactory ( new OPCUAClientFactory ( ) ) ;
2626
2727 const wot = await servient . start ( ) ;
28+
2829 const thing = await wot . consume ( thingDescription ) ;
2930
31+ let lastTemperature = NaN ;
32+ let lastWaterTankLevel = NaN ;
33+ let lastCoffeeBeanLevel = NaN ;
34+ let lastCurrentState = NaN ;
35+ let lastGrindingDuration = NaN ;
36+ let lastGrinderStatus = NaN ;
37+ let lastHeaterStatus = NaN ;
38+ let lastPumpStatus = NaN ;
39+ let lastValveStatus = NaN ;
40+
41+ const recordedActions : string [ ] = [ ] ;
42+ const recordAction = ( actionName : string ) => {
43+ recordedActions . push ( `${ new Date ( ) . toISOString ( ) } - ${ actionName } ` ) ;
44+ } ;
45+ process . stdout . write ( "\x1Bc" ) ; // clear console
46+ process . stdout . write ( "\x1B[?25l" ) ; // hide cursor
47+ const currentStateEnum = [ "Off" , "Standby" , "Error" , "Cleaning" , "Serving Coffee" , "Under Maintenance" ] ;
48+ const grinderStates = [ "Off" , "On" , "Jammed" , "Malfunctioning" ] ;
49+ const heaterStates = [ "Off" , "Heating" , "Ready" , "Malfunctioning" ] ;
50+ const pumpStates = [ "Off" , "On" , "Malfunctioning" ] ;
51+ const valveStates = [ "Open" , "Opening" , "Close" , "Closing" , "Malfunctioning" ] ;
52+
53+ const waitingMachineCoffeeStandByState = async ( ) => {
54+ await pause ( 1000 ) ;
55+ let state = lastCurrentState ;
56+ while ( state !== 1 ) {
57+ // Standby
58+ await pause ( 1000 ) ;
59+ state = lastCurrentState ;
60+ }
61+ } ;
62+ const writeLine = ( ...args : unknown [ ] ) => {
63+ process . stdout . write ( util . format ( ...args ) + " \n" ) ;
64+ } ;
65+ const displayOnlineStatus = ( ) => {
66+ process . stdout . write ( "\x1B[1;1H" ) ; // move cursor to top left
67+ writeLine ( `======== Coffee Machine Status ======== ${ new Date ( ) . toISOString ( ) } ` ) ;
68+ writeLine (
69+ ` 🔄 Current State : ${
70+ isNaN ( lastCurrentState ) ? "n/a" : ( currentStateEnum [ lastCurrentState ] ?? lastCurrentState )
71+ } `
72+ ) ;
73+ writeLine (
74+ ` 🔥 Heater Status : ${
75+ isNaN ( lastHeaterStatus ) ? "n/a" : ( heaterStates [ lastHeaterStatus ] ?? lastHeaterStatus )
76+ } `
77+ ) ;
78+ writeLine (
79+ ` 🌡️ Boiler Temperature : ${ isNaN ( lastTemperature ) ? "n/a" : lastTemperature . toFixed ( 2 ) + " °C" } `
80+ ) ;
81+ writeLine (
82+ ` 🚰 Pump Status : ${
83+ isNaN ( lastPumpStatus ) ? "n/a" : ( pumpStates [ lastPumpStatus ] ?? lastPumpStatus )
84+ } `
85+ ) ;
86+ writeLine (
87+ ` 🚪 Valve Status : ${
88+ isNaN ( lastValveStatus ) ? "n/a" : ( valveStates [ lastValveStatus ] ?? lastValveStatus )
89+ } `
90+ ) ;
91+ writeLine (
92+ ` 💧 Water Tank Level : ${ isNaN ( lastWaterTankLevel ) ? "n/a" : lastWaterTankLevel . toFixed ( 2 ) + " ml" } `
93+ ) ;
94+ writeLine (
95+ ` ⚙️ Grinder Status : ${
96+ isNaN ( lastGrinderStatus ) ? "n/a" : ( grinderStates [ lastGrinderStatus ] ?? lastGrinderStatus )
97+ } `
98+ ) ;
99+ writeLine (
100+ ` ⏱️ Grinding Duration : ${
101+ isNaN ( lastGrindingDuration ) ? "n/a" : lastGrindingDuration . toFixed ( 2 ) + " s"
102+ } `
103+ ) ;
104+ writeLine (
105+ ` ☕ Coffee Bean Level : ${ isNaN ( lastCoffeeBeanLevel ) ? "n/a" : lastCoffeeBeanLevel . toFixed ( 2 ) + " g" } `
106+ ) ;
107+ writeLine ( "========================================" ) ;
108+ writeLine ( "---- Recorded Actions (last 5) ----" ) ;
109+ recordedActions
110+ . slice ( - 5 )
111+ . forEach ( ( action ) => writeLine ( action + " " ) ) ;
112+ writeLine ( "-----------------------------------" ) ;
113+ } ;
30114 try {
31115 thing
32116 . observeProperty ( "waterTankLevel" , async ( data ) => {
33- const waterTankLevel = await data . value ( ) ;
34- console . log ( "------------------------------" ) ;
35- console . log ( "tankLevel : " , waterTankLevel , "ml" ) ;
36- console . log ( "------------------------------" ) ;
117+ lastWaterTankLevel = ( await data . value ( ) ) as number ;
118+ displayOnlineStatus ( ) ;
37119 } )
38120 . catch ( ( err ) => {
39121 console . error ( "Error observing waterTankLevel property:" , err ) ;
40122 } ) ;
41123 thing
42124 . observeProperty ( "coffeeBeanLevel" , async ( data ) => {
43- const coffeBeanLevel = await data . value ( ) ;
44- console . log ( "------------------------------" ) ;
45- console . log ( "bean level : " , coffeBeanLevel , "g" ) ;
46- console . log ( "------------------------------" ) ;
125+ lastCoffeeBeanLevel = ( await data . value ( ) ) as number ;
126+ displayOnlineStatus ( ) ;
47127 } )
48128 . catch ( ( err ) => {
49129 console . error ( "Error observing coffeeBeanLevel property:" , err ) ;
50130 } ) ;
131+ thing
132+ . observeProperty ( "temperature" , async ( data ) => {
133+ lastTemperature = ( await data . value ( ) ) as number ;
134+ displayOnlineStatus ( ) ;
135+ } )
136+ . catch ( ( err ) => {
137+ console . error ( "Error observing temperature property:" , err ) ;
138+ } ) ;
139+ thing
140+ . observeProperty ( "currentState" , async ( data ) => {
141+ lastCurrentState = ( await data . value ( ) ) as number ;
142+ displayOnlineStatus ( ) ;
143+ } )
144+ . catch ( ( err ) => {
145+ console . error ( "Error observing currentState property:" , err ) ;
146+ } ) ;
147+ thing
148+ . observeProperty ( "grinderStatus" , async ( data ) => {
149+ lastGrinderStatus = ( await data . value ( ) ) as number ;
150+ displayOnlineStatus ( ) ;
151+ } )
152+ . catch ( ( err ) => {
153+ console . error ( "Error observing grinderStatus property:" , err ) ;
154+ } ) ;
155+ thing
156+ . observeProperty ( "grindingDuration" , async ( data ) => {
157+ lastGrindingDuration = ( await data . value ( ) ) as number ;
158+ displayOnlineStatus ( ) ;
159+ } )
160+ . catch ( ( err ) => {
161+ console . error ( "Error observing grindingDuration property:" , err ) ;
162+ } ) ;
163+ thing
164+ . observeProperty ( "heaterStatus" , async ( data ) => {
165+ lastHeaterStatus = ( await data . value ( ) ) as number ;
166+ displayOnlineStatus ( ) ;
167+ } )
168+ . catch ( ( err ) => {
169+ console . error ( "Error observing heaterStatus property:" , err ) ;
170+ } ) ;
171+ thing
172+ . observeProperty ( "pumpStatus" , async ( data ) => {
173+ lastPumpStatus = ( await data . value ( ) ) as number ;
174+ displayOnlineStatus ( ) ;
175+ } )
176+ . catch ( ( err ) => {
177+ console . error ( "Error observing pumpStatus property:" , err ) ;
178+ } ) ;
179+ thing
180+ . observeProperty ( "valveStatus" , async ( data ) => {
181+ lastValveStatus = ( await data . value ( ) ) as number ;
182+ displayOnlineStatus ( ) ;
183+ } )
184+ . catch ( ( err ) => {
185+ console . error ( "Error observing valveStatus property:" , err ) ;
186+ } ) ;
187+
188+ // give some time to gather initial values
189+ await pause ( 2000 ) ;
190+ await waitingMachineCoffeeStandByState ( ) ;
191+ recordAction ( "Machine is ready !" ) ;
192+
193+ await pause ( 10000 ) ;
194+
195+ recordAction ( "Invoking brewCoffee(Mocha) action..." ) ;
196+ await thing . invokeAction ( "brewCoffee" , { RecipeName : "Mocha" } ) ;
197+ await waitingMachineCoffeeStandByState ( ) ;
198+ recordAction ( "Coffee is ready !" ) ;
199+
200+ await pause ( 10000 ) ;
201+
202+ recordAction ( "Invoking brewCoffee(Americano) action..." ) ;
203+ await thing . invokeAction ( "brewCoffee" , { RecipeName : "Americano" } ) ;
204+ await waitingMachineCoffeeStandByState ( ) ;
205+ recordAction ( "Coffee is ready !" ) ;
51206
52- await thing . invokeAction ( "brewCoffee" , { CoffeeType : 1 } ) ;
53- await pause ( 5000 ) ;
54- await thing . invokeAction ( "brewCoffee" , { CoffeeType : 0 } ) ;
55- await pause ( 5000 ) ;
207+ await pause ( 10000 ) ;
56208
209+ recordAction ( "Invoking fillTank action..." ) ;
57210 await thing . invokeAction ( "fillTank" ) ;
58- await pause ( 5000 ) ;
211+ await waitingMachineCoffeeStandByState ( ) ;
212+ recordAction ( "Tank is refilled !" ) ;
213+ recordAction ( "Done !" ) ;
59214 } finally {
60215 await servient . shutdown ( ) ;
61216 }
0 commit comments