Home AMX User Forum NetLinx Studio

oppo BDP-103 power state listener


I am working with an oppo BDP-103 dvd player, and want monitor the power state of the device. Mostly, I use code as following:
DATA_EVENT[dvDVD]
{
    ONLINE :
    {
        send_command DATA.DEVICE, 'SET MODE DATA'
        send_command DATA.DEVICE, 'SET BAUD 9600,N,8,1,485 DISABLE'

        timeline_create(TL1, gTLPolling, LENGTH_ARRAY(gTLPolling),
            TIMELINE_ABSOLUTE, TIMELINE_REPEAT)
    }
    STRING :
    {
        local_var char buf[32]
        buf = DATA.TEXT
        select
        {
            active (find_string(buf, "@OK ON", 1)) : gblDVDPower = 1
            active (find_string(buf, "@OK OFF", 1)) : gblDVDPower = 0
        }
    }
}

TIMELINE_EVENT[TL1]
{
    switch(timeline.sequence)
    {
        case 1 : send_string dvDVD, "'#QPW',$0D"   // DVD POWER POLL STRING
    }
}

Then in the BUTTON_EVENT, when push on power button, do on or off action according to the current state 'gblGFPower'.

The problem now is reference to the rs232 manual of BDP-103, both operation command and query command get the same response.
for example, power on operation command is "#PON$0D", the response is '@OK ON$0D'; while power query command is "#QPW$0D", which also success with a same response string "@OK ON$0D".
So if I push the powerOn button, then the DATA_EVENT will get the "@OK ON" string immediately. That is to say, the monitor doesn't work now.
Any idea for doing with such a case?

