Skip to content

Commit 927ba00

Browse files
authored
Merge pull request #2230 from Reivax851/development
New correction in Multibloc management
2 parents 6eabdd7 + f1dbb21 commit 927ba00

File tree

2 files changed

+148
-99
lines changed

2 files changed

+148
-99
lines changed

hardware/USBtin_MultiblocV8.cpp

Lines changed: 147 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ History :
112112
#define type_SFSP_CAPTEUR_1BS 514
113113
#define type_SFSP_CAPTEUR_4BS 515
114114
#define type_SFSP_SYNCHRO 516
115-
116115
#define type_SFSP_LearnCommand 517
117116

118117
#define BLOC_NORMAL_STATES 0x00
@@ -129,6 +128,7 @@ History :
129128

130129
#define BLOC_DOMOTICZ 0x01
131130

131+
#define BLOC_9 0x0D
132132
#define BLOC_SFSP_M 0x14
133133
#define BLOC_SFSP_E 0x15
134134

@@ -310,7 +310,12 @@ void USBtin_MultiblocV8::Traitement_MultiblocV8(int IDhexNumber,unsigned int rxD
310310
//_log.Log(LOG_NORM,"MultiblocV8: Life Frame, ref: %#x Codage : %d Network: %d",RefBloc,Codage,SsReseau);
311311
Traitement_Trame_Vie(RefBloc,Codage,SsReseau,rxDLC,Buffer_Octets);
312312
break;
313-
313+
314+
case type_ETAT_BLOC:
315+
//traitement ETAT BLOC reçu :
316+
Traitement_Trame_EtatBloc(RefBloc,Codage,SsReseau,rxDLC,Buffer_Octets);
317+
break;
318+
314319
case type_STATE_S_TOR_1_TO_2 :
315320
case type_STATE_S_TOR_3_TO_4 :
316321
case type_STATE_S_TOR_5_TO_6 :
@@ -443,15 +448,23 @@ void USBtin_MultiblocV8::BlocList_GetInfo(const unsigned char RefBloc, const ch
443448

444449
std::string defaultname = NomRefBloc[RefBloc].c_str();
445450
std::string defaultnamenormal = defaultname + " LEARN EXIT";
446-
std::string defaultnamelearn = defaultname + " LEARN";
447-
std::string defaultnameclear = defaultname + " CLEAR";
451+
std::string defaultnamelearn = defaultname + " LEARN ENTRY";
452+
std::string defaultnameclear = defaultname + " CLEAR ALL";
453+
std::string defaultnamenextlearning = defaultname + " NEXT LEARNING OUTPUT";
448454

449-
sID += (type_COMMANDE_ETAT_BLOC<<SHIFT_TYPE_TRAME);
455+
unsigned long sID_CommandBase = sID + (type_COMMANDE_ETAT_BLOC<<SHIFT_TYPE_TRAME);
456+
InsertUpdateControlSwitch(sID_CommandBase, BLOC_STATES_LEARNING_STOP, defaultnamenormal.c_str() );
457+
InsertUpdateControlSwitch(sID_CommandBase, BLOC_STATES_LEARNING, defaultnamelearn.c_str() );
458+
InsertUpdateControlSwitch(sID_CommandBase, BLOC_STATES_CLEARING, defaultnameclear.c_str() );
450459

451-
InsertUpdateControlSwitch(sID, BLOC_STATES_LEARNING_STOP, defaultnamenormal.c_str() );
452-
InsertUpdateControlSwitch(sID, BLOC_STATES_LEARNING, defaultnamelearn.c_str() );
453-
InsertUpdateControlSwitch(sID, BLOC_STATES_CLEARING, defaultnameclear.c_str() );
454-
460+
//not necessary : because the CommandBase LEARN ENTRY handles both the entry in Learn Mode
461+
//and after that, the jump from first to seconde output to learn, etc... and Go out automatically at end
462+
//so need to cretes the switch to jump in learn mode !
463+
//unsigned long sID_SFSPCommandBase = sID + (type_SFSP_LearnCommand<<SHIFT_TYPE_TRAME);
464+
//InsertUpdateControlSwitch(sID_SFSPCommandBase, 0, defaultnamenextlearning.c_str() );
465+
466+
sID = type_COMMANDE_ETAT_BLOC<<SHIFT_TYPE_TRAME; //creates a unique Reset Switch to restart all presents blocks
467+
InsertUpdateControlSwitch(sID, BLOC_STATES_RESET, "RESET ALL MULTIBLOC V8 Blocks" );
455468
break;
456469
}
457470
break;
@@ -482,6 +495,10 @@ void USBtin_MultiblocV8::InsertUpdateControlSwitch(const int NodeID, const int C
482495
"VALUES (%d,'%q',%d,%d,%d,%d,0, 12,255,'%q',0,' ')",
483496
m_HwdID, szIdx, ChildID, pTypeLighting2, sTypeAC, int(STYPE_PushOn), defaultname.c_str() );
484497
}
498+
else{ //sinon on remet à 0 les état ici
499+
m_sql.safe_query("UPDATE DeviceStatus SET nValue=%d WHERE (HardwareID==%d) AND (DeviceID=='%q') AND (Type==%d) AND (Subtype==%d) AND (Unit==%d)",
500+
0, m_HwdID, szIdx,pTypeLighting2,sTypeAC, ChildID);
501+
}
485502
}
486503

