[  
  {  
    "id":"mqtt_btn",  
    "type":"mqtt in",  
    "z":"flow",  
    "name":"AWTRIX Button",  
    "topic":"YOUR_MQTT_PREFIX/btn",  
    "qos":"0",  
    "datatype":"json",  
    "broker":"mqtt_broker"  
  },  
  {  
    "id":"handle_btn",  
    "type":"function",  
    "z":"flow",  
    "name":"Handle Middle Button",  
    "func":"// states: idle, work, break\nlet state = global.get('workState') || 'idle';\nif(msg.payload.button!=='middle') return null;\nswitch(state) {\n  case 'idle':\n    global.set('workState','work');\n    return {topic:'work_start'};\n  case 'work':\n    global.set('workState','break');\n    return {topic:'break_start'};\n  case 'break':\n    global.set('workState','work');\n    return {topic:'break_resume'};\n}\nreturn null;","outputs":1,"noerr":0},  
  {  
    "id":"inject_tick",  
    "type":"inject",  
    "z":"flow",  
    "name":"Every second",  
    "props":[{"p":"payload"}],  
    "repeat":"1",  
    "once":false  
  },  
  {  
    "id":"publish_work",  
    "type":"function",  
    "z":"flow",  
    "name":"Work Timer Tick",  
    "func":"let state=global.get('workState');\nif(state!=='work') return null;\nlet start=global.get('workStart')||Date.now();\nlet elapsed=(Date.now()-start)/1000; // seconds\nlet total=7.5*3600;\nlet rem=Math.max(0, total-elapsed)|0;\nlet pct=((elapsed/total)*100)|0;\n// hourly break trigger\nglobal.set('lastHourTrig', global.get('lastHourTrig')||0);\nif(rem%3600===0 && rem!==total && rem/3600!==global.get('lastHourTrig')){\n  global.set('lastHourTrig', rem/3600);\n  global.set('workState','paused_for_break');\n  return {topic:'hour_break'};\n}\nmsg.payload=JSON.stringify({icon:global.get('timerIcon'),text:rem,progress:pct,progressC:'#f00',progressBC:'#000'});\nmsg.topic=`${global.get('mqttPrefix')}/${global.get('customTopic')}`;\nreturn msg;","outputs":1,"noerr":0},  
  {  
    "id":"work_start",  
    "type":"function",  
    "z":"flow",  
    "name":"On Work Start",  
    "func":"global.set('workStart', Date.now());\nglobal.set('lastHourTrig',0);\nreturn null;","outputs":1  
  },  
  {  
    "id":"hour_break",  
    "type":"switch",  
    "z":"flow",  
    "name":"Hourly Break",  
    "property":"topic",  
    "rules":[{"t":"eq","v":"hour_break"}]  
  },  
  {  
    "id":"notify_break",  
    "type":"mqtt out",  
    "z":"flow",  
    "name":"Show 1 hr Break",  
    "topic":"${mqttPrefix}/${customTopic}",  
    "qos":"0",  
    "retain":false,  
    "broker":"mqtt_broker",  
    "x":750,"y":300  
  },  
  {  
    "id":"start_break_timer",  
    "type":"function",  
    "z":"flow",  
    "name":"Prepare Break",  
    "func":"// pause work tick\nglobal.set('workState','break_wait');\nmsg.payload=JSON.stringify({icon:global.get('breakIcon'),text:'1 hr break'});\nreturn msg;","outputs":1  
  },  
  {  
    "id":"break_start",  
    "type":"switch",  
    "z":"flow",  
    "name":"On Break Start",  
    "property":"topic",  
    "rules":[{"t":"eq","v":"break_start"}]  
  },  
  {  
    "id":"break_timer",  
    "type":"delay",  
    "z":"flow",  
    "name":"10 min Break Timer",  
    "pauseType":"delay",  
    "timeout":"10","timeoutUnits":"minutes"  
  },  
  {  
    "id":"break_finish",  
    "type":"function",  
    "z":"flow",  
    "name":"Break Complete",  
    "func":"// after break\nmsg.topic=`${global.get('mqttPrefix')}/${global.get('customTopic')}`;\nmsg.payload=JSON.stringify({icon:global.get('breakIcon'),text:0});\nglobal.set('workState','work');\nreturn msg;","outputs":1  
  },  
  {  
    "id":"publish_break",  
    "type":"function",  
    "z":"flow",  
    "name":"Break Tick",  
    "func":"let state=global.get('workState');\nif(state!=='break') return null;\nlet start=global.get('breakStart')||Date.now();\nlet elapsed=(Date.now()-start)/1000;\nlet total=10*60;\nlet rem=Math.max(0,total-elapsed)|0;\nmsg.topic=`${global.get('mqttPrefix')}/${global.get('customTopic')}`;\nmsg.payload=JSON.stringify({icon:global.get('breakIcon'),text:rem});\nreturn msg;","outputs":1  
  },  
  {  
    "id":"mqtt_out",  
    "type":"mqtt out",  
    "z":"flow",  
    "name":"AWTRIX Display",  
    "topic":"",  
    "qos":"0",  
    "retain":false,  
    "broker":"mqtt_broker"  
  }  
]