import * as cote from 'cote' ; import BalenaAudio from 'balena-audio' ; import SoundAPI from './SoundAPI' ; import SoundConfig from './SoundConfig' ; import { constants } from './constants' ; import { getSdk } from 'balena-sdk' ; const config = new SoundConfig ( ) ; const audioBlock = new BalenaAudio ( `tcp:${ config . device . ip }:4317` ) ; const soundAPI = new SoundAPI ( config , audioBlock ) ; config . bindAudioBlock ( audioBlock ) ; const sdk = getSdk ( { apiUrl : 'https://api.balena-cloud.com/' } ) ; sdk . auth . logout ( ) ; sdk . auth . loginWithToken ( process . env . BALENA_API_KEY ! ) ; let discoveryOptions = { log : false , helloLogsEnabled : false , statusLogsEnabled : false } ; const fleetPublisher = new cote . Publisher ( { name : 'balenaSound publisher' } , discoveryOptions ) ; const fleetSubscriber = new cote . Subscriber ( { name : 'balenaSound subscriber' } , discoveryOptions ) ; init ( ) ; async function init ( ) { await soundAPI . listen ( constants . port ) ; await audioBlock . listen ( ) ; await audioBlock . setVolume ( constants . volume ) ; if ( config . isMultiRoomEnabled ( ) ) { await timeout ( constants . coteDelay ) ; console . log ( 'Joining the fleet, requesting master info with fleet-sync...' ) ; fleetPublisher . publish ( 'fleet-sync' , { type : 'sync' , origin : config . device . ip } ) ; } setInterval ( ( ) => { if ( config . isMultiRoomEnabled ( ) ) { fleetPublisher . publish ( 'fleet-sync' , { type : 'sync' , origin : config . device . ip } ) ; } } , constants . multiroom . pollInterval ) ; } audioBlock . on ( 'play' , async ( sink ) => { if ( constants . debug ) { console . log ( `[event] Audio block: play` ) ; console . log ( sink ) ; } if ( config . isMultiRoomServer ( ) && sink . name === constants . inputSink ) { console . log ( `Playback started, announcing ${ config . device . ip } as multi-room master!` ) ; fleetPublisher . publish ( 'fleet-update' , { type : 'master' , master : config . device . ip } ) ; } try { await sdk . models . device . tags . set ( process . env . BALENA_DEVICE_UUID ! , 'metrics:play' , '' ) ; } catch ( error ) { console . log ( error . message ) ; } } ) ; fleetSubscriber . on ( 'fleet-update' , async ( data ) => { if ( constants . debug ) { console . log ( `[event] fleet: fleet-update` ) ; console . log ( data ) ; } if ( config . isNewMultiRoomMaster ( data . master ) && ! config . multiroom . forced && ! constants . multiroom . disallowUpdates ) { console . log ( `Multi-room master has changed to ${ data . master }, restarting snapcast-client...` ) ; config . setMultiRoomMaster ( data . master ) ; } } ) ; fleetSubscriber . on ( 'fleet-sync' , ( data ) => { if ( constants . debug ) { console . log ( `[event] fleet: fleet-sync` ) ; console . log ( data ) ; } if ( config . isMultiRoomMaster ( ) && data . origin !== config . device . ip ) { fleetPublisher . publish ( 'fleet-update' , { type : 'master' , master : config . multiroom . master } ) ; } } ) ; async function timeout ( delay ) { return new Promise ( resolve => setTimeout ( resolve , delay ) ) ; }