Implementation help #1

Closed
opened 2020-02-02 16:07:17 +00:00 by scolex71 · 22 comments
scolex71 commented 2020-02-02 16:07:17 +00:00 (Migrated from github.com)

How are you implementing this app?
I am a complete noob to github/programming and was expecting this to have some sort of GUI where you would click buttons and/or enter text instead of a cmd window.
I have an app (Rainmeter) I can create a GUI with to pass commands to the app but need some direction as to how the commands need to be structured.

How are you implementing this app? I am a complete noob to github/programming and was expecting this to have some sort of GUI where you would click buttons and/or enter text instead of a cmd window. I have an app (Rainmeter) I can create a GUI with to pass commands to the app but need some direction as to how the commands need to be structured.
FrankvdStam commented 2020-02-02 16:11:22 +00:00 (Migrated from github.com)

Hi,

As of right now there is no app, it's a library. The console app just demonstrates how to use it. Can rainmeter start a process with parameters? Like "denonapi.exe 192.168.xx.xx:8080 setvolume 80"?

Hi, As of right now there is no app, it's a library. The console app just demonstrates how to use it. Can rainmeter start a process with parameters? Like "denonapi.exe 192.168.xx.xx:8080 setvolume 80"?
scolex71 commented 2020-02-02 16:22:32 +00:00 (Migrated from github.com)

Yes, below is a simple/incomplete example of a skin.

[Rainmeter]
; This section contains general settings that can be used to change how Rainmeter behaves.
Author=poiru (mod by meilon)
AppVersion=2003000
Update=1000
Background=#@#Background.png
; #@# is equal to Rainmeter\Skins\illustro@Resources
BackgroundMode=3
BackgroundMargins=0,34,0,14

[Metadata]
; Contains basic information of the skin.
Description=Displays the current date and time.
License=Creative Commons BY-NC-SA 3.0
Version=1.0.0

[Variables]
; Variables declared here can be used later on between two # characters (e.g. #MyVariable#).
fontName=Trebuchet MS
textSize=8
colorBar=235,170,0,255
colorText=255,255,255,205
WEBPOST=C:*somelocation\DenonService.exe

[cmdVolUp]
Meter=String
MeterStyle=styleLeftText
X=10
Y=40
W=50
H=18
LeftMouseUpAction=!Execute ["#WEBPOST#" "MasterVolumeUp"]
MouseActionCursor=1
Antialias=1
Text=VolUp

[cmdVolDown]
Meter=String
MeterStyle=styleLeftText
X=60
Y=40
W=50
H=18
LeftMouseUpAction=!Execute ["#WEBPOST#" "MasterVolumeDown"]
MouseActionCursor=1
Antialias=1
Text=VolDown

Yes, below is a simple/incomplete example of a skin. [Rainmeter] ; This section contains general settings that can be used to change how Rainmeter behaves. Author=poiru (mod by meilon) AppVersion=2003000 Update=1000 Background=#@#Background.png ; #@# is equal to Rainmeter\Skins\illustro\@Resources BackgroundMode=3 BackgroundMargins=0,34,0,14 [Metadata] ; Contains basic information of the skin. Description=Displays the current date and time. License=Creative Commons BY-NC-SA 3.0 Version=1.0.0 [Variables] ; Variables declared here can be used later on between two # characters (e.g. #MyVariable#). fontName=Trebuchet MS textSize=8 colorBar=235,170,0,255 colorText=255,255,255,205 WEBPOST=C:\*somelocation\DenonService.exe [cmdVolUp] Meter=String MeterStyle=styleLeftText X=10 Y=40 W=50 H=18 LeftMouseUpAction=!Execute ["#WEBPOST#" "MasterVolumeUp"] MouseActionCursor=1 Antialias=1 Text=VolUp [cmdVolDown] Meter=String MeterStyle=styleLeftText X=60 Y=40 W=50 H=18 LeftMouseUpAction=!Execute ["#WEBPOST#" "MasterVolumeDown"] MouseActionCursor=1 Antialias=1 Text=VolDown
scolex71 commented 2020-02-02 16:39:47 +00:00 (Migrated from github.com)