487504
//call every 3 sec...
@@ -539,19 +556,62 @@ void USBtin_MultiblocV8::Traitement_Trame_Vie(const unsigned char RefBloc, const
539556
if( rxDLC == 5 ) BlocList_GetInfo(RefBloc,Codage,Ssreseau,bufferdata);
540557
}
541558

559+
//Traitement trame Etat_Bloc / States_Bloc frame treatement :
560+
void USBtin_MultiblocV8::Traitement_Trame_EtatBloc(const unsigned char RefBloc, const char Codage, const char Ssreseau,unsigned int rxDLC,unsigned int bufferdata[8])
561+
{
562+
int i = 0;
563+
int Command = 0;
564+
char szDeviceID[10];
565+
std::vector<std::vector<std::string> > result;
566+
//for searching the good commands switches :
567+
unsigned long sID=(type_COMMANDE_ETAT_BLOC<<SHIFT_TYPE_TRAME)+(RefBloc<<SHIFT_INDEX_MODULE)+(Codage<<SHIFT_CODAGE_MODULE)+Ssreseau;
568+
sprintf(szDeviceID,"%07X",(unsigned int)sID);
569+
if( rxDLC == 1 ){
570+
_log.Log(LOG_NORM,"MultiblocV8: Check Etat Bloc with hardwarId: %d and id: %s receive: %d",m_HwdID,szDeviceID, bufferdata[0] );
571+
//search the 3 switches (LEARN ENTRY / EXIT and CLEAR) associates to this return EtatBloc frame
572+
//in fact we can return each switch to it's normal states after a good sequence !
573+
if( bufferdata[0] == BLOC_NORMAL_STATES ){ //retour en mode normal / return in normal mode
574+
for(i = 0;i < (BLOC_STATES_CLEARING+1); i++){
575+
result = m_sql.safe_query("UPDATE DeviceStatus SET nValue=%d WHERE (HardwareID==%d) AND (DeviceID=='%q') AND (Type==%d) AND (Subtype==%d) AND (Unit==%d)",
576+
0, m_HwdID, szDeviceID,pTypeLighting2,sTypeAC, i);
577+
/*result = m_sql.safe_query("SELECT ID,nValue,sValue FROM DeviceStatus WHERE (HardwareID==%d) AND (DeviceID=='%q') AND (Type==%d) AND (Subtype==%d) AND (Unit==%d)",
578+
m_HwdID, szDeviceID,pTypeLighting2,sTypeAC, i);
579+
//if(!result.empty() ){ //if command exist in db :
580+
//Refresh it !
581+
tRBUF lcmd;
582+
memset(&lcmd, 0, sizeof(RBUF));
583+
lcmd.LIGHTING2.packetlength = sizeof(lcmd.LIGHTING2) - 1;
584+
lcmd.LIGHTING2.packettype = pTypeLighting2;
585+
lcmd.LIGHTING2.subtype = sTypeAC;
586+
lcmd.LIGHTING2.id1 = (sID>>24)&0xff;
587+
lcmd.LIGHTING2.id2 = (sID>>16)&0xff;
588+
lcmd.LIGHTING2.id3 = (sID>>8)&0xff;
589+
lcmd.LIGHTING2.id4 = sID&0xff;
590+
lcmd.LIGHTING2.cmnd = light2_sOff; //Off !
591+
lcmd.LIGHTING2.unitcode = i; //SubUnit = command index
592+
lcmd.LIGHTING2.level = 0; //level_value;
593+
lcmd.LIGHTING2.filler = 2;
594+
lcmd.LIGHTING2.rssi = 12;
595+
sDecodeRXMessage(this, (const unsigned char *)&lcmd.LIGHTING2, NULL, 255);
596+
597+
}*/
598+
}
599+
}
600+
601+
}
602+
}
542603
//check if an output has changed...
543604

