Sonos SMAPI unable to start playback of cloudQueue when receiving GET context and itemWindow - sonos

I am currently developing an API connection between my application, and Sonos Cloud API.
When initiating the loadCloudQueue command, some of tested players, will not start the playback of the
cloudQueue, but only the one item described in the loadCloudQueue command itself.
I really working blind, due to some of the players are able to start the cloudQueue playback, and some of them are now.
When testing the player, it is able to ask for the GET / Context and the GET / itemWindow.
But it never starts.
Example of the GET / Context response:
queueVersion: 608124fb068ff506234390dd,
contextVersion: 608124fb068ff506234390dd,
container: { name: 'Handcrafted playlist for Ole ' },
reports: { sendUpdateAfterMillis: 100000, sendPlaybackActions: true },
playbackPolicies: {
canSkip: true,
limitedSkips: false,
canSkipToItem: false,
canSkipBack: false,
canSeek: false,
canRepeat: true,
canRepeatOne: false,
canCrossfade: true,
canShuffle: false,
showNNextTracks: 10,
showNPreviousTracks: 10
}
}
And the itemWindow response:
1|app | {
1|app | isExplicit: 'false',
1|app | reason: 'load',
1|app | itemId: '5f9d1e98e51a783b3bb741a8-2',
1|app | positionMillis: '2335',
1|app | queueVersion: '608124fb068ff506234390dd',
1|app | contextVersion: '608124fb068ff506234390dd',
1|app | previousWindowSize: '9',
1|app | upcomingWindowSize: '10'
1|app | }
1|app | {
1|app | includesBeginningOfQueue: true,
1|app | includesEndOfQueue: false,
1|app | queueVersion: 608124fb068ff506234390dd,
1|app | contextVersion: 608124fb068ff506234390dd,
1|app | items: [
1|app | {
1|app | itemId: '5f9d1e98e51a783b3bb741a8-2',
1|app | deleted: false,
1|app | track: [Object]
1|app | },
1|app | {
1|app | itemId: '5f9f16df0255876d60a379c2-3',
1|app | deleted: false,
1|app | track: [Object]
1|app | },
1|app | {
1|app | itemId: '5f9fd3606941737c38b52845-4',
1|app | deleted: false,
1|app | track: [Object]
1|app | },
1|app | {
1|app | itemId: '5f9fd741c790807608310700-5',
1|app | deleted: false,
1|app | track: [Object]
1|app | },
1|app | {
1|app | itemId: '5fc39512583fe814cc017df4-6',
1|app | deleted: false,
1|app | track: [Object]
1|app | },
1|app | {
1|app | itemId: '602b9707aa5ff30a5ce2e72a-7',
1|app | deleted: false,
1|app | track: [Object]
1|app | },
1|app | {
1|app | itemId: '603f977f64c25e20af3b2cb0-8',
1|app | deleted: false,
1|app | track: [Object]
1|app | },
1|app | {
1|app | itemId: '6040e7ca0c32a64babe1d19b-9',
1|app | deleted: false,
1|app | track: [Object]
1|app | },
1|app | {
1|app | itemId: '604fbefaf627431c25f670d2-10',
1|app | deleted: false,
1|app | track: [Object]
1|app | }
1|app | ]
1|app | }
I really apreciate all the good advises I can get

