mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-02 01:40:34 +00:00
ef5df5c382
git-svn-id: https://svn.fhem.de/fhem/trunk@17186 2b470e98-0d58-463d-a4d8-8e2adae1ed80
262 lines
8.5 KiB
Perl
262 lines
8.5 KiB
Perl
##############################################
|
|
# $Id$
|
|
package main;
|
|
|
|
# Known controller function.
|
|
# Note: Known != implemented, see %sets & %gets for the implemented ones.
|
|
use vars qw(%zw_func_id);
|
|
use vars qw(%zw_type6);
|
|
|
|
%zw_func_id= (
|
|
'02' => 'SERIAL_API_GET_INIT_DATA',
|
|
'03' => 'SERIAL_API_APPL_NODE_INFORMATION',
|
|
'04' => 'APPLICATION_COMMAND_HANDLER',
|
|
'05' => 'ZW_GET_CONTROLLER_CAPABILITIES',
|
|
'06' => 'SERIAL_API_SET_TIMEOUTS',
|
|
'07' => 'SERIAL_API_GET_CAPABILITIES',
|
|
'08' => 'SERIAL_API_SOFT_RESET',
|
|
'0b' => 'SERIAL_API_SETUP',
|
|
'10' => 'ZW_SET_R_F_RECEIVE_MODE',
|
|
'11' => 'ZW_SET_SLEEP_MODE',
|
|
'12' => 'ZW_SEND_NODE_INFORMATION',
|
|
'13' => 'ZW_SEND_DATA',
|
|
'14' => 'ZW_SEND_DATA_MULTI',
|
|
'15' => 'ZW_GET_VERSION',
|
|
'16' => 'ZW_SEND_DATA_ABORT',
|
|
'17' => 'ZW_R_F_POWER_LEVEL_SET',
|
|
'18' => 'ZW_SEND_DATA_META',
|
|
'19' => 'ZW_SEND_DATA_GENERIC', # Appl. Guide
|
|
'1a' => 'ZW_SEND_DATA_META_GENERIC', # Appl. Guide
|
|
'1b' => 'ZW_SET_ROUTING_INFO', # Appl. Guide
|
|
'1c' => 'ZW_GET_RANDOM', # ZW_GET_RANDOM_WORD # Appl. Guide
|
|
'1d' => 'ZW_RANDOM', # Appl. Guide
|
|
'1e' => 'ZW_RF_POWER_LEVEL_REDISCOVERY_SET', # Appl. Guide
|
|
'20' => 'MEMORY_GET_ID',
|
|
'21' => 'MEMORY_GET_BYTE',
|
|
'22' => 'MEMORY_PUT_BYTE',
|
|
'23' => 'MEMORY_GET_BUFFER',
|
|
'24' => 'MEMORY_PUT_BUFFER',
|
|
'27' => 'FLASH_AUTO_PROG_SET',
|
|
'28' => 'ZW_NVR_GET_VALUE',
|
|
'29' => 'NVM_GET_ID',
|
|
'2a' => 'NVM_EXT_READ_LONG_BUFFER',
|
|
'2b' => 'NVM_EXT_WRITE_LONG_BUFFER',
|
|
'2c' => 'NVM_EXT_READ_LONG_BYTE',
|
|
'2d' => 'NVM_EXT_WRITE_LONG_BYTE',
|
|
'30' => 'CLOCK_SET',
|
|
'31' => 'CLOCK_GET',
|
|
'32' => 'CLOCK_COMPARE',
|
|
'33' => 'RTC_TIMER_CREATE',
|
|
'34' => 'RTC_TIMER_READ',
|
|
'35' => 'RTC_TIMER_DELETE',
|
|
'36' => 'RTC_TIMER_CALL',
|
|
'37' => 'ZW_CLEAR_TX_TIMERS',
|
|
'38' => 'ZW_GET_TX_TIMERS',
|
|
'39' => 'CLEAR_NETWORK_STATS',
|
|
'3a' => 'GET_NETWORK_STATS',
|
|
'3b' => 'GET_BACKGROUND_RSSI',
|
|
'3f' => 'REMOVE_NODEID_FROM_NETWORK',
|
|
'40' => 'ZW_SET_LEARN_NODE_STATE',
|
|
'41' => 'ZW_GET_NODE_PROTOCOL_INFO',
|
|
'42' => 'ZW_SET_DEFAULT',
|
|
'43' => 'ZW_NEW_CONTROLLER',
|
|
'44' => 'ZW_REPLICATION_COMMAND_COMPLETE',
|
|
'45' => 'ZW_REPLICATION_SEND_DATA',
|
|
'46' => 'ZW_ASSIGN_RETURN_ROUTE',
|
|
'47' => 'ZW_DELETE_RETURN_ROUTE',
|
|
'48' => 'ZW_REQUEST_NODE_NEIGHBOR_UPDATE',
|
|
'49' => 'ZW_APPLICATION_UPDATE',
|
|
'4a' => 'ZW_ADD_NODE_TO_NETWORK',
|
|
'4b' => 'ZW_REMOVE_NODE_FROM_NETWORK',
|
|
'4c' => 'ZW_CREATE_NEW_PRIMARY',
|
|
'4d' => 'ZW_CONTROLLER_CHANGE',
|
|
'4f' => 'ZW_ASSIGN_PRIORITY_RETURN_ROUTE',
|
|
'50' => 'ZW_SET_LEARN_MODE',
|
|
'51' => 'ZW_ASSIGN_SUC_RETURN_ROUTE',
|
|
'52' => 'ZW_ENABLE_SUC',
|
|
'53' => 'ZW_REQUEST_NETWORK_UPDATE',
|
|
'54' => 'ZW_SET_SUC_NODE_ID',
|
|
'55' => 'ZW_DELETE_SUC_RETURN_ROUTE',
|
|
'56' => 'ZW_GET_SUC_NODE_ID',
|
|
'57' => 'ZW_SEND_SUC_ID',
|
|
'58' => 'ZW_ASSIGN_PRIORITY_SUC_RETURN_ROUTE',
|
|
'59' => 'ZW_REDISCOVERY_NEEDED',
|
|
'5b' => 'ZW_SUPPORT_9600_ONLY', # Appl. Guide
|
|
'5c' => 'ZW_REQUEST_NEW_ROUTE_DESTINATIONS', # Appl. Guide
|
|
'5d' => 'ZW_IS_NODE_WIHTIN_DIRECT_RANGE', # Appl. Guide
|
|
'5e' => 'ZW_EXPLORE_REQUEST_INCLUSION',
|
|
'5f' => 'ZW_EXPLORE_REQUEST_EXCLUSION',
|
|
'60' => 'ZW_REQUEST_NODE_INFO',
|
|
'61' => 'ZW_REMOVE_FAILED_NODE_ID',
|
|
'62' => 'ZW_IS_FAILED_NODE',
|
|
'63' => 'ZW_REPLACE_FAILED_NODE',
|
|
'70' => 'TIMER_START',
|
|
'71' => 'TIMER_RESTART',
|
|
'72' => 'TIMER_CANCEL',
|
|
'73' => 'TIMER_CALL',
|
|
'78' => 'ZW_FIRMWARE_UPDATE_NVM',
|
|
'80' => 'GET_ROUTING_TABLE_LINE',
|
|
'81' => 'GET_T_X_COUNTER',
|
|
'82' => 'RESET_T_X_COUNTER',
|
|
'83' => 'STORE_NODE_INFO',
|
|
'84' => 'STORE_HOME_ID',
|
|
'90' => 'LOCK_ROUTE_RESPONSE',
|
|
'91' => 'ZW_SEND_DATA_ROUTE_DEMO',
|
|
'92' => 'ZW_GET_PRIORITY_ROUTE',
|
|
'93' => 'ZW_SET_PRIORITY_ROUTE',
|
|
'95' => 'SERIAL_API_TEST',
|
|
'a0' => 'SERIAL_API_SLAVE_NODE_INFO',
|
|
'a1' => 'APPLICATION_SLAVE_COMMAND_HANDLER',
|
|
'a2' => 'ZW_SEND_SLAVE_NODE_INFO',
|
|
'a3' => 'ZW_SEND_SLAVE_DATA',
|
|
'a4' => 'ZW_SET_SLAVE_LEARN_MODE',
|
|
'a5' => 'ZW_GET_VIRTUAL_NODES',
|
|
'a6' => 'ZW_IS_VIRTUAL_NODE',
|
|
'a8' => 'ZW_APPLICATION_COMMAND_HANLDER_BRIDGE', # Appl. Guide
|
|
'a9' => 'ZW_SEND_DATA_BRIDGE', # Appl. Guide
|
|
'aa' => 'ZW_SEND_DATA_META_BRIDGE', # Appl. Guide
|
|
'ab' => 'ZW_SEND_DATA_MULTI_BRIDGE', # Appl. Guide
|
|
'b4' => 'ZW_SET_WUT_TIMEOUT', # Appl. Guide
|
|
'b6' => 'ZW_WATCHDOG_ENABLE',
|
|
'b7' => 'ZW_WATCHDOG_DISABLE',
|
|
'b8' => 'ZW_WATCHDOG_CHECK', # ZW_WATCHDOG_KICK # Appl. Guide
|
|
'b9' => 'ZW_SET_EXT_INT_LEVEL',
|
|
'ba' => 'ZW_RF_POWERLEVEL_GET',
|
|
'bb' => 'ZW_GET_NEIGHBOR_COUNT',
|
|
'bc' => 'ZW_ARE_NODES_NEIGHBOURS',
|
|
'bd' => 'ZW_TYPE_LIBRARY',
|
|
'be' => 'ZW_SEND_TEST_FRAME',
|
|
'bf' => 'ZW_GET_PROTOCOL_STATUS',
|
|
'd0' => 'ZW_SET_PROMISCUOUS_MODE',
|
|
'd1' => 'PROMISCUOUS_COMMAND_HANDLER',
|
|
'd2' => 'WATCHDOG_START',
|
|
'd3' => 'WATCHDOG_STOP',
|
|
'd4' => 'ZW_SET_ROUTING_MAX',
|
|
'f2' => 'ZME_FREQ_CHANGE',
|
|
'f4' => 'ZME_BOOTLOADER_FLASH',
|
|
'f5' => 'ZME_CAPABILITIES',
|
|
);
|
|
|
|
%zw_type6 = (
|
|
'01' => 'GENERIC_CONTROLLER',
|
|
'02' => 'STATIC_CONTROLLER',
|
|
'03' => 'AV_CONTROL_POINT',
|
|
'04' => 'DISPLAY',
|
|
'05' => 'NETWORK_EXTENDER',
|
|
'06' => 'APPLIANCE',
|
|
'07' => 'SENSOR_NOTIFICATION',
|
|
'08' => 'THERMOSTAT',
|
|
'09' => 'WINDOW_COVERING',
|
|
'0f' => 'REPEATER_SLAVE',
|
|
'10' => 'SWITCH_BINARY',
|
|
'11' => 'SWITCH_MULTILEVEL',
|
|
'12' => 'SWITCH_REMOTE',
|
|
'13' => 'SWITCH_TOGGLE',
|
|
'15' => 'ZIP_NODE',
|
|
'16' => 'VENTILATION',
|
|
'17' => 'SECURITY_PANEL',
|
|
'18' => 'WALL_CONTROLLER',
|
|
'20' => 'SENSOR_BINARY',
|
|
'21' => 'SENSOR_MULTILEVEL',
|
|
'22' => 'WATER_CONTROL',
|
|
'30' => 'METER_PULSE',
|
|
'31' => 'METER',
|
|
'40' => 'ENTRY_CONTROL',
|
|
'50' => 'SEMI_INTEROPERABLE',
|
|
'a1' => 'SENSOR_ALARM',
|
|
'ff' => 'NON_INTEROPERABLE',
|
|
);
|
|
|
|
sub
|
|
zwlib_parseNeighborList($$)
|
|
{
|
|
my ($iodev, $data) = @_;
|
|
my $homeId = $iodev->{homeId};
|
|
my $ioName = $iodev->{NAME};
|
|
my @r = map { ord($_) } split("", pack('H*', $data));
|
|
return "Bogus neighborList $data" if(int(@r) != 29);
|
|
|
|
my @list;
|
|
my $ioId = ReadingsVal($ioName, "homeId", "");
|
|
$ioId = $1 if($ioId =~ m/CtrlNodeIdHex:(..)/);
|
|
for my $byte (0..28) {
|
|
my $bits = $r[$byte];
|
|
for my $bit (0..7) {
|
|
if($bits & (1<<$bit)) {
|
|
my $dec = $byte*8+$bit+1;
|
|
my $hex = sprintf("%02x", $dec);
|
|
my $h = $modules{ZWave}{defptr}{"$homeId $hex"};
|
|
push @list, ($hex eq $ioId ? $ioName :
|
|
($h ? $h->{NAME} : "UNKNOWN_$dec"));
|
|
}
|
|
}
|
|
}
|
|
return @list ? join(" ", @list) : "empty";
|
|
}
|
|
|
|
#####################################
|
|
sub
|
|
zwlib_checkSum_8($)
|
|
{
|
|
my ($data) = @_;
|
|
my $cs = 0xff;
|
|
map { $cs ^= ord($_) } split("", pack('H*', $data));
|
|
return sprintf("%02x", $cs);
|
|
}
|
|
|
|
sub
|
|
zwlib_checkSum_16($) # CRC16-CCITT (Polynom: 1021)
|
|
{
|
|
my ($data) = @_;
|
|
my $crc = 0x1d0f;
|
|
for my $c (split("", pack('H*', $data))) {
|
|
my $x = ($crc>>8) ^ ord($c);
|
|
$x ^= $x>>4;
|
|
$crc = (($crc<<8) ^ ($x<<12) ^ ($x<<5) ^ $x) & 0xffff;
|
|
}
|
|
return sprintf("%04x", $crc);
|
|
}
|
|
|
|
sub
|
|
zwlib_parseNodeInfo(@)
|
|
{
|
|
my @r = @_;
|
|
my @list;
|
|
my @type2 = qw(reserved0 2 SDK5.0x+4.2x SDK4.5x+6.0x reserved4
|
|
reserved5 reserved6 reserved7);
|
|
my @type2_1 = qw(reserved 9.6kbps 40kbps);
|
|
my @type3 = qw(Security Controller SpecificDev RoutingSlave BeamCap
|
|
FrequentListen250ms FrequentListen1000ms OptFunc);
|
|
my @type4 = qw(reserved0 100kbps 200kbps);
|
|
my @type4_1 = qw(N/A CentralStaticController SubStaticController
|
|
PortableController PortableReportingController
|
|
PortableSlave AlwaysOnSlave
|
|
SleepingReportingSlave SleepingListeningSlave);
|
|
my @type5 = qw(CONTROLLER STATIC_CONTROLLER SLAVE ROUTING_SLAVE);
|
|
push @list, "ProtocolVers:" . $type2[($r[2]&0x7)];
|
|
push @list, ($r[2] & 0x80) ? "listening" : "sleeping";
|
|
push @list, "routing"
|
|
if($r[2] & 0x40);
|
|
push @list, "maxBaud:" . $type2_1[($r[2] & 0x38) >> 3]
|
|
if($type2_1[($r[2] & 0x38) >> 3]);
|
|
for my $bit (0..7) {
|
|
push @list, $type3[$bit] if(($r[3] & (1<<$bit)) && $bit < @type3);
|
|
}
|
|
push @list, "SpeedExt:" . $type4[($r[4] & 0x7)]
|
|
if($type4[($r[4] & 0x7)] !=0);
|
|
push @list, "Reserved"
|
|
if($r[4] &0x08);
|
|
push @list, "RoleType:" . $type4_1[(($r[4] & 0x8) & 0xf0) >> 4]
|
|
if($type4_1[(($r[4] & 0x8) & 0xf0) >> 4]);
|
|
push @list, "BasicDevClass:" . $type5[$r[5]-1]
|
|
if($r[5]>0 && $r[5] <= @type5);
|
|
my $id = sprintf("%02x", $r[6]);
|
|
push @list, "GenericDevClass:" . $zw_type6{$id}
|
|
if($zw_type6{$id});
|
|
push @list, "SpecificDevClass:" . sprintf("%02x", $r[7])
|
|
if($r[7]);
|
|
return join(" ", @list);
|
|
}
|
|
|
|
1;
|