544605
bool USBtin_MultiblocV8::CheckOutputChange(unsigned long sID,int OutputNumber,bool CdeReceive,int LevelReceive){
545-
546606
char szDeviceID[10];
547607
int i;
548608
bool returnvalue = true;
549-
sprintf(szDeviceID,"%07X",(unsigned int)sID);
550609
std::vector<std::vector<std::string> > result;
551610
bool ForceUpdate = false;
552-
611+
int slevel = 0;
612+
int nvalue = 0;
553613
unsigned long StoreIdToFind = sID &(MSK_INDEX_MODULE+MSK_CODAGE_MODULE+MSK_SRES_MODULE);
554-
//serching for the bloc :
614+
//serching for the bloc in bloclist :
555615
for(i = 0;i < MAX_NUMBER_BLOC;i++){
556616
if( m_BlocList_CAN[i].BlocID == StoreIdToFind ){
557617
//bloc trouvé on vérifie si on doit forcer l'update ou non des composants associés :
@@ -561,23 +621,46 @@ bool USBtin_MultiblocV8::CheckOutputChange(unsigned long sID,int OutputNumber,bo
561621
break;
562622
}
563623
}
624+
unsigned long IdFordbSearch = StoreIdToFind;
625+
unsigned int outputindex = OutputNumber-1; //because OutputNumber is the real out number
626+
//but we start to 0 for the management !
627+
switch(outputindex){
628+
case 0 :case 1 : IdFordbSearch += (type_STATE_S_TOR_1_TO_2<<SHIFT_TYPE_TRAME); break;
629+
case 2 :case 3 : IdFordbSearch += (type_STATE_S_TOR_3_TO_4<<SHIFT_TYPE_TRAME); break;
630+
case 4 :case 5 : IdFordbSearch += (type_STATE_S_TOR_5_TO_6<<SHIFT_TYPE_TRAME); break;
631+
case 6 :case 7 : IdFordbSearch += (type_STATE_S_TOR_7_TO_8<<SHIFT_TYPE_TRAME); break;
632+
case 8 :case 9 : IdFordbSearch += (type_STATE_S_TOR_9_TO_10<<SHIFT_TYPE_TRAME); break;
633+
case 10 :case 11 : IdFordbSearch += (type_STATE_S_TOR_11_TO_12<<SHIFT_TYPE_TRAME); break;
634+
}
564635

565-
566-
result = m_sql.safe_query("SELECT ID,nValue,sValue FROM DeviceStatus WHERE (HardwareID==%d) AND (DeviceID=='%q') AND (Type==%d) AND (Subtype==%d==%d) AND (Unit==%d)",
636+
sprintf(szDeviceID,"%07X",(unsigned int)IdFordbSearch);
637+
//_log.Log(LOG_NORM,"MultiblocV8: Check states for output: %d with hardwarId: %d and id: %s ",OutputNumber,m_HwdID,szDeviceID);
638+
result = m_sql.safe_query("SELECT ID,nValue,sValue FROM DeviceStatus WHERE (HardwareID==%d) AND (DeviceID=='%q') AND (Type==%d) AND (Subtype==%d) AND (Unit==%d)",
567639
m_HwdID, szDeviceID,pTypeLighting2,sTypeAC, OutputNumber); //Unit = 1 = sortie n°1
568-
if(!result.empty() && !ForceUpdate ){ //if output exist in db and no forceupdate
569-
//check if we have a change, if not do not update it
570-
int nvalue = atoi(result[0][1].c_str());
571-
//_log.Log(LOG_NORM,"MultiblocV8: Output 1 nvalue : %d ",nvalue);
572-
if ( (!CdeReceive) && (nvalue == 0) ) returnvalue = false; //still off, nothing to do
573-
else{
574-
//Check Level changed
575-
int slevel = atoi(result[0][2].c_str());
576-
//_log.Log(LOG_NORM,"MultiblocV8: Output 1 slevel : %d ",slevel);
577-
if( (slevel == LevelReceive) ) returnvalue = false;
640+
if(!result.empty() ){ //if output exist in db and no forceupdate
641+
if( !ForceUpdate ){
642+
//check if we have a change, if not do not update it
643+
nvalue = atoi(result[0][1].c_str());
644+
slevel = atoi(result[0][2].c_str());
645+
//_log.Log(LOG_NORM,"MultiblocV8: Output 1 nvalue : %d ",nvalue);
646+
if ( (!CdeReceive) && (nvalue == 0) ) returnvalue = false; //still off, nothing to do
647+
else{
648+
//Check Level changed
649+
//_log.Log(LOG_NORM,"MultiblocV8: Output 1 slevel : %d ",slevel);
650+
//level check only if cde and states = 1
651+
if( CdeReceive && (nvalue > 0) ){
652+
if( (slevel == LevelReceive) ) returnvalue = false;
653+
}
654+
}
578655
}
656+
/*else{
657+
_log.Log(LOG_NORM,"MultiblocV8: ForceUpdate is active for this output, we are maybe just started system !?");
658+
}*/
579659
}
580-
660+
else{
661+
_log.Log(LOG_ERROR,"MultiblocV8: No output find in db");
662+
}
663+
//_log.Log(LOG_NORM,"MultiblocV8: Check states Output: %d Actual States/Lvl: %d / %d Compare to: %d / %d Update?: %d",OutputNumber,CdeReceive,LevelReceive,nvalue,slevel,returnvalue);
581664
return returnvalue;
582665
}
583666

@@ -617,56 +700,6 @@ void USBtin_MultiblocV8::OutputNewStates(unsigned long sID,int OutputNumber,bool
617700
sDecodeRXMessage(this, (const unsigned char *)&lcmd.LIGHTING2, defaultname.c_str(), 255);
618701
}
619702

620-
void USBtin_MultiblocV8::DoBlinkOutput(){
621-
//every one second, check if an output is On and in blink Mode
622-
int i = 0;
623-
int output_index = 0;
624-
int RefBlocAlive = 0;
625-
unsigned long sID = 0;
626-
627-
m_BOOL_GlobalBlinkOutputs = !m_BOOL_GlobalBlinkOutputs;
628-
//serching for blocks :
629-
for(i = 0;i < MAX_NUMBER_BLOC;i++){
630-
if( m_BlocList_CAN[i].BlocID != 0 ){ //if bloc is logged
631-
//we extract the blocs reference :
632-
RefBlocAlive = (( m_BlocList_CAN[i].BlocID & MSK_INDEX_MODULE) >> SHIFT_INDEX_MODULE);
633-
if( m_BlocList_CAN[i].Status == BLOC_ALIVE ){ //only if block is alive
634-
switch(RefBlocAlive){ //Switch because the Number of output can be different for over ref blocks !
635-
case BLOC_SFSP_M :
636-
case BLOC_SFSP_E :
637-
//6 outputs on sfsp blocks
638-
for(output_index = 1;output_index < 7;output_index ++){
639-
if( m_BlocList_CAN[i].IsOutputBlink[output_index] == true ){
640-
_log.Log(LOG_NORM,"MultiblocV8: Output n: %d blink state %d",output_index,m_BOOL_GlobalBlinkOutputs);
641-
if(output_index == 1 || output_index==2 ){
642-
sID = (type_STATE_S_TOR_1_TO_2<<SHIFT_TYPE_TRAME)+ m_BlocList_CAN[i].BlocID;
643-
//if Blink mode is on:
644-
//simulate a change only in domoticz, no sending frame for that !
645-
OutputNewStates( sID, output_index,m_BOOL_GlobalBlinkOutputs,15 );
646-
}
647-
else if(output_index == 3 || output_index==4 ){
648-
sID = (type_STATE_S_TOR_3_TO_4<<SHIFT_TYPE_TRAME)+ m_BlocList_CAN[i].BlocID;
649-
//if Blink mode is on:
650-
//simulate a change only in domoticz, no sending frame for that !
651-
OutputNewStates( sID, output_index,m_BOOL_GlobalBlinkOutputs,15 );
652-
}
653-
else if(output_index == 5 || output_index==6 ){
654-
sID = (type_STATE_S_TOR_5_TO_6<<SHIFT_TYPE_TRAME)+ m_BlocList_CAN[i].BlocID;
655-
//if Blink mode is on:
656-
//simulate a change only in domoticz, no sending frame for that !
657-
OutputNewStates( sID, output_index,m_BOOL_GlobalBlinkOutputs,15 );
658-
}
659-
660-
}
661-
}
662-
break;
663-
664-
}
665-
}
666-
}
667-
}
668-
}
669-
670703
//The STOR Frame always contain a maximum of 2 stor States. 4 Low bytes = STOR 1 / 4 high bytes = STOR2
671704
//( etc... for STOR3-4 /// 5/6 /// 7/8 ...)
672705
void USBtin_MultiblocV8::Traitement_Etat_S_TOR_Recu(const unsigned int FrameType,const unsigned char RefeBloc, const char Codage, const char Ssreseau,unsigned int bufferdata[8])
@@ -910,37 +943,37 @@ bool USBtin_MultiblocV8::WriteToHardware(const char *pdata, const unsigned char
910943
return false;
911944
}
912945
}
913-
else if( FrameType == type_COMMANDE_ETAT_BLOC ){ //specific command send to blocs
946+
else if( FrameType == type_COMMANDE_ETAT_BLOC ){ //specific command send to blocks
914947
if( ReferenceBloc == BLOC_SFSP_M || ReferenceBloc == BLOC_SFSP_E ){
915948
//on each "push on" switch send a bloc command starting with learn on OUTPUT 1
916949
//to OUTPUT 6 and return to Normal State Bloc.
917-
//In learning mode the output return states : ON + BLINK(1sec) ON but we can't show this in domoticz on a SWITCH because the output will only turn on !
918-
//So we can show it in the log message (OUTPUT+n° + LEARN MODE) !
919-
unsigned char Commande = (pSen->LIGHTING2.unitcode);
920-
switch(Commande){
921-
default :
922-
case BLOC_STATES_LEARNING_STOP :
923-
m_CHAR_CommandBlocToSend = BLOC_STATES_LEARNING_STOP;
924-
break;
925-
case BLOC_STATES_LEARNING :
926-
m_CHAR_CommandBlocToSend = BLOC_STATES_LEARNING;
927-
break;
928-
case BLOC_STATES_CLEARING :
929-
m_CHAR_CommandBlocToSend = BLOC_STATES_CLEARING;
930-
break;
931-
}
950+
//In learning mode the output return states : ON with BLINK MODE ON(1sec)
951+
//but we can't show the blink mode in domoticz on a SWITCH because the output will only turn on !
952+
char Commande = (pSen->LIGHTING2.unitcode);
932953
//sID_EnBase + commande
933-
USBtin_MultiblocV8_Send_CommandBlocState_OnCAN(sID_EnBase,m_CHAR_CommandBlocToSend);
934-
if( Commande == BLOC_STATES_LEARNING ){
935-
USBtin_MultiblocV8_Send_SFSP_LearnCommand_OnCAN(sID_EnBase,0); //
936-
}
954+
USBtin_MultiblocV8_Send_CommandBlocState_OnCAN(sID_EnBase,Commande);
955+
//Lerning mode entrance : automatically reset and start on Output 1 !
956+
/*if( Commande == BLOC_STATES_LEARNING ){
957+
m_V8_INT_PushCountLearnMode = 0;
958+
} */
937959
return true;
938960
}
939961
else{
940962
_log.Log(LOG_ERROR,"MultiblocV8: Error Command BLoc not allowed !");
941963
return false;
942964
}
943965
}
966+
else if( FrameType == type_SFSP_LearnCommand ){ //specific command for sfsp to jump from one output to the next
967+
if( ReferenceBloc == BLOC_SFSP_M || ReferenceBloc == BLOC_SFSP_E ){
968+
char Commande = (pSen->LIGHTING2.unitcode);
969+
USBtin_MultiblocV8_Send_SFSP_LearnCommand_OnCAN(sID_EnBase,Commande); //
970+
return true;
971+
}
972+
else{
973+
_log.Log(LOG_ERROR,"MultiblocV8: Error Command SFSP Learn not allowed !");
974+
return false;
975+
}
976+
}
944977
}
945978
else{
946979
_log.Log(LOG_ERROR,"MultiblocV8: This Can engine is disabled, please re-check MultiblocV8...");
@@ -984,7 +1017,7 @@ void USBtin_MultiblocV8::USBtin_MultiblocV8_Send_CommandBlocState_OnCAN(long sID
9841017
void USBtin_MultiblocV8::USBtin_MultiblocV8_Send_SFSP_LearnCommand_OnCAN(long baseID_ToSend,char Commande){
9851018
char szDeviceID[10];
9861019
char DataToSend[16];
987-
unsigned long sID = (type_CMD_S_TOR<<SHIFT_TYPE_TRAME)+ (baseID_ToSend&(MSK_INDEX_MODULE+MSK_CODAGE_MODULE+MSK_SRES_MODULE));
1020+
unsigned long sID = (type_SFSP_LearnCommand<<SHIFT_TYPE_TRAME)+ (baseID_ToSend&(MSK_INDEX_MODULE+MSK_CODAGE_MODULE+MSK_SRES_MODULE));
9881021
sprintf(szDeviceID,"%08X",(unsigned int)sID);
9891022
//unsigned int DevIdOnCan = 0x00000001; //on the CAN a wired Input always send a DevId at 0x01 on a u32
9901023
//differ from a real wireless EnOcean receive switch send directly its (u32)DeviceId
@@ -996,4 +1029,21 @@ void USBtin_MultiblocV8::USBtin_MultiblocV8_Send_SFSP_LearnCommand_OnCAN(long ba
9961029
//if( m_BOOL_DebugInMultiblocV8 == true )
9971030
_log.Log(LOG_NORM,"MultiblocV8: Sending SFSP learn command: %s ",szTrameToSend.c_str() );
9981031
writeFrame(szTrameToSend);
1032+
/*
1033+
char RefBloc = (baseID_ToSend & MSK_INDEX_MODULE) >> SHIFT_INDEX_MODULE; //retreive the refblock
1034+
1035+
switch(RefBloc){
1036+
case BLOC_SFSP_M :
1037+
case BLOC_SFSP_E :
1038+
case BLOC_9 :
1039+
//6 push max and automatically go out of Learning Mode !
1040+
if( m_V8_INT_PushCountLearnMode >= 6 ){
1041+
m_V8_INT_PushCountLearnMode = 0;
1042+
//return to normal states...
1043+
USBtin_MultiblocV8_Send_CommandBlocState_OnCAN(baseID_ToSend,BLOC_STATES_LEARNING_STOP);
1044+
}
1045+
else m_V8_INT_PushCountLearnMode++;
1046+
break;
1047+
}*/
1048+
9991049
}

hardware/USBtin_MultiblocV8.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ class USBtin_MultiblocV8 : public CDomoticzHardwareBase
6969
void USBtin_MultiblocV8_Send_SFSP_LearnCommand_OnCAN(long baseID_ToSend,char Commande);
7070
void InsertUpdateControlSwitch(const int NodeID, const int ChildID, const std::string &defaultname);
7171
void SetOutputBlinkInDomoticz (unsigned long sID,int OutputNumber,bool Blink);
72-
void DoBlinkOutput();
73-
72+
void Traitement_Trame_EtatBloc(const unsigned char RefBloc, const char Codage, const char Ssreseau,unsigned int rxDLC,unsigned int bufferdata[8]);
7473
};
7574

0 commit comments

Comments
 (0)