In the above example #WEBPOST# (defined in variables) is the exe that RM would pass the MasterVolumeUp command to.
I saw that the IP is defined in the DenonAPI code so I did not enter that in variables but it could be implemented

In the above example #WEBPOST# (defined in variables) is the exe that RM would pass the MasterVolumeUp command to. I saw that the IP is defined in the DenonAPI code so I did not enter that in variables but it could be implemented
FrankvdStam commented 2020-02-02 18:11:31 +00:00 (Migrated from github.com)

I could create a simple .exe for you that you could call from rainmeter.

I could create a simple .exe for you that you could call from rainmeter.
scolex71 commented 2020-02-02 18:19:33 +00:00 (Migrated from github.com)

That would be awesome and greatly appreciated.
On a side note you might find Rainmeter interesting.
Little snippet from their site:
Rainmeter allows you to display customizable skins on your desktop, from hardware usage meters to fully functional audio visualizers. You are only limited by your imagination and creativity.
https://www.rainmeter.net/

**That would be awesome and greatly appreciated**. On a side note you might find Rainmeter interesting. Little snippet from their site: Rainmeter allows you to display customizable skins on your desktop, from hardware usage meters to fully functional audio visualizers. You are only limited by your imagination and creativity. [https://www.rainmeter.net/](url)
FrankvdStam commented 2020-02-02 18:33:10 +00:00 (Migrated from github.com)

I'm actually familiar with rainmeter, just not it's technical details. :)

Take a look at this: https://github.com/FrankvdStam/DenonApi/blob/master/docs/IP_Protocol_AVR-Xx100.pdf

Easiest implementation for this would be to just use that api directly. No need to redefine everything. I can setup a tcp connection to the given ip:port (1st parameter) and than just forward the command (2nd parameter). We can force the use of quotes there to make parsing easier.

For example:
denonapi.exe 192.168.1.65:23 "PWON"

We can drop the newline, the program will insert a newline on every command. It will wait about a second, if a response is given, write to standard out. I'm sure rainmeter can handle that.

I can also make it display exactly what it's writing to the given ip, to make it easier to debug. You'll be able to use it from cmd and see the output.

Would that work?

I'm actually familiar with rainmeter, just not it's technical details. :) Take a look at this: https://github.com/FrankvdStam/DenonApi/blob/master/docs/IP_Protocol_AVR-Xx100.pdf Easiest implementation for this would be to just use that api directly. No need to redefine everything. I can setup a tcp connection to the given ip:port (1st parameter) and than just forward the command (2nd parameter). We can force the use of quotes there to make parsing easier. For example: denonapi.exe 192.168.1.65:23 "PWON" We can drop the newline, the program will insert a newline on every command. It will wait about a second, if a response is given, write to standard out. I'm sure rainmeter can handle that. I can also make it display exactly what it's writing to the given ip, to make it easier to debug. You'll be able to use it from cmd and see the output. Would that work?
scolex71 commented 2020-02-02 19:26:53 +00:00 (Migrated from github.com)

I'll take your word for it that it will work, you are the expert here.
I have a copy of the control protocol in excel.

I'll take your word for it that it will work, you are the expert here. I have a copy of the control protocol in excel.
FrankvdStam commented 2020-02-02 19:34:19 +00:00 (Migrated from github.com)

Can you build from source or do you need me to provide an exe? (I'd recommend you building from source, I'm not a trustworthy source for executables)

Can you build from source or do you need me to provide an exe? (I'd recommend you building from source, I'm not a trustworthy source for executables)
scolex71 commented 2020-02-02 19:35:26 +00:00 (Migrated from github.com)

I have Visual Studio 2019 so yes

I have Visual Studio 2019 so yes
FrankvdStam commented 2020-02-02 19:57:26 +00:00 (Migrated from github.com)

