Logitech Media Server (LMS) dzVents adapter

Easy to use, 100% Lua-based event scripting framework.

Moderator: leecollings

Eoreh
Posts: 65
Joined: Tuesday 13 October 2015 13:50
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Poland
Contact:

Logitech Media Server (LMS) dzVents adapter

Post by Eoreh »

Hi !
I have made very simple custom dzVents' adapter for Logitech Media Server (LMS) based on adapter for "Kodi". Its look like this.

Code: Select all

return {
	baseType = 'device',
	name = 'lms device',
	matches = function (device, adapterManager)
		local res = (device.hardwareType == 'Logitech Media Server')
		if (not res) then
			adapterManager.addDummyMethod(device, 'lmsSwitchOff')
			adapterManager.addDummyMethod(device, 'lmsStop')
			adapterManager.addDummyMethod(device, 'lmsPlay')
			adapterManager.addDummyMethod(device, 'lmsPause')
			adapterManager.addDummyMethod(device, 'lmsSetVolume')
			adapterManager.addDummyMethod(device, 'lmsPlayPlaylist')
			adapterManager.addDummyMethod(device, 'lmsPlayFavorites')
		end
		return res
	end,
	process = function (device, data, domoticz, utils, adapterManager)
		function device.lmsSwitchOff()
			--return TimedCommand(domoticz, device.name, 'Off')
			domoticz.sendCommand(device.name, 'Off')
		end
		function device.lmsStop()
			--return TimedCommand(domoticz, device.name, 'Stop')
			domoticz.sendCommand(device.name, 'Stop')
		end
		function device.lmsPlay()
			--return TimedCommand(domoticz, device.name, 'Play')
			domoticz.sendCommand(device.name, 'Play')
		end
		function device.lmsPause()
			--return TimedCommand(domoticz, device.name, 'Pause')
			domoticz.sendCommand(device.name, 'Pause')
		end
		function device.lmsSetVolume(value)
			if (value < 0 or value > 100) then
				utils.log('Volume must be between 0 and 100. Value = ' .. tostring(value), utils.LOG_ERROR)
			else
				--return TimedCommand(domoticz, device.name, 'Pause')
				domoticz.sendCommand(device.name, 'Set Volume ' .. tostring(value))
			end
		end
		function device.lmsPlayPlaylist(name)
			if (position == nil) then
				position = ''
			end
			domoticz.sendCommand(device.name, 'Play Playlist ' .. tostring(name))
		end
		function device.lmsPlayFavorites(position)
			if (position == nil) then
				position = 0
			end
			domoticz.sendCommand(device.name, 'Play Favorites ' .. tostring(position))
		end
	end
}
Without changed in code Domoticz (only add adapter) I can play song in mp3 from "playlist" Favorites and my own defined (Test1 and Test2) from LMS (Synlogy) on my phone (android) with very cheap apps "Squeeze player".
(LMS and domoticz -> https://www.domoticz.com/wiki/Logitech_Media_Server)

My example of dzVents script looks like this (1 device to play song and 1 switch dummy for action):

Code: Select all

local lmsDevice='samsung SM-J500FN'   -- lms devices to play songs. 
return {
	on = {
		devices = {
			'test1'  -- dummy switch devices 
		}
	},
	execute = function(domoticz, mySwitch)
    	local lms = domoticz.devices(lmsDevice)
       --lms.lmsSetVolume(20)       
        if mySwitch.state=='On'  then
         lms.lmsPlayPlaylist('Test2')    -- play playlist with name "Test2"
           --lms.lmsPlay()
        end 
        if mySwitch.state=='Off'  then
            lms.lmsPlayPlaylist('Test1')    -- play playlist with name "Test1"
            --lms.lmsPlayFavorites(4)
            --lms.lmsPause()
            --lms.lmsStop()
            --lms.lmsSwitchOff()
    end 
	end
}
Ok. Now problems.
1. First -For some reason I can do only One (last one !) valid command with lms for One period of script. (so that's reason I commented on other commands in the example)

When i try do 2 command for example SetVolume() and PlayPlayList() only one command is made by eventhandler.
I dont know how this fix.

Code: Select all

2017-11-12 22:54:31.599 dzVents: Info: Handling events for: "test1", value: "On"
2017-11-12 22:54:31.599 dzVents: Info: ------ Start internal script: lms: Device: "test1 (Dummy)", Index: 2
2017-11-12 22:54:31.600 dzVents: Info: ------ Finished lms
2017-11-12 22:54:31.601 Command=Set Volume 20, FOR=0.00, AFTER=0.00, RANDOM=0.00, REPEAT=1 INTERVAL 0.00
2017-11-12 22:54:31.602 EventSystem: Scheduled Set Volume after 0.00.
2017-11-12 22:54:31.602 Command=Play Playlist Test2, FOR=0.00, AFTER=0.00, RANDOM=0.00, REPEAT=1 INTERVAL 0.00
2017-11-12 22:54:31.603 EventSystem: Scheduled Play Playlist after 0.00.
2017-11-12 22:54:31.603 EventSystem: Script event triggered: dzVents\runtime\dzVents.lua
2017-11-12 22:54:32.026  EventSystem: {"id":1,"method":"slim.request","params":["8c:27:6e:f9:ab:d2",["playlist", "play", "Test2"]]}
2. Unfortunately, the command "afterSec(x)" does not work for this device so i cant do lms.lmsSetVolume(20) and next lms.lmsPlayFavorites(4).afterSec(5)
3. If I want to choose a song from my favorite list, little change in EventSystem.cpp in function CEventSystem::ScheduleEvent is needed like this.

Code: Select all

if (pBaseHardware == NULL)  // if not handled try Logitech
		{
			pBaseHardware = m_mainworker.GetHardwareByType(HTYPE_LogitechMediaServer);
			if (pBaseHardware == NULL) return false;
			CLogitechMediaServer *pHardware = reinterpret_cast<CLogitechMediaServer*>(pBaseHardware);

			if (sParams.length() > 0)
			{
				level = atoi(sParams.c_str());
			}
		}

but without bigger changed in domoticz its not possible choose song from "custom list" (Test1 or Test2).

Can anyone help me with this problems ?.
Last edited by Eoreh on Monday 13 November 2017 18:21, edited 1 time in total.
dannybloe
Posts: 1355
Joined: Friday 29 August 2014 11:26
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Ermelo
Contact:

Re: LMS dzVents adapter

Post by dannybloe »

I will contact you soon to have this added to the codebase somehow.

I think that there is a limitation on how sendCommand works for a specific device in that if you send multiple commands back to Domoticz it only executes the last one.

If you want to use command options like afterSec() you have to wrap the command in a TimedCommand class. See any of the other adapters for examples.
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
Eoreh
Posts: 65
Joined: Tuesday 13 October 2015 13:50
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Poland
Contact:

Re: LMS dzVents adapter

Post by Eoreh »

1. Thank You for your replay. I will wait for your contact.

2. I'll try make afterSec() for this adapter. Maybe this will be solution to "limitation sendCommand.
Eoreh
Posts: 65
Joined: Tuesday 13 October 2015 13:50
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Poland
Contact:

Re: Logitech Media Server (LMS) dzVents adapter

Post by Eoreh »

Wow, it was so easy and "afterSec()" works.
Now in scripts i can use many commands for LMS. I know this is only workaround but its work. Thx again.
eg. script:

Code: Select all

local lmsDevice='samsung SM-J500FN'   -- lms devices to play songs. 
return {
	on = {
		devices = {
			'test1'  -- dummy switch devices to do any action 
		}
	},
	execute = function(domoticz, mySwitch)
    	local lms = domoticz.devices(lmsDevice)
        if mySwitch.state=='On'  then
            lms.lmsSetVolume(20)
            lms.lmsPlayPlaylist('Test2').afterSec(5)    -- play playlist with name "Test2"
            lms.lmsSetVolume(50).afterSec(10)       
            lms.lmsPause().afterSec(12)
            lms.lmsPlay().afterSec(20)
            lms.lmsSetVolume(100).afterSec(22)       
        end 
        if mySwitch.state=='Off'  then
            lms.lmsSetVolume(20)
            lms.lmsPlayPlaylist('Test1').afterSec(2)    -- play playlist with name "Test1"
            lms.lmsSetVolume(50).afterSec(8)
            lms.lmsPlayFavorites(4).afterSec(10)       -- play favorite list song 4  (required change in domoticz code). 
            --lms.lmsPause()
            lms.lmsPlayPlaylist('Test2').afterSec(20)    -- play playlist with name "Test2"
            lms.lmsSetVolume(100).afterSec(28)
            lms.lmsStop().afterSec(30)
            lms.lmsSetVolume(80).afterSec(38)
            lms.lmsSwitchOff().afterSec(40)
    end 
	end
}
dzVents - LMS adapter code:

Code: Select all

local TimedCommand = require('TimedCommand')
return {
	baseType = 'device',
	name = 'lms device',

	matches = function (device, adapterManager)
		local res = (device.hardwareType == 'Logitech Media Server')
		if (not res) then
			adapterManager.addDummyMethod(device, 'lmsSwitchOff')
			adapterManager.addDummyMethod(device, 'lmsStop')
			adapterManager.addDummyMethod(device, 'lmsPlay')
			adapterManager.addDummyMethod(device, 'lmsPause')
			adapterManager.addDummyMethod(device, 'lmsSetVolume')
			adapterManager.addDummyMethod(device, 'lmsPlayPlaylist')
			adapterManager.addDummyMethod(device, 'lmsPlayFavorites')
		end
		return res
	end,

	process = function (device, data, domoticz, utils, adapterManager)

		function device.lmsSwitchOff()
			return TimedCommand(domoticz, device.name, 'Off', 'device', device.state)
		--	domoticz.sendCommand(device.name, 'Off')
		end

		function device.lmsStop()
			return TimedCommand(domoticz, device.name, 'Stop', 'device', device.state)			
		--	domoticz.sendCommand(device.name, 'Stop')
		end

		function device.lmsPlay()
			return TimedCommand(domoticz, device.name, 'Play', 'device', device.state)			
			--domoticz.sendCommand(device.name, 'Play')
		end
		
		function device.lmsPause()
			return TimedCommand(domoticz, device.name, 'Pause', 'device', device.state)			
--			domoticz.sendCommand(device.name, 'Pause')
		end


		
		function device.lmsSetVolume(value)

			if (value < 0 or value > 100) then

				utils.log('Volume must be between 0 and 100. Value = ' .. tostring(value), utils.LOG_ERROR)

			else
				return TimedCommand(domoticz, device.name, 'Set Volume ' .. tostring(value), 'device', device.state)	
--				domoticz.sendCommand(device.name, 'Set Volume ' .. tostring(value))
			end
		end

		function device.lmsPlayPlaylist(name)
			if (position == nil) then
				position = ''
			end
			return TimedCommand(domoticz, device.name, 'Play Playlist ' .. tostring(name), 'device', device.state)	
--			domoticz.sendCommand(device.name, 'Play Playlist ' .. tostring(name))
		end

		function device.lmsPlayFavorites(position)
			if (position == nil) then
				position = 0
			end
			return TimedCommand(domoticz, device.name, 'Play Favorites ' .. tostring(position), 'device', device.state)	
--			domoticz.sendCommand(device.name, 'Play Favorites ' .. tostring(position))
		end
	
	end

}
dannybloe
Posts: 1355
Joined: Friday 29 August 2014 11:26
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Ermelo
Contact:

Re: Logitech Media Server (LMS) dzVents adapter

Post by dannybloe »

Does this device have any specific state information? Can you check this? Put dzVents in debug mode and locate the file scripts/dzVents/domoticzData.lua. Copy/paste the part for the LMS in here.
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
dannybloe
Posts: 1355
Joined: Friday 29 August 2014 11:26
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Ermelo
Contact:

Re: Logitech Media Server (LMS) dzVents adapter

Post by dannybloe »

I changed the function names a bit as you can see below.

Could you write some piece of the documentation here:

Code: Select all

#### Logitech Media Server
 - **switchOff()**: *Function*.  todo.
 - **stop()**: *Function*.  todo.
 - **play()**: *Function*.  todo.
 - **pause()**: *Function*.  todo.
 - **setVolume()**: *Function*.  todo.
 - **startPlaylist()**: *Function*.  todo.
 - **playFavorites()**: *Function*.  todo.
We also have to check if all the commands support all the TimedCommand options (like afterXXX(), forXXX(), withinXXX(), repeatAfterXXX(), checkState()).
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
dannybloe
Posts: 1355
Joined: Friday 29 August 2014 11:26
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Ermelo
Contact:

Re: Logitech Media Server (LMS) dzVents adapter

Post by dannybloe »

Eoreh?
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
Eoreh
Posts: 65
Joined: Tuesday 13 October 2015 13:50
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Poland
Contact:

Re: Logitech Media Server (LMS) dzVents adapter

Post by Eoreh »

Sorry for delay. Today I'm returning from a weekly delegation at work.
Tomorrow, I will try all things you ask me.
Eoreh
Posts: 65
Joined: Tuesday 13 October 2015 13:50
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Poland
Contact:

Re: Logitech Media Server (LMS) dzVents adapter

Post by Eoreh »

dannybloe wrote: Friday 17 November 2017 8:27 Does this device have any specific state information? Can you check this? Put dzVents in debug mode and locate the file scripts/dzVents/domoticzData.lua. Copy/paste the part for the LMS in here.

Code: Select all

[96] = {
		["data"] = {
			["unit"] = 1;
			["_nValue"] = 22;
			["usedByCamera"] = false;
			["protected"] = false;
			["levelVal"] = 147;
			["maxDimLevel"] = 15;
			["_state"] = "Unknown";
			["hardwareName"] = "LMS";
			["hardwareType"] = "Logitech Media Server";
			["hardwareID"] = 22;
			["hardwareTypeValue"] = 60;
			["icon"] = "LogitechMediaServer";
		};
		["timedOut"] = false;
		["switchType"] = "Media Player";
		["baseType"] = "device";
		["lastLevel"] = 0;
		["subType"] = "AC";
		["description"] = "";
		["changed"] = false;
		["deviceType"] = "Lighting 2";
		["signalLevel"] = 12;
		["rawData"] = {
			[1] = "147";
		};
		["deviceID"] = "0000015";
		["batteryLevel"] = 255;
		["lastUpdate"] = "2017-11-23 22:46:57";
		["switchTypeValue"] = 17;
		["id"] = 441;
		["name"] = "samsung SM-J500FN";
	};
Eoreh
Posts: 65
Joined: Tuesday 13 October 2015 13:50
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Poland
Contact:

Re: Logitech Media Server (LMS) dzVents adapter

Post by Eoreh »

dannybloe wrote: Friday 17 November 2017 8:45 I changed the function names a bit as you can see below.
My primary name based on "kodi" (cos' lms is internally very similar) but "short" name will be better.
dannybloe wrote: Friday 17 November 2017 8:45 Could you write some piece of the documentation here:

Code: Select all

#### Logitech Media Server
 - **switchOff()**: *Function*.  Will turn the device off.
 - **stop()**: *Function*.  Will send a Stop command, only effective if the device is streaming.
 - **play()**: *Function*.  Will send a Play command. If defice was off, it's  turning on and device is streming 
 - **pause()**: *Function*.  Will send a Pause command, only effective if the device is streaming.
 - **setVolume()**: *Function*.  Set the volume for a LMS device, 0 <= level <= 100.
 - **startPlaylist(name)**: *Function*.  Will playlist with "name". 
 - **playFavorites([position])**: *Function*.  Will playlist with name "Favorites", optionally starting at position. Favorite positions start from 0 which is the default.
dannybloe wrote: Friday 17 November 2017 8:45 We also have to check if all the commands support all the TimedCommand options (like afterXXX(), forXXX(), withinXXX(), repeatAfterXXX(), checkState()).

Code: Select all

- afterXXX() - support - and its necessary if two or more function will play in one scripts, one after one. 
- repeatAfterXXX() - support. 
rest function i have to do more test. I will do them in saturday.
dannybloe
Posts: 1355
Joined: Friday 29 August 2014 11:26
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Ermelo
Contact:

Re: Logitech Media Server (LMS) dzVents adapter

Post by dannybloe »

Eoreh wrote: Thursday 23 November 2017 22:54
dannybloe wrote: Friday 17 November 2017 8:27 Does this device have any specific state information? Can you check this? Put dzVents in debug mode and locate the file scripts/dzVents/domoticzData.lua. Copy/paste the part for the LMS in here.

Code: Select all

[96] = {
		["data"] = {
			["levelVal"] = 147;
			["_nValue"] = 22;
		};
		["rawData"] = {
			[1] = "147";
		};
	};
I wonder what levelVal/rawData is here. Any idea? If you say that the volume is from 0-100 then what is this? And what about the _nValue? Given this information I'd say at this moment you don't know what the current volume level is right?
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
Eoreh
Posts: 65
Joined: Tuesday 13 October 2015 13:50
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Poland
Contact:

Re: Logitech Media Server (LMS) dzVents adapter

Post by Eoreh »

dannybloe wrote: Friday 17 November 2017 8:27 I wonder what levelVal/rawData is here. Any idea? If you say that the volume is from 0-100 then what is this? And what about the _nValue? Given this information I'd say at this moment you don't know what the current volume level is right?

Code: Select all

[96] = {
		["data"] = {
			["levelVal"] = 147;
			["_nValue"] = 22;
		};
		["rawData"] = {
			[1] = "147";
		};
	};
147 - it's uniq id playlist from LMS
22 - it's idx of hardware (LMS).

Correct. I dont have information of volume level in current moment from device hardware. LMS have very extended API but in this moment domoticz is used limited implementation.
dannybloe
Posts: 1355
Joined: Friday 29 August 2014 11:26
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Ermelo
Contact:

Re: Logitech Media Server (LMS) dzVents adapter

Post by dannybloe »

Ok, so would it help to add a property playlistID?
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
User avatar
EdwinK
Posts: 1820
Joined: Sunday 22 January 2017 21:46
Target OS: Raspberry Pi / ODroid
Domoticz version: BETA
Location: Rhoon
Contact:

Re: Logitech Media Server (LMS) dzVents adapter

Post by EdwinK »

Waht is the difference with the build-in LMS plugin?
Running latest BETA on a Pi-3 | Toon® Thermostat (rooted) | Hue | Tuya | IKEA tradfri | Dashticz V3 on Lenovo Huawei Tablet | Conbee
dannybloe
Posts: 1355
Joined: Friday 29 August 2014 11:26
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Ermelo
Contact:

Re: Logitech Media Server (LMS) dzVents adapter

Post by dannybloe »

Eoreh wrote: Friday 24 November 2017 11:27
dannybloe wrote: Friday 17 November 2017 8:27 I wonder what levelVal/rawData is here. Any idea? If you say that the volume is from 0-100 then what is this? And what about the _nValue? Given this information I'd say at this moment you don't know what the current volume level is right?

Code: Select all

[96] = {
		["data"] = {
			["levelVal"] = 147;
			["_nValue"] = 22;
		};
		["rawData"] = {
			[1] = "147";
		};
	};
147 - it's uniq id playlist from LMS
22 - it's idx of hardware (LMS).

Correct. I dont have information of volume level in current moment from device hardware. LMS have very extended API but in this moment domoticz is used limited implementation.
uniq id playlist? Is that the current playlist being played?
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
Eoreh
Posts: 65
Joined: Tuesday 13 October 2015 13:50
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Poland
Contact:

Re: Logitech Media Server (LMS) dzVents adapter

Post by Eoreh »

EdwinK wrote: Friday 24 November 2017 13:09 Waht is the difference with the build-in LMS plugin?
"Plugin" or rather "hardwar"e becouse LMS is implemented in domoticz just give You device to play or stop play from LMS server (with broken, not implemented pilot). dzVents lets you do things that only it can do :)
Eoreh
Posts: 65
Joined: Tuesday 13 October 2015 13:50
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Poland
Contact:

Re: Logitech Media Server (LMS) dzVents adapter

Post by Eoreh »

uniq id playlist? Is that the current playlist being played?
Yep. Its just implementation domoticz. if i would play list I just pass "name playlist" (not id list). I dont see id playlist in LMS. I thing its some like bug domoticz.
Eoreh
Posts: 65
Joined: Tuesday 13 October 2015 13:50
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Poland
Contact:

Re: Logitech Media Server (LMS) dzVents adapter

Post by Eoreh »

dannybloe wrote: Friday 17 November 2017 8:45 We also have to check if all the commands support all the TimedCommand options (like afterXXX(), forXXX(), withinXXX(), repeatAfterXXX(), checkState()).
Ok, i do little more test with timedCommand:

Code: Select all

- afterXXX() - support - and its necessary if two or more function will play in one scripts, one after one. 
- repeatAfterXXX() - support. 
- withinXXX() - support. 

no support: forXXX(), checkState()
User avatar
EdwinK
Posts: 1820
Joined: Sunday 22 January 2017 21:46
Target OS: Raspberry Pi / ODroid
Domoticz version: BETA
Location: Rhoon
Contact:

Re: Logitech Media Server (LMS) dzVents adapter

Post by EdwinK »

Eoreh wrote: Friday 24 November 2017 21:54
EdwinK wrote: Friday 24 November 2017 13:09 Waht is the difference with the build-in LMS plugin?
"Plugin" or rather "hardwar"e becouse LMS is implemented in domoticz just give You device to play or stop play from LMS server (with broken, not implemented pilot). dzVents lets you do things that only it can do :)
Okay. i will wait till this product is finished :)
Running latest BETA on a Pi-3 | Toon® Thermostat (rooted) | Hue | Tuya | IKEA tradfri | Dashticz V3 on Lenovo Huawei Tablet | Conbee
stephanvdplas
Posts: 73
Joined: Wednesday 13 February 2019 18:09
Target OS: Windows
Domoticz version: 2023.1
Location: Netherlands
Contact:

Re: Logitech Media Server (LMS) dzVents adapter

Post by stephanvdplas »

Hello, I use the LMS DZVents adapter with much pleasure. I've only got a small feature request.

domoticz.devices(<name>).setvolume(<0<=x<=100) sets the volume of the LMS player.
Is it possible to expand this function with VolumeUp and VolumeDown?

In JSON, this is already possible: https://<serverFQDN>/json.htm?type=command&param=lmsmediacommand&idx=29&action=VolumeDown sets the volume of this specific LMS player 2 down.
- Running LMS, Domoticz and Dashticz on a windows 11 laptop.
- LMS (11 players) / Hue (26 lights, 2 switches) / Z-wave (14 devices) / Toon (unrooted) / Chromecast
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest