Add sound manager initial source code
[staging/soundmanager.git] / sample / radio_qml / app / api / Binding.qml
1 /*
2  * Copyright (C) 2016 The Qt Company Ltd.
3  * Copyright (C) 2017 Konsulko Group
4  * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 import QtQuick 2.6
20 import QtWebSockets 1.0
21
22 WebSocket {
23     id: root
24     active: true
25     url: bindingAddress
26
27     property string apiString: "radio"
28     property string smApiString: "soundmanager"
29     property var verbs: []
30     property string payloadLength: "9999"
31
32     readonly property var msgid: {
33          "call": 2,
34          "retok": 3,
35          "reterr": 4,
36          "event": 5
37     }
38
39     readonly property int amBand: 0
40     readonly property int fmBand: 1
41
42     readonly property int stoppedState: 0
43     readonly property int activeState: 1
44
45     property int band: fmBand
46     property int frequency
47     property int frequencyStep
48     property int minimumFrequency
49     property int maximumFrequency
50     property int state: stoppedState
51     property int scanningState: stoppedState
52     property bool scanningFreqUpdate: false
53     property string stationId: ""
54
55     signal stationFound
56
57     property Connections c : Connections {
58         target: root
59
60         onFrequencyChanged: {
61             if(scanningState != activeState) {
62                 // Not scanning, push update
63                 sendSocketMessage("frequency", { value: frequency })
64             } else if(!scanningFreqUpdate) {
65                 // External change, stop scanning
66                 sendSocketMessage("scan_stop", 'None')
67                 scanningState = stoppedState
68                 sendSocketMessage("frequency", { value: frequency })
69             } else {
70                 // This update was from scanning, clear state
71                 scanningFreqUpdate = false
72             }
73         }
74
75         onBandChanged: {
76             sendSocketMessage("band", { value: band })
77             updateFrequencyRange(band)
78             updateFrequencyStep(band)
79             frequency = minimumFrequency
80         }
81     }
82
83     onTextMessageReceived: {
84         var json = JSON.parse(message)
85         //console.debug("Raw response: " + message)
86         var request = json[2].request
87         var response = json[2].response
88
89         switch (json[0]) {
90         case msgid.call:
91             break
92         case msgid.retok:
93             var verb = verbs.shift()
94             if (verb == "frequency_range") {
95                 minimumFrequency = response.min
96                 maximumFrequency = response.max
97             } else if (verb == "frequency_step") {
98                 frequencyStep = response.step
99             }
100             break
101         case msgid.event:
102             var event = JSON.parse(JSON.stringify(json[2]))
103             if (event.event === "radio/frequency") {
104                 if(scanningState == activeState) {
105                     scanningFreqUpdate = true
106                     frequency = event.data.value
107                 }
108             } else if (event.event === "radio/station_found") {
109                 if(scanningState == activeState) {
110                     scanningState = stoppedState
111                     stationId = freq2str(event.data.value)
112                     root.stationFound()
113                 }
114             }
115             break
116         case msg.reterr:
117             console.debug("Bad return value, binding probably not installed")
118             break
119         case MessageId.event:
120             break
121         }
122     }
123
124     onStatusChanged: {
125         switch (status) {
126         case WebSocket.Open:
127             // Initialize band values now that we're connected to the
128             // binding
129             updateFrequencyRange(band)
130             updateFrequencyStep(band)
131             frequency = minimumFrequency
132             sendSocketMessage("subscribe", { value: "frequency" })
133             sendSocketMessage("subscribe", { value: "station_found" })
134             break
135         case WebSocket.Error:
136             console.debug("WebSocket error: " + root.errorString)
137             break
138         }
139     }
140
141     function freq2str(freq) {
142         if (freq > 5000000) {
143             return '%1 MHz'.arg((freq / 1000000).toFixed(1))
144         } else {
145             return '%1 kHz'.arg((freq / 1000).toFixed(0))
146         }
147     }
148
149     function sendSocketMessage(verb, parameter) {
150         var requestJson = [ msgid.call, payloadLength, apiString + '/'
151                            + verb, parameter ]
152         //console.debug("sendSocketMessage: " + JSON.stringify(requestJson))
153         verbs.push(verb)
154         sendTextMessage(JSON.stringify(requestJson))
155     }
156
157     function start() {
158         sendSocketMessage("start", 'None')
159         state = activeState
160     }
161
162     function stop() {
163         sendSocketMessage("stop", 'None')
164         state = stoppedState
165     }
166
167     function tuneUp() {
168         frequency += frequencyStep
169         if(frequency > maximumFrequency) {
170             frequency = minimumFrequency
171         }
172     }
173
174     function tuneDown() {
175         frequency -= frequencyStep
176         if(frequency < minimumFrequency) {
177             frequency = maximumFrequency
178         }
179     }
180
181     function scanUp() {
182         scanningState = activeState
183         sendSocketMessage("scan_start", { direction: "forward" })
184     }
185
186     function scanDown() {
187         scanningState = activeState
188         sendSocketMessage("scan_start", { direction: "backward" })
189     }
190
191     function updateFrequencyRange(band) {
192         sendSocketMessage("frequency_range", { band: band })
193     }
194
195     function updateFrequencyStep(band) {
196         sendSocketMessage("frequency_step", { band: band })
197     }
198
199         // Add function for communicating sound manager
200         // This is temporary. It is not better to create function 
201         // for soundmanager in this scope
202
203     function sendSocketMessageToSoundManager(verb, parameter) {
204         var requestJson = [ msgid.call, payloadLength, smApiString + '/'
205                            + verb, parameter ]
206         //console.debug("sendSocketMessage: " + JSON.stringify(requestJson))
207         verbs.push(verb)
208         sendTextMessage(JSON.stringify(requestJson))
209     }
210         function connect(sourceID, sinkID) {
211                 var str = "{sourceID:" + sourceID + ", sinkID:" + sinkID + "}"
212                 var JsonArg = JSON.stringify(str)
213         console.log(str)
214         console.log(JsonArg)
215                 sendSocketMessageToSoundManager("connect", JsonArg)     
216         }
217         function subscribe(event) {
218                 var str = "{event:" + event + "}"
219                 var JsonArg = JSON.stringify(str)
220                 sendSocketMessageToSoundManager("subscribe", JsonArg)
221         }
222         function unsubscribe(event) {
223                 var str = "{event:" + event + "}"
224                 var JsonArg = JSON.stringify(str)
225                 sendSocketMessageToSoundManager("unsubscribe", JsonArg)
226         }
227         function registerSource() {
228                 // Nothing for now
229         }
230 }