Checkout TcpForward on master, build it and run it from cmd. I split the IP and port up so 1st param is ip, 2nd param is port, 3rd is command. Example usage:

C:\projects\DenonApi\src\TcpForward\bin\Debug\netcoreapp3.0>tcpforward.exe 192.168.1.65 23 PWON
Parsed input as ip: 192.168.1.65, port: 23 amd command: PWON

C:\projects\DenonApi\src\TcpForward\bin\Debug\netcoreapp3.0>tcpforward.exe 192.168.1.65 23 MVUP
Parsed input as ip: 192.168.1.65, port: 23 amd command: MVUP
Checkout TcpForward on master, build it and run it from cmd. I split the IP and port up so 1st param is ip, 2nd param is port, 3rd is command. Example usage: ``` C:\projects\DenonApi\src\TcpForward\bin\Debug\netcoreapp3.0>tcpforward.exe 192.168.1.65 23 PWON Parsed input as ip: 192.168.1.65, port: 23 amd command: PWON C:\projects\DenonApi\src\TcpForward\bin\Debug\netcoreapp3.0>tcpforward.exe 192.168.1.65 23 MVUP Parsed input as ip: 192.168.1.65, port: 23 amd command: MVUP ```
scolex71 commented 2020-02-02 19:57:59 +00:00 (Migrated from github.com)

Could you easily implement a function to write and overwrite AVR responses to a text file that I could parse and use as a status repeater. My AVR is not visible and I would like to show things like current volume, input, Tuner freq, etc.
I can add the commands just not sure how to have the responses written to an external file.

Could you easily implement a function to write and overwrite AVR responses to a text file that I could parse and use as a status repeater. My AVR is not visible and I would like to show things like current volume, input, Tuner freq, etc. I can add the commands just not sure how to have the responses written to an external file.
FrankvdStam commented 2020-02-02 20:00:18 +00:00 (Migrated from github.com)

Tested on my X1500H.

Responses are a bit weird in this case - the program really doesn't know what the commands mean and it's just forwarding whatever you give it over tcp. Some commands don't have a response - how long should the program wait for a response? I could add a fourth parameter where you tell it to wait for a response or to ignore any response.

The library only waits for a response if the command has one. Don't really feel like rewriting the library or a command parser for this.

Tested on my X1500H. Responses are a bit weird in this case - the program really doesn't know what the commands mean and it's just forwarding whatever you give it over tcp. Some commands don't have a response - how long should the program wait for a response? I could add a fourth parameter where you tell it to wait for a response or to ignore any response. The library only waits for a response if the command has one. Don't really feel like rewriting the library or a command parser for this.
scolex71 commented 2020-02-02 20:11:26 +00:00 (Migrated from github.com)

I will see if I can figure it out, there are several commands that are only there to ask a question.
example:
MV? returns current Master Volume level
Thank you for your work

I will see if I can figure it out, there are several commands that are only there to ask a question. example: MV? returns current Master Volume level Thank you for your work
FrankvdStam commented 2020-02-02 20:21:33 +00:00 (Migrated from github.com)