An example of a functional request & response for /context & /itemWindow:
request to /context:
200 [06/01/21 5:03:14 pm] GET /v2.3/radio/myprefix%3a123456789012345678901234/context?queueVersion=&contextVersion= ReqToken- Bearer <authToken> ResToken- -
response from /context:
{
contextVersion: 'CV:00001',
queueVersion: 'QV:00001',
container: {
type: 'trackList.program',
name: 'my cool name',
imageUrl: 'https://myartworkdomain/program_default.jpg',
id: { objectId: 'myprefix:123456789012345678901234' }
},
playbackPolicies: {
canSkip: true,
limitedSkips: true,
canSkipToItem: false,
canSkipBack: false,
canSeek: false,
canCrossfade: true,
canRepeat: true,
canRepeatOne: false,
canShuffle: false,
pauseAtEndOfQueue: false,
showNPreviousTracks: 0,
showNNextTracks: 1
},
reports: { sendUpdateAfterMillis: 5000, periodicIntervalMillis: 30000 }
}
request to /itemWindow:
200 [06/01/21 5:03:17 pm] GET /v2.3/radio/myprefix%3a123456789012345678901234/itemWindow?isExplicit=true&reason=load&itemId=&positionMillis=0&queueVersion=&contextVersion=CV%3a00001&previousWindowSize=9&upcomingWindowSize=10&heardItemId= ReqToken- Bearer <authToken> ResToken- -
response from /itemWindow:
{
contextVersion: 'CV:00001',
queueVersion: 'QV:00001',
items: [
{
id: 'C6RRZGXP',
deleted: false,
policies: { canSkip: true },
track: {
name: '<name>',
album: { name: '<albumName>', artist: { name: '<artistName>' } },
artist: { name: '<artistName>' },
imageUrl: 'https://myartworkdomain.com/e24f71bf24f67a38eeeed6865d2bd582.jpeg',
mediaUrl: 'https://mystreamdomain.com/e24f71bf24f67a38eeeed6865d2bd582.m4a',
durationMillis: 123456,
contentType: 'audio/aac'
}
},
{
id: 'FT46XQT3',
deleted: false,
policies: { canSkip: true },
track: {
name: '<name>',
album: { name: '<albumName>', artist: { name: '<artistName>' } },
artist: { name: '<artistName>' },
imageUrl: 'https://myartworkdomain.com/0cff6be10e41a0beed35438b1e43bf8b.jpeg',
mediaUrl: 'https://mystreamdomain.com/0cff6be10e41a0beed35438b1e43bf8b.m4a',
durationMillis: 234567,
contentType: 'audio/aac'
}
}
],
limitedSkipsState: { skipsRemaining: 3, skipLimitReached: false },
includesBeginningOfQueue: true,
includesEndOfQueue: false
}
This should work.

Related

How to populate data from jqGrid row to a textbox

