Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Updating settings when app is closed

Hello all,

 

I am currently having an issue where if the user updates the settings while the app is not open it does not get persisted to the app.

 

This is my companion code.  It does call sendSettings, but I get the "No peerSocket connection".  What is the correct way of persisting the settings data to the app when it is closed?

 

/*
 * Entry point for the companion app
 */
import { settingsStorage } from "settings";
import { me } from "companion";
import * as messaging from "messaging";


// Event fires when a setting is changed
settingsStorage.onchange = (evt) => { sendSettings(); }

// Settings were changed while the companion was not running
if (me.launchReasons.settingsChanged) {
  sendSettings();
}

function sendSettings(){
  let flowTime = settingsStorage.getItem("flowTime");
  let shortTime = settingsStorage.getItem("shortBreakTime")
  let longTime = settingsStorage.getItem("longBreakTime")
  let data = {
      flowTime : flowTime ? flowTime : "25",
      shortBreakTime : shortTime ? shortTime : "5",
      longBreakTime : longTime ? longTime : "15"
  }
  
  // If we have a MessageSocket, send the data to the device
  if (messaging.peerSocket.readyState === messaging.peerSocket.OPEN) {
    messaging.peerSocket.send(data);
  } else {
    console.log("No peerSocket connection");
  }
}
Best Answer
0 Votes
3 REPLIES 3

I think this is normal, as the device app is not loaded so you can't send messages at that time.
You probably should persist the settings in your companion and load them (or read them directly from settingsStorage) as soon as the device app is started and messaging.peerSocket.onopen is called.

Best Answer
0 Votes

You can use the File Transfer API, this will ensure the settings files are transferred to the device, even if the app isn't running.

 

Here's an incomplete example which should give you some ideas:

 

// Companion 
import * as cbor from "cbor";
import { outbox } from "file-transfer";
import { settingsStorage } from "settings";

import { settingsPrefix } from "../common/constants";

function handleSettingsChange(evt) {
  if (!evt.newValue || evt.oldValue === evt.newValue) return;

  const data = {
    key: evt.key,
    value: JSON.parse(evt.newValue)
  };

  outbox
    .enqueue(`${settingsPrefix}.${evt.key}.cbor`, cbor.encode(data))
    .catch(error => {
      console.log(`Failed to queue settings for ${evt.key}. Error: ${error}`);
    });
}

settingsStorage.addEventListener("change", handleSettingsChange);
// App
let settings = {};

function startsWith(str, word) {
return str.lastIndexOf(word, 0) === 0;
}
function processSettingFile(newFile) { const setting = readFileSync(`/private/data/${newFile}`, settingsType); settings[setting.key] = setting.value; } function getNewFiles() { let fileName; do { fileName = inbox.nextFile(); if (fileName && startsWith(fileName, settingsPrefix)) { processSettingFile(fileName); } } while (fileName); }

getNewFiles();
Best Answer

This should really be added to the primary documentation on how to handle setting changes. I've been searching for this for some time lol.

 

Ironically I manage state through watch local JSON files. I should have put two and two together.

Best Answer
0 Votes