Comments

  • viningvining Posts: 4,368
    Not sure I follow but I think you don't what to trigger TP feed back based on query return but rather a command response return.

    If so I would send FB when gblDVPower != newDVDPower and then make the latter = the former so it doesn't matter what iniated the responce or you could just track last command sent and ignore responses last command was a query but then why query in the 1st place.

    You could also track the FB sent to TPs and only send if sent != current value, maintain values in structs or array so you can update when TPs come on page.
  • f0ghuaf0ghua Posts: 16
    Thanks vining, actually, I want trigger the TP feedback based on query.
    I have added the following code to sync the TP power button state with the variable "gblDVDPower" like this:
    DEFINE_PROGRAM
    [dvTP, 40] = gblDVDPower
    
    When receive a response based on command, the device sometimes doesn't power done, so I the query seems better.
    My problem is I don't know how to distinguish the query response from command response.

    BTW, another problem is sometimes I mentioned that the command has sent to device, but no response back, looks like a retry mechanism is need. Does anybody has experience of such a issue? Any suggestion will be appreciated.
  • viningvining Posts: 4,368
    f0ghua wrote: »
    Thanks vining, actually, I want trigger the TP feedback based on query.
    I have added the following code to sync the TP power button state with the variable "gblDVDPower" like this:
    DEFINE_PROGRAM
    [dvTP, 40] = gblDVDPower
    
    When receive a response based on command, the device sometimes doesn't power done, so I the query seems better.
    My problem is I don't know how to distinguish the query response from command response.

    BTW, another problem is sometimes I mentioned that the command has sent to device, but no response back, looks like a retry mechanism is need. Does anybody has experience of such a issue? Any suggestion will be appreciated.
    Have you tried hitting the Oppo with a hammer? Since it should respond correctly, maybe update its firmware. Anyway for a quick fix just create another var and sent that var to the current command being sent, of course I always call it the cLastCMDSent or something similar. Now when you receive your response check your cLastCmdSent to see if there's a Q in the response, if so send TP feedback otherwise ignore.
    Personally I would figure out why there's a hiccup first and correct it if possible. I wrote an Oppo module some time ago and don't recall coming across this problem so maybe it's firmware related but I wouldn't rule out strange code behavior either.

    Also you should concatenate your buf var to just in case you don't get a complete response and then wait for the $0D delimiter before processing and remove up to that $0D to process. After thinking a bit about your code that may be your issue since you're not removing the contents of buf so it's still there during the next string event so which case is going to be correct? The 1st case since both strings may be in the buffer.

    Here's what I have, it may be confusing
    STRING:
          {
          LOCAL_VAR CHAR cOppo_Buf[LEN_MAX_TX_STR * DEV_QSIZE];
           
          //fnDEV_DeBug("'RX: "',DATA.TEXT,'" :DEBUG<',ITOA(__LINE__),'>'");
          cOppo_Buf = "cOppo_Buf,DATA.TEXT";
          
          CANCEL_WAIT 'CLEAR_BUFFER';
          WAIT 40 'CLEAR_BUFFER'
               {
               cOppo_Buf = '';
               }
               
          //set flag so we don't query power when we're RXing ddat
          sOppo.nRX_InLst_10s = 1;
          CANCEL_WAIT 'RX_IN_LST_10s';
          WAIT 100 'RX_IN_LST_10s'
               {
               sOppo.nRX_InLst_10s = 0;
               }
          
          WHILE(find_string(cOppo_Buf,"DEV_RX_END",1))
               {
               STACK_VAR INTEGER nFBS;
               STACK_VAR CHAR cTmpStr[LEN_MAX_TX_STR];
                              
               cTmpStr = REMOVE_STRING(cOppo_Buf,"DEV_RX_END",1);
               fnDEV_DeBug("'RX: [ ',cTmpStr,' ] :DEBUG<',ITOA(__LINE__),'>'");
               REMOVE_STRING(cTmpStr,"DEV_RX_START",1);
               
               if(length_string(cTmpStr) > 1)//NOT JUST THE ENDING
                {
                LOCAL_VAR _sRX sRX_Data;//make stack after tested
                STACK_VAR _sRX sRX_Zero;//remove after tested
                
                sRX_Data = sRX_Zero; //remove after tested
                
                //fnDEV_DeBug("'RX: [ ',cTmpStr,' ] :DEBUG<',ITOA(__LINE__),'>'");
                
                nFBS = find_string(cTmpStr,"' '",1);
                //fnDEV_DeBug("'RX: find_string "space" = [ ',itoa(nFBS),' ] :DEBUG<',ITOA(__LINE__),'>'");
                if(nFBS == 3)//not verbose
                 {
                 fnDEV_CTS();
                 sRX_Data.cCmd = sOppo.sQ[sOppo.nQSent].cCmd; //might need work/should match command sent
                 sRX_Data.cResult = GET_BUFFER_STRING(cTmpStr,nFBS-1);
                 REMOVE_STRING(cTmpStr,"' '",1);
                 nFBS = find_string(cTmpStr,"DEV_RX_END",1);
                 if(nFBS > 1)//we have a parameter
                      {
                      sRX_Data.cParam = GET_BUFFER_STRING(cTmpStr,nFBS-1);
                      fnDEV_Process_RX(sRX_Data,RX_VERBOSE_NOT);
                      }
                 else
                      {
                      fnDEV_DeBug("'RX ERR: No parameter found in non verbose response :DEBUG<',ITOA(__LINE__),'>'");
                      PULSE[vDEVcomm,CHNL_COMM_ERR];
                      }
                 }
                else if(nFBS == 4)
                 {
                 fnDEV_CTS();
                 sRX_Data.cCmd = GET_BUFFER_STRING(cTmpStr,nFBS-1);
                 REMOVE_STRING(cTmpStr,"' '",1);
                 if(sRX_Data.cCmd[1] == 'U')//unsolicited response
                      {
                      nFBS = find_string(cTmpStr,"DEV_RX_END",1);
                      if(nFBS > 1)
                       {
                       sRX_Data.cParam = GET_BUFFER_STRING(cTmpStr,nFBS-1);
                       fnDEV_Process_RX(sRX_Data,RX_VERBOSE_UNSOL);
                       }
                      else
                       {
                       fnDEV_DeBug("'RX ERR: No parameter found in unsolicited verbose response :DEBUG<',ITOA(__LINE__),'>'");
                       PULSE[vDEVcomm,CHNL_COMM_ERR];
                       }
                      }
                 else//command response
                      {
                      fnDEV_CTS();
                      nFBS = find_string(cTmpStr,"' '",1);
                      if(nFBS == 3)
                       {
                       sRX_Data.cResult = GET_BUFFER_STRING(cTmpStr,nFBS-1);
                       REMOVE_STRING(cTmpStr,"' '",1);
                       nFBS = find_string(cTmpStr,"DEV_RX_END",1);
                       if(nFBS > 1)
                        {
                        sRX_Data.cParam = GET_BUFFER_STRING(cTmpStr,nFBS-1);
                        fnDEV_Process_RX(sRX_Data,RX_VERBOSE_CMD);
                        }
                       else
                        {
                        fnDEV_Process_RX(sRX_Data,RX_VERBOSE_CMD);
                        //fnDEV_DeBug("'RX ERR: No parameter found in verbose cmd rx [ ',cTmpStr,' ] :DEBUG<',ITOA(__LINE__),'>'");
    //                    PULSE[vDEVcomm,CHNL_COMM_ERR];
                        }
                       }
                      else if(!nFBS)//if it ain't 3 or 0 F' it
                       {
                       nFBS = find_string(cTmpStr,"DEV_RX_END",1);
                       if(nFBS == 3)
                        {
                        sRX_Data.cResult = GET_BUFFER_STRING(cTmpStr,nFBS-1);
                        if(sRX_Data.cResult == 'OK')
                             {
                             fnDEV_Process_RX(sRX_Data,RX_VERBOSE_CMD);
                             }
                        else
                             {
                             fnDEV_DeBug("'RX ERR: Malformed command rx [ ',sRX_Data.cResult,' ] :DEBUG<',ITOA(__LINE__),'>'");
                             PULSE[vDEVcomm,CHNL_COMM_ERR];
                             }
                        }
                       }
                      else
                       {
                       fnDEV_DeBug("'RX ERR: Malformed command rx [ ',cTmpStr,' ] :DEBUG<',ITOA(__LINE__),'>'");
                       PULSE[vDEVcomm,CHNL_COMM_ERR];
                       }
                      }
                 }
                else
                 {
                 fnDEV_CTS(); // let timeout
                 fnDEV_DeBug("'RX ERR: Malformed command rx [ ',cTmpStr,' ] :DEBUG<',ITOA(__LINE__),'>'");
                 PULSE[vDEVcomm,CHNL_COMM_ERR];
                 }
                }
               else
                {
                fnDEV_CTS(); // let timeout
                fnDEV_DeBug("'RX Err No data in rx [ ',cTmpStr,' ] :DEBUG<',ITOA(__LINE__),'>'");
                PULSE[vDEVcomm,CHNL_COMM_ERR];
                }
               }
    
  • MLaletasMLaletas Posts: 226
    Im confused what does it matter whether you get the power on acknowledgment whether it was from the power on command or the power query? Either way you know the unit is on.
  • f0ghuaf0ghua Posts: 16
    Im confused what does it matter whether you get the power on acknowledgment whether it was from the power on command or the power query? Either way you know the unit is on.

    The reason is that the device sometimes doesn't power on even I get the power on acknowledgment, it maybe in a cooling state and so on. Only query reply can give me a certain state.
  • f0ghuaf0ghua Posts: 16
    vining wrote: »
    Have you tried hitting the Oppo with a hammer? Since it should respond correctly, maybe update its firmware. Anyway for a quick fix just create another var and sent that var to the current command being sent, of course I always call it the cLastCMDSent or something similar. Now when you receive your response check your cLastCmdSent to see if there's a Q in the response, if so send TP feedback otherwise ignore.
    Personally I would figure out why there's a hiccup first and correct it if possible. I wrote an Oppo module some time ago and don't recall coming across this problem so maybe it's firmware related but I wouldn't rule out strange code behavior either.

    Also you should concatenate your buf var to just in case you don't get a complete response and then wait for the $0D delimiter before processing and remove up to that $0D to process. After thinking a bit about your code that may be your issue since you're not removing the contents of buf so it's still there during the next string event so which case is going to be correct? The 1st case since both strings may be in the buffer.

    Here's what I have, it may be confusing

    Thanks vining, I will try with your solution.
  • MLaletasMLaletas Posts: 226
    f0ghua wrote: »

    The reason is that the device sometimes doesn't power on even I get the power on acknowledgment, it maybe in a cooling state and so on. Only query reply can give me a certain state.
    Oh ok understood, let us know what that works out.
  • sling100sling100 Posts: 123
    You need to change the verbose mode of the Oppo - if it responding with 'OK' and nothing else then it is in mode 1. Try changing it to 2 or 3 - you will get loads more info back. SVM is the command you need I think.

    Simon
  • f0ghuaf0ghua Posts: 16
    sling100 wrote: »
    You need to change the verbose mode of the Oppo - if it responding with 'OK' and nothing else then it is in mode 1. Try changing it to 2 or 3 - you will get loads more info back. SVM is the command you need I think.

    Simon

    Thanks Simon, it's the right solution.
Sign In or Register to comment.