I have a main jqgrid working with 5 columns out of 22 columns. I want to populate the 22 columns data in toolboxes (textbox, checkbox...) when a row is selected
Using a jqgrid subgrid all work perfectly.
So how to populate the data passed into the subgrid to my toolbox elements instead.
The other work arround that works, but does not satisfy me, is to call all needed data in the main grid hide the 22 columns and populate them in the boxes onselect. See whole code below:
jQuery(document).ready(function () {
$("#grid").jqGrid({
url: 'GetDemandeurs_Cons',
datatype: 'json',
mtype: 'GET',
colNames: [
'Code',
'Nom',
'Prenoms',
'Courriel',
'Adresse_Demandeur',
],
colModel: [
{ key: true, name: 'Code_Demandeur', index: 'Code_Demandeur' },
{ key: false, name: 'Nom_Demandeur', index: 'Nom_Demandeur' },
{ key: false, name: 'Prenoms_Demandeur', index: 'Prenoms_Demandeur' },
{ key: false, name: 'Courriel1_Demandeur', index: 'Courriel1_Demandeur' },
{ key: false, name: 'Adresse_Demandeur', index: 'Adresse_Demandeur' },
],
pager: $('#pager'),
rowNum: 10,
rowList: [5, 10, 20, 50],
height: '100%',
emptyrecords: "Pas d'enregistrement à afficher",
jsonReader: {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
id: "0"
},
autowidth: true,
multiselect: false,
sortname: 'Code_Demandeur',
sortorder: "asc",
viewrecords: true,
//caption: '<bListe des demandeurs</b>',
onSelectRow: function (ids) {
var data = $("#grid").getRowData(ids);
if (ids != null) {
console.log(data.Code_Demandeur);
console.log(data.Adresse_Demandeur);
$("#detailsDdeur")
.setGridParam({ url: "GetDdeurs_Cons_Subgrid?id=" + data.Code_Demandeur, page: 1 })
.setCaption("<b>Details pour : " + data.Prenoms_Demandeur + ' ' + data.Nom_Demandeur + "</b>")
.trigger('reloadGrid');
}
}
}).navGrid(pager, { edit: false, add: false, del: false, refresh: true, search: false });
jQuery("#grid").jqGrid('hideCol', ["Adresse_Demandeur"]);
$("#detailsDdeur").jqGrid
({
height: 100,
datatype: "json",
colNames: [
'Adresse_Demandeur',
'Ville',
'Province',
'Code Postal',
'Téléphone',
'Tel2_Demandeur',
'Tel3_Demandeur',
'Courriel2_Demandeur',
'Courriel3_Demandeur',
'ID_SituationMatrimoniale',
'Sexe',
'Date de Naissance',
'Revenu_Demandeur',
'ID_Occupation',
'ID_Scolarite',
'ID_StatutLegal',
'ID_Communaute',
'ID_SourceInformation',
'Handicape',
'Reference',
'Remarques_Demandeur',
'Photo'
],
colModel:
[
{ key: false, name: 'Adresse_Demandeur', index: 'Adresse_Demandeur' },
{ key: false, name: 'Ville', index: 'Ville' },
{ key: false, name: 'Province', index: 'Province' },
{ key: false, name: 'CodePostal_Demandeur', index: 'CodePostal_Demandeur' },
{ key: false, name: 'Tel1_Demandeur', index: 'Tel1_Demandeur' },
{ key: false, name: 'Tel2_Demandeur', index: 'Tel2_Demandeur' },
{ key: false, name: 'Tel3_Demandeur', index: 'Tel3_Demandeur' },
{ key: false, name: 'Courriel2_Demandeur', index: 'Courriel2_Demandeur' },
{ key: false, name: 'Courriel3_Demandeur', index: 'Courriel3_Demandeur' },
{ key: false, name: 'SitMat', index: 'SitMat' },
{ key: false, name: 'Sexe', index: 'Sexe' },
{ key: false, name: 'Date_Naissance_Demandeur', index: 'Date_Naissance_Demandeur' },
{ key: false, name: 'Revenu_Demandeur', index: 'Revenu_Demandeur' },
{ key: false, name: 'Occupation', index: 'Occupation' },
{ key: false, name: 'Scolarite', index: 'Scolarite' },
{ key: false, name: 'StatutLegal', index: 'StatutLegal' },
{ key: false, name: 'Communaute', index: 'Communaute' },
{ key: false, name: 'SourceInformation', index: 'SourceInformation' },
{ key: false, name: 'Handicape', index: 'Handicape' },
{ key: false, name: 'Reference', index: 'Reference' },
{ key: false, name: 'Remarques_Demandeur', index: 'Remarques_Demandeur' },
{ key: false, name: 'ID_Photo', index: 'ID_Photo' }
],
rowNum: 5,
rowList: [5, 10, 20],
jsonReader: {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
id: "0"
},
viewrecords: true,
sortorder: "desc",
}).navGrid('#OrderPager', { add: false, edit: false, del: false, search: false });
});
Add Code as given Below
colModel: [
{ name: 'Code_Demandeur', index: 'Code_Demandeur', width: 15, sorttype: "int", sortable: false, resizable: false,
formatter: function (cellvalue, options, rowObject) {
TxtRankName = "Code_Demandeur_" + options.rowId;
return txtBx(TxtRankName, cellvalue)
}
}
]
function txtBx(Id, Value) {
strTextBox = "<input type='text' id='" + Id + "'";
if (Value != "")
strTextBox = strTextBox + " title='" + Value + "' value='" + Value + "'";
strTextBox = strTextBox + " />";
return strTextBox;
}

ComboBoxItem not clearing unknown value on blur