You can ask it with w to wait for a response, or give it a filepath to write to (it does not handle filemanagement for you - if the file or path doesn't exist, it will just skip writing the file.)

C:\projects\DenonApi\src\TcpForward\bin\Debug\netcoreapp3.0>tcpforward.exe 192.168.1.65 23 MV? w
Parsed input as ip: 192.168.1.65, port: 23, command: MV?, wait for response: True, write to file: no file
MVMAX 91: MV565

Also updated the readme with more info.

Here is some info (you probably know more about this than I) of parsing this output. https://docs.rainmeter.net/manual/plugins/runcommand/

You can seperate the response from the AVR device by splitting on the newline character (\n) - everything after the first newline should be AVR response. I'm not sure what happens if you wait for a response if there is none...

No problem, I hope this works out for you.

You can ask it with w to wait for a response, or give it a filepath to write to (it does not handle filemanagement for you - if the file or path doesn't exist, it will just skip writing the file.) ``` C:\projects\DenonApi\src\TcpForward\bin\Debug\netcoreapp3.0>tcpforward.exe 192.168.1.65 23 MV? w Parsed input as ip: 192.168.1.65, port: 23, command: MV?, wait for response: True, write to file: no file MVMAX 91: MV565 ``` Also updated the readme with more info. Here is some info (you probably know more about this than I) of parsing this output. https://docs.rainmeter.net/manual/plugins/runcommand/ You can seperate the response from the AVR device by splitting on the newline character (\n) - everything after the first newline should be AVR response. I'm not sure what happens if you wait for a response if there is none... No problem, I hope this works out for you.
scolex71 commented 2020-02-02 20:59:24 +00:00 (Migrated from github.com)

Works perfectly thank you.
Only hiccup is if I move the exe and dll to a more convenient location (D:\Rainmeter) it get this:
D:\Rainmeter>TcpForward.exe 192.168.1.10 23 MVUP
A fatal error was encountered. The library 'hostpolicy.dll' required to execute the application was not found in 'C:\Program Files\dotnet'.

Works perfectly thank you. Only hiccup is if I move the exe and dll to a more convenient location (D:\Rainmeter) it get this: D:\Rainmeter>TcpForward.exe 192.168.1.10 23 MVUP A fatal error was encountered. The library 'hostpolicy.dll' required to execute the application was not found in 'C:\Program Files\dotnet'.
FrankvdStam commented 2020-02-02 21:04:35 +00:00 (Migrated from github.com)

Are you copying all the files in the build directory? Looks like you mightve skipped some config files. Maybe this helps: https://stackoverflow.com/questions/38085430/the-library-hostpolicy-dll-was-not-found

Are you copying all the files in the build directory? Looks like you mightve skipped some config files. Maybe this helps: https://stackoverflow.com/questions/38085430/the-library-hostpolicy-dll-was-not-found
scolex71 commented 2020-02-02 21:25:03 +00:00 (Migrated from github.com)

I changed the output folder and that fixed it, like I stated before I am as green as grass when it comes to VS

I changed the output folder and that fixed it, like I stated before I am as green as grass when it comes to VS
FrankvdStam commented 2020-02-02 21:46:52 +00:00 (Migrated from github.com)

Alright, closing this for now but feel free to ask for help later.

Alright, closing this for now but feel free to ask for help later.
scolex71 commented 2020-02-11 06:02:49 +00:00 (Migrated from github.com)

I was wondering if you could help me with something that I can't wrap my head around.
I am using a modified version of TcpForward where I have added a couple of additional read/write operations and would like to manipulate the server return message before sending a new command.
The gist of it is I request current Master Volume (MV?) in preparation to send a Direct MV command I would like to split and store the returned value in 2 variables and then add or subtract a value before sending a new command to the server.
Example:
client message = MV?
server response = MV30
split MV30 into
command=MV, parameter=30
then write a console line that is command + (parameter +- (x)).
Lets assume x=2 then my command back to the server would be either MV28 or MV32 depending on whether I am looking to increase or decrease the volume by 2.
I know I am going to have to differentiate between MVUP and MVDOWN in some manor but I think I can figure that out or at least hope so as I find most of this quite counterintuitive.

I only want to accomplish this because in/decreasing volume .5db at a time is a pita.

My current code is attached, I added the + test + to the write to make sure the read/split operation was working as expected.

current program.cs is attached as a .txt
Program.cs.txt

TIA

I was wondering if you could help me with something that I can't wrap my head around. I am using a modified version of TcpForward where I have added a couple of additional read/write operations and would like to manipulate the server return message before sending a new command. The gist of it is I request current Master Volume (MV?) in preparation to send a Direct MV command I would like to split and store the returned value in 2 variables and then add or subtract a value before sending a new command to the server. Example: client message = MV? server response = MV30 split MV30 into command=MV, parameter=30 then write a console line that is command + (parameter +- (x)). Lets assume x=2 then my command back to the server would be either MV28 or MV32 depending on whether I am looking to increase or decrease the volume by 2. I know I am going to have to differentiate between MVUP and MVDOWN in some manor but I think I can figure that out or at least hope so as I find most of this quite counterintuitive. I only want to accomplish this because in/decreasing volume .5db at a time is a pita. My current code is attached, I added the + test + to the write to make sure the read/split operation was working as expected. current program.cs is attached as a .txt [Program.cs.txt](https://github.com/FrankvdStam/DenonApi/files/4184190/Program.cs.txt) ### TIA
FrankvdStam commented 2020-02-11 09:15:58 +00:00 (Migrated from github.com)

Well, this is what the library is meant for.

    IDenonDevice denonDevice = new TcpDenonDevice("192.168.1.65", 23);
    var masterVolume = denonDevice.GetMasterVolume();
    masterVolume += 2;
    denonDevice.SetMasterVolume(masterVolume);

If you do something like denonDevice.SetMasterVolume(50.2); - it will automatically round to the nearest half decimal.

The thing is, you don't want to make a command line program that does all the parsing, the library already does the parsing.

If you look at the implementation of GetMasterVolume() you see it returns VolumeStringToDecimal. This method takes a string in denon "volume string" format, examples are CVFL 50\r (in which case you want to get 50) or CVFL 745\r -> (in which case you want 74.5, since the 5 is half a decibel).

Are you only ever going to automate the master volume? Because if that's the case I suggest you start using the library instead of using tcp directly. Then you can just use GetMasterVolume(), no need to do any string manipulation.

Well, this is what the library is meant for. ``` IDenonDevice denonDevice = new TcpDenonDevice("192.168.1.65", 23); var masterVolume = denonDevice.GetMasterVolume(); masterVolume += 2; denonDevice.SetMasterVolume(masterVolume); ``` If you do something like `denonDevice.SetMasterVolume(50.2);` - it will automatically round to the nearest half decimal. The thing is, you don't want to make a command line program that does all the parsing, the library already does the parsing. If you look at the implementation of `GetMasterVolume()` you see it returns `VolumeStringToDecimal`. This method takes a string in denon "volume string" format, examples are CVFL 50\r (in which case you want to get 50) or CVFL 745\r -> (in which case you want 74.5, since the 5 is half a decibel). Are you only ever going to automate the master volume? Because if that's the case I suggest you start using the library instead of using tcp directly. Then you can just use `GetMasterVolume()`, no need to do any string manipulation.
scolex71 commented 2020-02-11 17:48:07 +00:00 (Migrated from github.com)

I would love to use the library but not sure how, looks like I have some reading to do.
Thank you for your input.

I would love to use the library but not sure how, looks like I have some reading to do. Thank you for your input.
FrankvdStam commented 2020-02-12 07:06:55 +00:00 (Migrated from github.com)

You can use NuGet to include the library - in visual studio, right click on a project, click "manage nuget packages" - find the project and click install. NuGet is what is called a package manager, many programming languages/ide's have a package manager. You can use it to install packages (no shit) that the community or big companies make. After installing the package, you can bring the namespace of the package into scope with a using statement, then use the classes in the package.

If you can't figure this out, you can also copy and paste all methods you need from the GetMasterVolume() method. You can then check if the input is MV? -> if yes use the method, if now continue as normal.

You can use NuGet to include the library - in visual studio, right click on a project, click "manage nuget packages" - find the project and click install. NuGet is what is called a package manager, many programming languages/ide's have a package manager. You can use it to install packages (no shit) that the community or big companies make. After installing the package, you can bring the namespace of the package into scope with a using statement, then use the classes in the package. If you can't figure this out, you can also copy and paste all methods you need from the `GetMasterVolume()` method. You can then check if the input is MV? -> if yes use the method, if now continue as normal.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
FrankvdStam/DenonApi#1
No description provided.