@@ -228,6 +228,21 @@ typedef enum
228
228
#define S_RPS_RPC 0x0F
229
229
#define S_RPS_RPC_SHIFT 0
230
230
/* @}*/
231
+
232
+ #define F60201_R1_MASK 0xE0
233
+ #define F60201_R1_SHIFT 5
234
+ #define F60201_EB_MASK 0x10
235
+ #define F60201_EB_SHIFT 4
236
+ #define F60201_R2_MASK 0x0E
237
+ #define F60201_R2_SHIFT 1
238
+ #define F60201_SA_MASK 0x01
239
+ #define F60201_SA_SHIFT 0
240
+
241
+ #define F60201_BUTTON_A1 0
242
+ #define F60201_BUTTON_A0 1
243
+ #define F60201_BUTTON_B1 2
244
+ #define F60201_BUTTON_B0 3
245
+
231
246
/* *
232
247
* @defgroup status_rpc Status of telegram (for 1BS, 4BS, HRC or 6DT telegrams)
233
248
* Bitmasks for the status-field, if ORG = 1BS, 4BS, HRC or 6DT.
@@ -486,6 +501,18 @@ void CEnOceanESP3::Do_Work()
486
501
487
502
void CEnOceanESP3::Add2SendQueue (const char * pData, const size_t length)
488
503
{
504
+ #ifdef ENABLE_LOGGING
505
+ std::stringstream sstr;
506
+
507
+ for (int idx=0 ;idx<length;idx++)
508
+ {
509
+ sstr << std::hex << std::uppercase << std::setw (2 ) << std::setfill (' 0' ) << (((unsigned int )pData[idx]) & 0xFF );
510
+ if (idx!=length-1 )
511
+ sstr << " " ;
512
+ }
513
+ _log.Log (LOG_STATUS," EnOcean Send: %s" ,sstr.str ().c_str ());
514
+ #endif
515
+
489
516
std::string sBytes ;
490
517
sBytes .insert (0 ,pData,length);
491
518
boost::lock_guard<boost::mutex> l (m_sendMutex);
@@ -620,24 +647,10 @@ bool CEnOceanESP3::WriteToHardware(const char *pdata, const unsigned char length
620
647
unsigned long sID =(tsen->LIGHTING2 .id1 <<24 )|(tsen->LIGHTING2 .id2 <<16 )|(tsen->LIGHTING2 .id3 <<8 )|tsen->LIGHTING2 .id4 ;
621
648
if ((sID <m_id_base)||(sID >m_id_base+129 ))
622
649
{
623
- _log.Log (LOG_ERROR," EnOcean: Can not switch with this DeviceID, use a switch created with our id_base!..." );
650
+ _log.Log (LOG_ERROR," (1) EnOcean: Can not switch with this DeviceID, use a switch created with our id_base!..." );
624
651
return false ;
625
652
}
626
653
627
- unsigned char buf[100 ];
628
- buf[0 ]=0xa5 ;
629
- buf[1 ]=0x2 ;
630
- buf[2 ]=100 ; // level
631
- buf[3 ]=1 ; // speed
632
- buf[4 ]=0x09 ; // Dim Off
633
-
634
- buf[5 ]=(sID >> 24 ) & 0xff ;
635
- buf[6 ]=(sID >> 16 ) & 0xff ;
636
- buf[7 ]=(sID >> 8 ) & 0xff ;
637
- buf[8 ]=sID & 0xff ;
638
-
639
- buf[9 ]=0x30 ; // status
640
-
641
654
unsigned char RockerID=0 ;
642
655
unsigned char Pressed=1 ;
643
656
@@ -690,41 +703,124 @@ bool CEnOceanESP3::WriteToHardware(const char *pdata, const unsigned char length
690
703
cmnd=light2_sSetLevel;
691
704
}
692
705
693
- if (cmnd!=light2_sSetLevel)
706
+ // char buff[512];
707
+ // sprintf(buff,"cmnd: %d, level: %d, orgcmd: %d",cmnd, iLevel, orgcmd);
708
+ // _log.Log(LOG_ERROR,buff);
709
+ unsigned char buf[100 ];
710
+ unsigned char optbuf[100 ];
711
+
712
+ if (!bIsDimmer)
694
713
{
695
- // On/Off
714
+ // on/off switch without dimming capability: Profile F6-02-01
715
+ // cf. EnOcean Equipment Profiles v2.6.5 page 11 (RPS format) & 14
696
716
unsigned char UpDown = 1 ;
697
- UpDown = ((cmnd != light2_sOff) && (cmnd != light2_sGroupOff));
698
717
718
+ buf[0 ] = RORG_RPS;
719
+
720
+ UpDown = ((orgcmd != light2_sOff) && (orgcmd != light2_sGroupOff));
721
+
722
+ switch (RockerID)
723
+ {
724
+ case 0 : // Button A
725
+ if (UpDown)
726
+ buf[1 ] = F60201_BUTTON_A1 << F60201_R1_SHIFT;
727
+ else
728
+ buf[1 ] = F60201_BUTTON_A0 << F60201_R1_SHIFT;
729
+ break ;
730
+
731
+ case 1 : // Button B
732
+ if (UpDown)
733
+ buf[1 ] = F60201_BUTTON_B1 << F60201_R1_SHIFT;
734
+ else
735
+ buf[1 ] = F60201_BUTTON_B0 << F60201_R1_SHIFT;
736
+ break ;
737
+
738
+ default :
739
+ return false ; // not supported
740
+ }
741
+
742
+ buf[1 ] |= F60201_EB_MASK; // button is pressed
743
+
744
+ buf[2 ]=(sID >> 24 ) & 0xff ; // Sender ID
745
+ buf[3 ]=(sID >> 16 ) & 0xff ;
746
+ buf[4 ]=(sID >> 8 ) & 0xff ;
747
+ buf[5 ]=sID & 0xff ;
699
748
700
- buf[1 ] = (RockerID<<DB3_RPS_NU_RID_SHIFT) | (UpDown<<DB3_RPS_NU_UD_SHIFT) | (Pressed<<DB3_RPS_NU_PR_SHIFT);// 0x30;
701
- buf[9 ] = 0x30 ;
749
+ buf[6 ] = S_RPS_T21|S_RPS_NU; // press button // b5=T21, b4=NU, b3-b0= RepeaterCount
702
750
703
- sendFrameQueue (PACKET_RADIO,buf,10 ,NULL ,0 );
751
+ // char buff[512];
752
+ // sprintf(buff,"%02X %02X %02X %02X %02X %02X %02X",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6]);
753
+ // _log.Log(LOG_ERROR,buff);
754
+
755
+ sendFrameQueue (PACKET_RADIO,buf,7 ,NULL ,0 );
704
756
705
757
// Next command is send a bit later (button release)
706
- buf[1 ] = 0 ;
707
- buf[9 ] = 0x20 ;
708
- sendFrameQueue (PACKET_RADIO,buf,10 ,NULL ,0 );
758
+ buf[1 ] = 0 ; // no button press
759
+ buf[6 ] = S_RPS_T21; // release button // b5=T21, b4=NU, b3-b0= RepeaterCount
760
+ // sprintf(buff,"%02X %02X %02X %02X %02X %02X %02X",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6]);
761
+ // _log.Log(LOG_ERROR,buff);
762
+
763
+ sendFrameQueue (PACKET_RADIO,buf,7 ,NULL ,0 );
709
764
}
710
765
else
711
766
{
712
- // Send dim value
767
+ // on/off switch with dimming capability: Profile A5-38-02
768
+ // cf. EnOcean Equipment Profiles v2.6.5 page 12 (4BS format) & 103
769
+ buf[0 ]=0xa5 ;
770
+ buf[1 ]=0x2 ;
771
+ buf[2 ]=100 ; // level
772
+ buf[3 ]=1 ; // speed
773
+ buf[4 ]=0x09 ; // Dim Off
774
+
775
+ buf[5 ]=(sID >> 24 ) & 0xff ;
776
+ buf[6 ]=(sID >> 16 ) & 0xff ;
777
+ buf[7 ]=(sID >> 8 ) & 0xff ;
778
+ buf[8 ]=sID & 0xff ;
779
+
780
+ buf[9 ]=0x30 ; // status
781
+
782
+ if (cmnd!=light2_sSetLevel)
783
+ {
784
+ // On/Off
785
+ unsigned char UpDown = 1 ;
786
+ UpDown = ((cmnd != light2_sOff) && (cmnd != light2_sGroupOff));
787
+
788
+ buf[1 ] = (RockerID<<DB3_RPS_NU_RID_SHIFT) | (UpDown<<DB3_RPS_NU_UD_SHIFT) | (Pressed<<DB3_RPS_NU_PR_SHIFT);// 0x30;
789
+ buf[9 ] = 0x30 ;
713
790
714
- // Dim On DATA_BYTE0 = 0x09
715
- // Dim Off DATA_BYTE0 = 0x08
791
+ sendFrameQueue (PACKET_RADIO,buf,10 ,NULL ,0 );
716
792
717
- buf[ 1 ]= 2 ;
718
- buf[2 ]=iLevel ;
719
- buf[ 3 ]= 1 ; // very fast dimming
793
+ // char buff[512] ;
794
+ // sprintf(buff,"%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9]) ;
795
+ // _log.Log(LOG_ERROR,buff);
720
796
721
- if ((iLevel==0 )||(orgcmd==light2_sOff))
722
- buf[4 ]=0x08 ; // Dim Off
797
+ // Next command is send a bit later (button release)
798
+ buf[1 ] = 0 ;
799
+ buf[9 ] = 0x20 ;
800
+ // sprintf(buff,"%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9]);
801
+ // _log.Log(LOG_ERROR,buff);
802
+ sendFrameQueue (PACKET_RADIO,buf,10 ,NULL ,0 );
803
+ }
723
804
else
724
- buf[4 ]=0x09 ;// Dim On
805
+ {
806
+ // Send dim value
807
+
808
+ // Dim On DATA_BYTE0 = 0x09
809
+ // Dim Off DATA_BYTE0 = 0x08
810
+
811
+ buf[1 ]=2 ;
812
+ buf[2 ]=iLevel;
813
+ buf[3 ]=1 ;// very fast dimming
725
814
726
- sendFrameQueue (PACKET_RADIO,buf,10 ,NULL ,0 );
815
+ if ((iLevel==0 )||(orgcmd==light2_sOff))
816
+ buf[4 ]=0x08 ; // Dim Off
817
+ else
818
+ buf[4 ]=0x09 ;// Dim On
819
+
820
+ sendFrameQueue (PACKET_RADIO,buf,10 ,NULL ,0 );
821
+ }
727
822
}
823
+
728
824
return true ;
729
825
}
730
826
@@ -739,7 +835,7 @@ void CEnOceanESP3::SendDimmerTeachIn(const char *pdata, const unsigned char leng
739
835
unsigned long sID = (tsen->LIGHTING2 .id1 << 24 ) | (tsen->LIGHTING2 .id2 << 16 ) | (tsen->LIGHTING2 .id3 << 8 ) | tsen->LIGHTING2 .id4 ;
740
836
if ((sID <m_id_base) || (sID >m_id_base + 129 ))
741
837
{
742
- _log.Log (LOG_ERROR, " EnOcean: Can not switch with this DeviceID, use a switch created with our id_base!..." );
838
+ _log.Log (LOG_ERROR, " (2) EnOcean: Can not switch with this DeviceID, use a switch created with our id_base!..." );
743
839
return ;
744
840
}
745
841
@@ -1710,6 +1806,66 @@ void CEnOceanESP3::ParseRadioDatagram()
1710
1806
}
1711
1807
}
1712
1808
break ;
1809
+ case RORG_VLD:
1810
+ {
1811
+ unsigned char DATA_BYTE3=m_buffer[1 ];
1812
+ unsigned char func = m_buffer[1 ];
1813
+ unsigned char type = m_buffer[2 ];
1814
+
1815
+ if (func == 0x04 )
1816
+ {
1817
+ // D2-04
1818
+ switch ((type & 0xE0 ) >> 5 )
1819
+ {
1820
+ case 3 :
1821
+ // Nodon wall module event notification
1822
+ {
1823
+ unsigned char channel = type & 0x1F ;
1824
+
1825
+ unsigned char dim_power = m_buffer[3 ] & 0x7F ; // 0=off, 0x64=100%
1826
+
1827
+ unsigned char ID_BYTE3=m_buffer[4 ];
1828
+ unsigned char ID_BYTE2=m_buffer[5 ];
1829
+ unsigned char ID_BYTE1=m_buffer[6 ];
1830
+ unsigned char ID_BYTE0=m_buffer[7 ];
1831
+ long id = (ID_BYTE3 << 24 ) + (ID_BYTE2 << 16 ) + (ID_BYTE1 << 8 ) + ID_BYTE0;
1832
+
1833
+ // m_buffer[8] = 00 ?
1834
+ // m_buffer[9] = 01 ?
1835
+ RBUF tsen;
1836
+ memset (&tsen,0 ,sizeof (RBUF));
1837
+ tsen.LIGHTING2 .packetlength =sizeof (tsen.LIGHTING2 )-1 ;
1838
+ tsen.LIGHTING2 .packettype =pTypeLighting2;
1839
+ tsen.LIGHTING2 .subtype =sTypeNodon ;
1840
+ tsen.LIGHTING2 .seqnbr =0 ;
1841
+
1842
+ tsen.LIGHTING2 .id1 =(BYTE)ID_BYTE3;
1843
+ tsen.LIGHTING2 .id2 =(BYTE)ID_BYTE2;
1844
+ tsen.LIGHTING2 .id3 =(BYTE)ID_BYTE1;
1845
+ tsen.LIGHTING2 .id4 =(BYTE)ID_BYTE0;
1846
+ tsen.LIGHTING2 .level =dim_power;
1847
+ tsen.LIGHTING2 .rssi =12 ;
1848
+
1849
+ tsen.LIGHTING2 .unitcode = channel + 1 ;
1850
+ tsen.LIGHTING2 .cmnd = (dim_power>0 ) ? light2_sOn : light2_sOff;
1851
+
1852
+ #ifdef ENOCEAN_BUTTON_DEBUG
1853
+ _log.Log (LOG_NORM, " EnOcean message: 0x%02X Node 0x%08x UnitID: %02X cmd: %02X " ,
1854
+ DATA_BYTE3,
1855
+ id,
1856
+ tsen.LIGHTING2 .unitcode ,
1857
+ tsen.LIGHTING2 .cmnd
1858
+ );
1859
+ #endif // ENOCEAN_BUTTON_DEBUG
1860
+
1861
+ sDecodeRXMessage (this , (const unsigned char *)&tsen.LIGHTING2 , NULL , 255 );
1862
+ return ;
1863
+ }
1864
+ break ;
1865
+ }
1866
+ }
1867
+ }
1868
+
1713
1869
default :
1714
1870
_log.Log (LOG_NORM, " EnOcean: Unhandled RORG (%02x)" , m_buffer[0 ]);
1715
1871
break ;
0 commit comments