To Start, here is my ComboBoxItem field
{
name: "State",
type: "ComboBoxItem",
canEdit: true,
valueMap: {
WI: "Wisconsin",
IL: "Illinois",
MN: "Minnesota",
MI: "Michigan"
},
addUnknownValues: false,
allowEmptyValue: false,
completeOnTab: true
}
I'm getting very different behavior out of a ComboBoxItem when it is in a ListGrid vs when it's in a DynamicForm.
In a DynamicForm if you were to type in a value that does NOT have a match in the valueMap and then leave the field, it would return to the previous value.
In an editable ListGrid if you were to type in a value that does NOT have a match in the valueMap and then leave the field, it would keep what ever characters you typed and try to save the edits with that string.
Walkthrough
The code used in the walkthrough
isc.VLayout.create({
height: 500,
width: 900,
margin: 100,
members: [
isc.ListGrid.create({
height: "100%",
width: "100%",
canEdit: true,
modalEditing: true,
extraSpace: 5,
fields: [
{ name: "Name", canEdit: true, },
{
name: "State",
type: "ComboBoxItem",
canEdit: true,
valueMap: {
WI: "Wisconsin",
IL: "Illinois",
MN: "Minnesota",
MI: "Michigan"
},
addUnknownValues: false,
//allowEmptyValue: false,
completeOnTab: true
}
],
data: [
{ Name: "Evan", State: "WI" },
{ Name: "Erik", State: "IL" },
{ Name: "Philip", State: "MI" },
]
}),
isc.DynamicForm.create({
height: "100%",
width: "100%",
border: "1px solid #ababab",
canEdit: true,
fields: [
{ name: "Name", canEdit: true, },
{
name: "State",
type: "ComboBoxItem",
canEdit: true,
valueMap: {
WI: "Wisconsin",
IL: "Illinois",
MN: "Minnesota",
MI: "Michigan"
},
addUnknownValues: false,
allowEmptyValue: false,
completeOnTab: true
}
],
values: { Name: "Evan", State: "WI" }
})
]
});
It would appear that addUnknownValues has a different effect on the two instances.
I solved the issue by moving addUnknownValues to the ListGridField's editorProperties
this is the updated ListGridField item
{
name: "State",
type: "ComboBoxItem",
canEdit: true,
valueMap: {
WI: "Wisconsin",
IL: "Illinois",
MN: "Minnesota",
MI: "Michigan"
},
editorProperties:{
addUnknownValues: false,
allowEmptyValue: false,
completeOnTab: true
}
}

Sequelizejs not giving clean data

When I query my database through sequelize.js using the following query:
models.User.findAll({
attributes: ['name', 'company_id'],
where: {
id: 6
}
}).then( function( data ) {
console.log( data );
});
I get :
[ { dataValues: { name: 'John', company_id: 221 },
_previousDataValues: { name: 'John', company_id: 221 },
_changed: {},
'$modelOptions':
{ timestamps: true,
instanceMethods: {},
classMethods: {},
validate: {},
freezeTableName: false,
underscored: false,
underscoredAll: false,
paranoid: false,
whereCollection: [Object],
schema: null,
schemaDelimiter: '',
defaultScope: null,
scopes: [],
hooks: {},
indexes: [],
name: [Object],
tableName: 'users',
createdAt: 'created',
updatedAt: 'modified',
omitNull: false,
sequelize: [Object],
uniqueKeys: {},
hasPrimaryKeys: true },
'$options': { isNewRecord: false, raw: true, attributes: [Object] },
hasPrimaryKeys: true,
__eagerlyLoadedAssociations: [],
isNewRecord: false } ]
How do I configure sequelize to give me clean data,i.e., only data rows and nothing else.

How to configure the datasource for the Kendo Treeview?

