Package: knx-stack
knx-stackA Python 3 KNX stack, not complete but easily extensible.It is able toencode/decodeknx messages for bothUSB HIDandKNXnet IP.It can be used with anasynchronousorsynchronousclient.ExamplesSetup>>>importknx_stack>>>individual_address=knx_stack.Address(0x0001)>>>abcd=knx_stack.GroupAddress(free_style=0xABCD)>>>abce=knx_stack.GroupAddress(three_level_style=knx_stack.address.ThreeLevelStyle(main=21,middle=3,sub=206))>>>abcf=knx_stack.GroupAddress(two_level_style=knx_stack.address.TwoLevelStyle(main=21,sub=975))>>>asap_1=knx_stack.ASAP(1,"on/off light")>>>asap_2=knx_stack.ASAP(2,"info on/off light")>>>asap_3=knx_stack.ASAP(3,"two temperature sensors (together)")>>>address_table=knx_stack.AddressTable(individual_address,[],255)>>>association_table=knx_stack.AssociationTable(address_table,[])>>>association_table.associate(asap_1,[abcd])>>>association_table.associate(asap_2,[abcd])>>>association_table.associate(asap_3,[abce,abcf])>>>group_object_table=knx_stack.GroupObjectTable({asap_1:knx_stack.datapointtypes.DPT_Switch,...asap_2:knx_stack.datapointtypes.DPT_Switch,...asap_3:knx_stack.datapointtypes.DPT_Value_Temp,...})>>>association_tableAssociationTable:asap->addresses0(individualaddress)->[0x0001]1(on/offlight)->[(0xABCD21/97321/3/205)]2(infoon/offlight)->[(0xABCD21/97321/3/205)]3(twotemperaturesensors(together))->[(0xABCE21/97421/3/206),(0xABCF21/97521/3/207)]AddressTable:individualaddress:0x0001,max_size=255<BLANKLINE>tsap->individualaddress0->0x0001tsap->groupaddress(hex_free_styletwo_level_stylethree_level_style)1->(0xABCD21/97321/3/205)2->(0xABCE21/97421/3/206)3->(0xABCF21/97521/3/207)<BLANKLINE>>>>group_object_tableGroupObjectTable:ASAP->datapointtype1(on/offlight)->DPT_Switch2(infoon/offlight)->DPT_Switch3(twotemperaturesensors(together))->DPT_Value_Temp<BLANKLINE>USB HID decode/encode>>>state=knx_stack.State(knx_stack.state.Medium.usb_hid,association_table,group_object_table)>>>msg=knx_stack.Msg.make_from_str("0113130008000B010300002900BCE00001ABCD010080")>>>knx_stack.decode_msg(state,msg)[GroupValueWriteInd(DPT_Switch{'action':'off'}forasap1(on/offlight)),GroupValueWriteInd(DPT_Switch{'action':'off'}forasap2(infoon/offlight))]>>>msg=knx_stack.Msg.make_from_str("0113130008000B010300002900BCE00001ABCC010081")>>>knx_stack.decode_msg(state,msg)[]>>>msg=knx_stack.Msg.make_from_str("0113140008000C010300002900B4E00001ABCE02008005")>>>knx_stack.decode_msg(state,msg)[GroupValueWriteInd(DPT_Value_Temp:{'decoded_value':0.05}forasap3(twotemperaturesensors(together)))]>>>req=knx_stack.layer.application.a_group_value_read.req.Msg(asap=asap_3)>>>knx_stack.encode_msg(state,req)0113130008000B01030000110096E00000ABCE010000>>>dpt=knx_stack.datapointtypes.DPT_Value_Temp()>>>dpt.encode(0.05)>>>req=knx_stack.layer.application.a_group_value_write.req.Msg(asap=asap_3,dpt=dpt)>>>knx_stack.encode_msg(state,req)0113150008000D01030000110096E00000ABCE0300800005KNXnet IP decode/encode>>>state=knx_stack.knxnet_ip.State(knx_stack.state.Medium.knxnet_ip,association_table,group_object_table)>>>state.sequence_counter_remote=1>>>msg=knx_stack.knxnet_ip.Msg.make_from_str("061004200015047401002900BCE00001ABCD010080")>>>knx_stack.decode_msg(state,msg)[TunnelingReq(sequencecounter=1,status=<ErrorCodes.E_NO_ERROR:0>),GroupValueWriteInd(DPT_Switch{'action':'off'}forasap1(on/offlight)),GroupValueWriteInd(DPT_Switch{'action':'off'}forasap2(infoon/offlight))]>>>msg=knx_stack.knxnet_ip.Msg.make_from_str("061004200016047401002900B4E00001ABCE02008005")>>>knx_stack.decode_msg(state,msg)[TunnelingReq(sequencecounter=1,status=<ErrorCodes.E_NO_ERROR:0>),GroupValueWriteInd(DPT_Value_Temp:{'decoded_value':0.05}forasap3(twotemperaturesensors(together)))]>>>req=knx_stack.layer.application.a_group_value_read.req.Msg(asap=asap_3)>>>knx_stack.encode_msg(state,req)06100420001504000000110096E00000ABCE010000>>>dpt=knx_stack.datapointtypes.DPT_Value_Temp()>>>dpt.encode(0.05)>>>req=knx_stack.layer.application.a_group_value_write.req.Msg(asap=asap_3,dpt=dpt)>>>knx_stack.encode_msg(state,req)06100420001704000000110096E00000ABCE0300800005Encode from a dictionary>>>state=knx_stack.State(knx_stack.state.Medium.usb_hid,association_table,group_object_table)>>>factory=knx_stack.datapointtypes.DPT_Factory()>>>dpt=factory.make("DPT_Switch",{"action":"off"})>>>req=knx_stack.layer.application.a_group_value_write.req.Msg(asap=asap_1,dpt=dpt)>>>reqGroupValueWriteReq(DPT_Switch{'action':'off'}forasap1(on/offlight))>>>knx_stack.encode_msg(state,req)0113130008000B01030000110096E00000ABCD010080Decode to a dictionary>>>state=knx_stack.State(knx_stack.state.Medium.usb_hid,association_table,group_object_table)>>>msg=knx_stack.knxnet_ip.Msg.make_from_str("0113130008000B01030000290096E00000ABCD010080")>>>msgs=knx_stack.decode_msg(state,msg)>>>msgs[GroupValueWriteInd(DPT_Switch{'action':'off'}forasap1(on/offlight)),GroupValueWriteInd(DPT_Switch{'action':'off'}forasap2(infoon/offlight))]>>>factory=knx_stack.datapointtypes.Description_Factory()>>>factory.make(msgs[0].dpt)('DPT_Switch',{'action':'off'})Installationpip install knx-stackDiving InDocumentationContributingPull requests are welcome, and I am waiting for them.Licenseknx-stack is licensed under the MIT license.