This should be an easy one but I'm missing something. I have an MVC application that returns JSON data using this controller method:
public ActionResult GetVenues()
{
ActionResult ar = Json(_VenueRepository.GetData(), JsonRequestBehavior.AllowGet);
return ar;
}
Nothing fancy here. I'm displaying a Kendo treeview on my view using the following code:
var venuetree = function () {
$("#venuetreeview").kendoTreeView({
checkboxes: {
checkChildren: true
},
dataSource: [{ id: 0, text: "Venues", items: [{ id: 1, text: "Venue 1", items: [{ id: 5, text: "Venue 2" }] }, { id: 2, text: "Venue 3", items: [{ id: 14, text: "Venue 4" }] }, { id: 3, text: "Venue 5", items: [{ id: 38, text: "Venue 6" }, { id: 39, text: "Venue 7" }, { id: 25, text: "Venue 8" }, { id: 26, text: "Venue 9" }, { id: 27, text: "Venue 10" }, { id: 28, text: "Venue 11" }] }, { id: 30, text: "Venue 12" }, { id: 40, text: "Venue 13", items: [{ id: 41, text: "Venue 14" }] }, { id: 4, text: "Venue 15", items: [{ id: 29, text: "Venue 16" }] }, { id: 31, text: "Venue 17" }, { id: 32, text: "Venue 18" }] }]
//dataSource: new kendo.data.HierarchicalDataSource({
// transport: {
// read: {
// url: "DataManager/GetVenues",
// dataType: "json",
// contentType: "application/json"
// }
// },
// pageSize: 100,
// requestEnd: function (e) {
// $("#wait").hide();
// },
//})
}).data("kendoTreeView");
};
The hard-coded JSON here renders just fine. I obtained this JSON directly from the ActionResult object in the controller method.
However, when I uncomment the code that returns the HierarchicalDataSource (while commenting out the hard-coded version, of course) The treeview displays a Loading message with a wait animation. Note: same problem using DataSource as HierarchicalDataSource.
Any ideas why its acting this way?
Thanks
Carl
i use this
var dataSource = new kendo.data.HierarchicalDataSource({
transport: {
read: {
url: foo,
datatype: "json",
contentType: "application/json"
}
},
schema: {
model: {
children: "items",
id: "id"
},
data: function(data) {
var dataArray = eval(data);
return dataArray;
}
}
});
I think eval(data) is the solution.
I tried many things and after using eval it works :)

Kendo UI: Sum in footertemplate

I'm trying to get my footerTemplate working with a Kendo UI grid. I want to get the sum of 'hours_worked' in the footer of the tabel. I've tryed several options from the Kendo UI example but it doesn't work for me. What im doing wrong?
$(document).ready(function() {
$("#grid").kendoGrid({
dataSource: {
transport:
read: {
url: "mods/hours/data/get_hours.php?id=<?php echo $volunteer_id; ?>",
dataType: "json"
}
},
schema: {
model: {
fields: {
hours_id: { type: "number" },
volunteer_first_name: { type: "string" },
volunteer_last_name: { type: "string" },
hours_date: { type: "date" },
location_name: { type: "string" },
work_type_name: { type: "string" },
volunteer_id: { type: "number" },
hours_worked: { type: "number" }
}
}
},
aggregate:[{ field:"hours_worked", aggregate:"sum" }],
pageSize: 10
},
height: 350,
filterable: true,
sortable: true,
pageable: true,
selectable:true,
columns: [
{
title:"Naam",
template:"#=volunteer_last_name#, #=volunteer_first_name#",
},{
title:"Locatie",
field:"location_name",
},{
title:"Werkzaamheden",
field:"work_type_name",
},{
title:"Uren",
field:"hours_worked",
footerTemplate:"Sum: #=sum#",
},{
title:"Datum",
field:"hours_date",
},{
width:"200px",
title:"Opties",
filterable: false,
template:"<a href='?p=edit_reported_hours&id=#=volunteer_id#&hours_id=#=hours_id#' class='k-button'>Bewerken</a> <a href='?p=manage_reported_hours&o=delete&id=#=volunteer_id#&hours_id=#=hours_id#' class='k-button'>Delete</a>"
},
]
});
});
</script>
Add a curly bracket after transport and it will work.
transport: {
read: {
url: "mods/hours/data/get_hours.php?id=<?php echo $volunteer_id; ?>",
dataType: "json"
}
},
See it here: http://jsfiddle.net/OnaBai/bWS7C/