| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124 |
- ###############################################################
- # $Id: 36_Vallox.pm 17170 2018-08-19 06:12:22Z Skjall $
- #
- # @File 36_Vallox.pm
- #
- # @Author Skjall
- # @Created 21.07.2016 10:18:23
- # @Version 1.6.1
- #
- # The modul reads and writes parameters via RS485 from and to a Vallox
- # ventilation bus.
- #
- # This module was made possible by Heinz from mysensors Community
- # (https://forum.mysensors.org/user/heinz). His insights to the
- # Vallox bus were nessecary to make this script. - Thanks!
- #
- # This script is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # The GNU General Public License can be found at
- # http://www.gnu.org/copyleft/gpl.html.
- # A copy is found in the textfile GPL.txt and important notices to the license
- # from the author is found in LICENSE.txt distributed with these scripts.
- #
- # This script is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY || FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # This copyright notice MUST APPEAR in all copies of the script!
- #
- ################################################################
- ##############################################
- package main;
- use strict;
- use warnings;
- ##############################################
- # Global Variables
- ##############################################
- my %Vallox_datatypes;
- my %Vallox_datatypesReverse;
- ##################################
- # List of Datatyps of the Vallox bus
- ##################################
- my %Vallox_datatypes_base = (
- "06" => "FanSpeed-Relays",
- "07" => "MultiPurpose1",
- "08" => "MultiPurpose2",
- "29" => "FanSpeed",
- "2A" => "Humidity",
- "2B" => "CO2High",
- "2C" => "CO2Low",
- "2D" => "MachineInstalledCO2Sensors",
- "2E" => "CurrentVoltageIncomingOnMachine",
- "2F" => "HumiditySensor1",
- "30" => "HumiditySensor2",
- "32" => "TempOutside",
- "33" => "TempExhaust",
- "34" => "TempInside",
- "35" => "TempIncoming",
- "36" => "LastSystemFault",
- "55" => "PostHeatingOnCounter",
- "56" => "PostHeatingOffTime",
- "57" => "PostHeatingTargetValue",
- "6C" => "Flags1",
- "6D" => "Flags2",
- "6E" => "Flags3",
- "6F" => "Flags4",
- "70" => "Flags5",
- "71" => "Flags6",
- "79" => "FireplaceBoosterCountdownMinutes",
- "8F" => "ResumeBus",
- "91" => "SuspendBusForCO2Communication",
- "A3" => "Select",
- "A4" => "HeatingSetPoint",
- "A5" => "FanSpeedMax",
- "A6" => "ServiceReminderMonths",
- "A7" => "PreheatingSetPoint",
- "A8" => "InputFanStopTemperatureThreshold",
- "A9" => "FanSpeedMin",
- "AA" => "Program",
- "AB" => "MaintencanceCountdownMonths",
- "AE" => "BasicHumidityLevel",
- "AF" => "HeatRecoveryCellBypassSetpointTemperature",
- "B0" => "DCFanInputAdjustment",
- "B1" => "DCFanOutputAdjustment",
- "B2" => "CellDefrostingSetpointTemperature",
- "B3" => "CO2SetPointUpper",
- "B4" => "CO2SetPointLower",
- "B5" => "Program2",
- "C0" => "Initial1",
- "C6" => "Initial2",
- "C7" => "Initial3",
- "C8" => "Initial4",
- "C9" => "Initial5",
- );
- my %Vallox_datatypesReverse_base = reverse %Vallox_datatypes_base;
- my %Vallox_datatypes_legacy1 = (
- "49" => "Legacy49", # Unknown legacy Reading
- "4A" => "Legacy4A", # Unknown legacy Reading
- "4C" => "Legacy4C", # Unknown legacy Reading
- "53" => "Legacy53", # Unknown legacy Reading
- "54" => "Legacy54", # Unknown legacy Reading
- "58" => "TempOutside",
- "5A" => "TempInside",
- "5B" => "TempIncoming",
- "5C" => "TempExhaust",
- );
- my %Vallox_datatypesReverse_legacy1 = reverse %Vallox_datatypes_legacy1;
- ##################################
- # Mapping of the fan speeds
- ##################################
- my %Vallox_levelTable = (
- "01" => "1",
- "03" => "2",
- "07" => "3",
- "0F" => "4",
- "1F" => "5",
- "3F" => "6",
- "7F" => "7",
- "FF" => "8",
- );
- my %Vallox_levelTableReverse = reverse %Vallox_levelTable;
- ##################################
- # Mapping of the temperatures
- ##################################
- my %Vallox_temperatureTable = (
- "00" => "-74",
- "01" => "-70",
- "02" => "-66",
- "03" => "-62",
- "04" => "-59",
- "05" => "-56",
- "06" => "-54",
- "07" => "-52",
- "08" => "-50",
- "09" => "-48",
- "0A" => "-47",
- "0B" => "-46",
- "0C" => "-44",
- "0D" => "-43",
- "0E" => "-42",
- "0F" => "-41",
- "10" => "-40",
- "11" => "-39",
- "12" => "-38",
- "13" => "-37",
- "14" => "-36",
- "15" => "-35",
- "16" => "-34",
- "17" => "-33",
- "18" => "-33",
- "19" => "-32",
- "1A" => "-31",
- "1B" => "-30",
- "1C" => "-30",
- "1D" => "-29",
- "1E" => "-28",
- "1F" => "-28",
- "20" => "-27",
- "21" => "-27",
- "22" => "-26",
- "23" => "-25",
- "24" => "-25",
- "25" => "-24",
- "26" => "-24",
- "27" => "-23",
- "28" => "-23",
- "29" => "-22",
- "2A" => "-22",
- "2B" => "-21",
- "2C" => "-21",
- "2D" => "-20",
- "2E" => "-20",
- "2F" => "-19",
- "30" => "-19",
- "31" => "-19",
- "32" => "-18",
- "33" => "-18",
- "34" => "-17",
- "35" => "-17",
- "36" => "-16",
- "37" => "-16",
- "38" => "-16",
- "39" => "-15",
- "3A" => "-15",
- "3B" => "-14",
- "3C" => "-14",
- "3D" => "-14",
- "3E" => "-13",
- "3F" => "-13",
- "40" => "-12",
- "41" => "-12",
- "42" => "-12",
- "43" => "-11",
- "44" => "-11",
- "45" => "-11",
- "46" => "-10",
- "47" => "-10",
- "48" => "-9",
- "49" => "-9",
- "4A" => "-9",
- "4B" => "-8",
- "4C" => "-8",
- "4D" => "-8",
- "4E" => "-7",
- "4F" => "-7",
- "50" => "-7",
- "51" => "-6",
- "52" => "-6",
- "53" => "-6",
- "54" => "-5",
- "55" => "-5",
- "56" => "-5",
- "57" => "-4",
- "58" => "-4",
- "59" => "-4",
- "5A" => "-3",
- "5B" => "-3",
- "5C" => "-3",
- "5D" => "-2",
- "5E" => "-2",
- "5F" => "-2",
- "60" => "-1",
- "61" => "-1",
- "62" => "-1",
- "63" => "-1",
- "64" => "0",
- "65" => "0",
- "66" => "0",
- "67" => "1",
- "68" => "1",
- "69" => "1",
- "6A" => "2",
- "6B" => "2",
- "6C" => "2",
- "6D" => "3",
- "6E" => "3",
- "6F" => "3",
- "70" => "4",
- "71" => "4",
- "72" => "4",
- "73" => "5",
- "74" => "5",
- "75" => "5",
- "76" => "5",
- "77" => "6",
- "78" => "6",
- "79" => "6",
- "7A" => "7",
- "7B" => "7",
- "7C" => "7",
- "7D" => "8",
- "7E" => "8",
- "7F" => "8",
- "80" => "9",
- "81" => "9",
- "82" => "9",
- "83" => "10",
- "84" => "10",
- "85" => "10",
- "86" => "11",
- "87" => "11",
- "88" => "11",
- "89" => "12",
- "8A" => "12",
- "8B" => "12",
- "8C" => "13",
- "8D" => "13",
- "8E" => "13",
- "8F" => "14",
- "90" => "14",
- "91" => "14",
- "92" => "15",
- "93" => "15",
- "94" => "15",
- "95" => "16",
- "96" => "16",
- "97" => "16",
- "98" => "17",
- "99" => "17",
- "9A" => "18",
- "9B" => "18",
- "9C" => "18",
- "9D" => "19",
- "9E" => "19",
- "9F" => "19",
- "A0" => "20",
- "A1" => "20",
- "A2" => "21",
- "A3" => "21",
- "A4" => "21",
- "A5" => "22",
- "A6" => "22",
- "A7" => "22",
- "A8" => "23",
- "A9" => "23",
- "AA" => "24",
- "AB" => "24",
- "AC" => "24",
- "AD" => "25",
- "AE" => "25",
- "AF" => "26",
- "B0" => "26",
- "B1" => "27",
- "B2" => "27",
- "B3" => "27",
- "B4" => "28",
- "B5" => "28",
- "B6" => "29",
- "B7" => "29",
- "B8" => "30",
- "B9" => "30",
- "BA" => "31",
- "BB" => "31",
- "BC" => "32",
- "BD" => "32",
- "BE" => "33",
- "BF" => "33",
- "C0" => "34",
- "C1" => "34",
- "C2" => "35",
- "C3" => "35",
- "C4" => "36",
- "C5" => "36",
- "C6" => "37",
- "C7" => "37",
- "C8" => "38",
- "C9" => "38",
- "CA" => "39",
- "CB" => "40",
- "CC" => "40",
- "CD" => "41",
- "CE" => "41",
- "CF" => "42",
- "D0" => "43",
- "D1" => "43",
- "D2" => "44",
- "D3" => "45",
- "D4" => "45",
- "D5" => "46",
- "D6" => "47",
- "D7" => "48",
- "D8" => "49",
- "D9" => "49",
- "DA" => "50",
- "DB" => "51",
- "DC" => "52",
- "DD" => "53",
- "DE" => "53",
- "DF" => "54",
- "E0" => "55",
- "E1" => "56",
- "E2" => "57",
- "E3" => "59",
- "E4" => "60",
- "E5" => "61",
- "E6" => "62",
- "E7" => "63",
- "E8" => "65",
- "E9" => "66",
- "EA" => "68",
- "EB" => "69",
- "EC" => "71",
- "ED" => "73",
- "EE" => "75",
- "EF" => "77",
- "F0" => "79",
- "F1" => "81",
- "F2" => "82",
- "F3" => "86",
- "F4" => "90",
- "F5" => "93",
- "F6" => "97",
- "F7" => "100",
- "F8" => "100",
- "F9" => "100",
- "FA" => "100",
- "FB" => "100",
- "FC" => "100",
- "FD" => "100",
- "FE" => "100",
- "FF" => "100"
- );
- my %Vallox_temperatureTableReverse = reverse %Vallox_temperatureTable;
- ##################################
- # Mapping of the percentages (eg humidity)
- ##################################
- my %Vallox_percentageTable = (
- "34" => "0",
- "36" => "1",
- "38" => "2",
- "3A" => "3",
- "3C" => "4",
- "3E" => "5",
- "40" => "6",
- "42" => "7",
- "44" => "8",
- "46" => "9",
- "48" => "10",
- "4A" => "11",
- "4C" => "12",
- "4E" => "13",
- "50" => "14",
- "52" => "15",
- "54" => "16",
- "56" => "17",
- "58" => "18",
- "5A" => "19",
- "5C" => "20",
- "5E" => "21",
- "60" => "22",
- "62" => "23",
- "64" => "24",
- "66" => "25",
- "68" => "26",
- "6A" => "27",
- "6C" => "28",
- "6E" => "29",
- "70" => "30",
- "72" => "31",
- "74" => "32",
- "76" => "33",
- "78" => "34",
- "7A" => "35",
- "7C" => "36",
- "7E" => "37",
- "80" => "38",
- "82" => "39",
- "84" => "40",
- "86" => "41",
- "88" => "42",
- "8A" => "43",
- "8C" => "44",
- "8E" => "45",
- "90" => "46",
- "92" => "47",
- "94" => "48",
- "96" => "49",
- "98" => "50",
- "9A" => "51",
- "9C" => "52",
- "9E" => "53",
- "A0" => "54",
- "A2" => "55",
- "A4" => "56",
- "A6" => "57",
- "A8" => "58",
- "AA" => "59",
- "AC" => "60",
- "AE" => "61",
- "B0" => "62",
- "B2" => "63",
- "B4" => "64",
- "B6" => "65",
- "B8" => "66",
- "BA" => "67",
- "BC" => "68",
- "BE" => "69",
- "C0" => "70",
- "C2" => "71",
- "C4" => "72",
- "C6" => "73",
- "C8" => "74",
- "CA" => "75",
- "CC" => "76",
- "CE" => "77",
- "D0" => "78",
- "D2" => "79",
- "D4" => "80",
- "D6" => "81",
- "D8" => "82",
- "DA" => "83",
- "DC" => "84",
- "DE" => "85",
- "E0" => "86",
- "E2" => "87",
- "E4" => "88",
- "E6" => "89",
- "E8" => "90",
- "EA" => "91",
- "EC" => "92",
- "EE" => "93",
- "F0" => "94",
- "F2" => "95",
- "F4" => "96",
- "F6" => "97",
- "F8" => "98",
- "FA" => "99",
- "FC" => "100"
- );
- my %Vallox_percentageTableReverse = reverse %Vallox_percentageTable;
- ##################################
- # Mapping of the faults
- ##################################
- my %Vallox_faultTable = (
- "00" => "No fault stored",
- "05" => "Supply air temperature sensor fault",
- "06" => "Carbon dioxide alarm",
- "07" => "Outdoor air sensor fault",
- "08" => "Extract air sensor fault",
- "09" => "Water radiator danger of freezing",
- "0A" => "Exhaust air sensor fault",
- );
- my %Vallox_faultTableReverse = reverse %Vallox_faultTable;
- ##################################
- # Mapping of the MultiReadings with R/W
- # TODO: Find s.th. more elegant for all MR
- ##################################
- my %Vallox_multiReadingTable_realcmd = (
- "SupplyFan" => "MultiPurpose2",
- "ExhaustFan" => "MultiPurpose2",
- "CO2HigherSpeedRequest" => "Flags2",
- "CO2LowerRatePublicInvitation" => "Flags2",
- "HumidityLowerRatePublicInvitation" => "Flags2",
- "SwitchLowerSpeedRequest" => "Flags2",
- "CO2Alarm" => "Flags2",
- "FrostAlarmSensor" => "Flags2",
- "FrostAlarmWaterRadiator" => "Flags4",
- "MasterSlaveSelection" => "Flags4",
- "PreHeatingStatus" => "Flags5",
- "FireplaceSwitchActivation" => "Flags6",
- "PowerState" => "Select",
- "CO2AdjustState" => "Select",
- "RHAdjustState" => "Select",
- "HeatingState" => "Select",
- "ServiceReminderIndicator" => "Select",
- "AutomaticHumidityBasicLevelSeekerState" => "Program",
- "BoostSwitchMode" => "Program",
- "RadiatorType" => "Program",
- "CascadeAdjust" => "Program",
- "MaxSpeedLimitFunction" => "Program2",
- );
- my %Vallox_multiReadingTable_digit = (
- "SupplyFan" => 3,
- "ExhaustFan" => 5,
- "CO2HigherSpeedRequest" => 0,
- "CO2LowerRatePublicInvitation" => 1,
- "HumidityLowerRatePublicInvitation" => 2,
- "SwitchLowerSpeedRequest" => 3,
- "CO2Alarm" => 6,
- "FrostAlarmSensor" => 7,
- "FrostAlarmWaterRadiator" => 4,
- "MasterSlaveSelection" => 7,
- "PreHeatingStatus" => 7,
- "FireplaceSwitchActivation" => 5,
- "PowerState" => 0,
- "CO2AdjustState" => 1,
- "RHAdjustState" => 2,
- "HeatingState" => 3,
- "ServiceReminderIndicator" => 7,
- "AutomaticHumidityBasicLevelSeekerState" => 4,
- "BoostSwitchMode" => 5,
- "RadiatorType" => 6,
- "CascadeAdjust" => 7,
- "MaxSpeedLimitFunction" => 0,
- );
- ##################################
- # Initialize Buffer fillings
- ##################################
- my $bufferRead = "00";
- my $bufferDevIO = "00";
- my $bufferDebug = "--";
- ##################################
- # basic get commands
- ##################################
- my %Vallox_gets = ( "raw" => "raw" );
- ##################################
- # basic set commands
- ##################################
- my %Vallox_sets = ( "raw" => "raw" );
- ##############################################
- # Custom Functions
- ##############################################
- ##################################
- # Create a valid message to send
- ##################################
- sub Vallox_CreateMsg ($@) {
- my ( $hash, $readingIdentifier ) = @_;
- my $domain = hex "0x"
- . AttrVal( $hash->{NAME}, "ValloxIDDomain", "01" )
- ; # Domain (1 by default)
- my $sender = hex "0x"
- . AttrVal( $hash->{NAME}, "ValloxIDFHEM", "2F" ); # ID of this FHEM
- my $receiver = hex "0x"
- . AttrVal( $hash->{NAME}, "ValloxIDCentral", "11" ); # ID of the central
- my $datatype = hex "0x" . $readingIdentifier;
- my $checksum = ( $domain + $sender + $receiver + $datatype ) % 0x100;
- my $msg =
- lc(
- sprintf( "%02x", $domain )
- . sprintf( "%02x", $sender )
- . sprintf( "%02x", $receiver ) . "00"
- . sprintf( "%02x", $datatype )
- . sprintf( "%02x", $checksum ) );
- return $msg;
- }
- ##############################################
- # Check if a message is valid
- ##############################################
- sub Vallox_ValidateStream ($@) {
- my ( $hash, @a ) = @_;
- my $name = shift @a;
- return undef if ( length($bufferRead) < 12 );
- my $domain = hex "0x" . substr( $bufferRead, 0, 2 );
- my $sender = hex "0x" . substr( $bufferRead, 2, 2 );
- my $receiver = hex "0x" . substr( $bufferRead, 4, 2 );
- my $data_1 = hex "0x" . substr( $bufferRead, 6, 2 );
- my $data_2 = hex "0x" . substr( $bufferRead, 8, 2 );
- my $checksum =
- ( $domain + $sender + $receiver + $data_1 + $data_2 ) % 0x100;
- #++$hash->{"CheckCount"};
- if (
- lc($domain) eq 01
- && lc(
- sprintf( "%02x", $domain )
- . sprintf( "%02x", $sender )
- . sprintf( "%02x", $receiver )
- . sprintf( "%02x", $data_1 )
- . sprintf( "%02x", $data_2 )
- . sprintf( "%02x", $checksum )
- ) eq lc($bufferRead)
- )
- {
- #Log3 ($name, 5, "Vallox: Debug: DO ".$domain." - SE ".$sender." - RE ".$receiver." - D1 ".$data_1." - D2 ".$data_2." - CS ".$checksum." NE ".$bufferRead);
- #++$hash->{"MessageCount"};
- #$hash->{"BufferDatagramRatio"} = "1 : ".$hash->{"CheckCount"} / $hash->{"MessageCount"};
- if (
- (
- ( $sender >= 17 && $sender <= 31 ) || ( $sender >= 33
- && $sender <= 47 )
- )
- && (
- ( $receiver >= 16 && $receiver <= 31 )
- || ( $receiver >= 32
- && $receiver <= 47 )
- )
- )
- {
- return 1;
- }
- else {
- ++$hash->{"ErrorCount"};
- return 2;
- }
- }
- else {
- Log3( $name, 4,
- "Vallox: Debug: DO "
- . $domain
- . " - SE "
- . $sender
- . " - RE "
- . $receiver
- . " - D1 "
- . $data_1
- . " - D2 "
- . $data_2
- . " - CS "
- . $checksum . " NE "
- . $bufferRead );
- return 0;
- }
- }
- ##############################################
- # Change bit in MultiReading
- # (bitnumber = 0 (rightest) - 7 (leftest)!)
- ##############################################
- sub Vallox_ReplaceBit ($@) {
- my ( $hash, $bitstring, $bitnumber, $value ) = @_;
- return
- substr( $bitstring, 0, 8 - $bitnumber - 1 )
- . $value
- . substr( $bitstring, 8 - $bitnumber, $bitnumber );
- }
- ##############################################
- # Update reading bulk for binary reading
- ##############################################
- sub Vallox_ReadingsBulkUpdateMultiReading($@) {
- my ( $hash, $rawReadingType, $readingname, $bitnumber, ) = @_;
- readingsBulkUpdate(
- $hash,
- $readingname,
- substr(
- $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} },
- 8 - $bitnumber - 1, 1
- )
- )
- ; # if (ReadingsVal($hash->{NAME},$readingname,"unknown") ne substr($hash->{"MR_".$Vallox_datatypes{$rawReadingType}},8-$bitnumber-1,1));
- return;
- }
- ##############################################
- # Interpret datagram and handle it
- ##############################################
- sub Vallox_InterpretAndUpdate(@) {
- my ( $hash, $datagram ) = @_;
- my $name = $hash->{NAME};
- my $rawReadingType;
- my $rawReadingValue;
- my $rawReadingChecksum;
- my $singlereading = 1;
- my $fineReadingValue = 1;
- $datagram = uc($datagram);
- # get the type of the datagram
- $rawReadingType = substr( $datagram, 6, 2 );
- # get the value of the datagram
- $rawReadingValue = substr( $datagram, 8, 2 );
- # get the value of the datagram
- $rawReadingChecksum = substr( $datagram, 10, 2 );
- if ( $rawReadingType ne "00" ) {
- # Decoding for the final readings.
- # - rawReading... is the original information from the datagram
- # - fineReading... is the human readable information
- # Starting with the "One information in one datagram"-Section
- # Convert FanSpeeds by the Vallox_levelTable
- if ( $rawReadingType eq "29"
- || $rawReadingType eq "A5"
- || $rawReadingType eq "A9" )
- {
- $fineReadingValue = $Vallox_levelTable{$rawReadingValue};
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (FanSpeed): $datagram (Level $fineReadingValue)"
- );
- # Convert Temperatures by the Vallox_temperatureTable
- }
- elsif ($rawReadingType eq "32"
- || $rawReadingType eq "33"
- || $rawReadingType eq "34"
- || $rawReadingType eq "35"
- || $rawReadingType eq "A4"
- || $rawReadingType eq "A7"
- || $rawReadingType eq "A8"
- || $rawReadingType eq "AF" )
- {
- if ( $rawReadingType eq "A4" && $hash->{BusVersion} eq "1" ) {
- $fineReadingValue = $Vallox_levelTable{$rawReadingValue};
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (HeatingSetPoint): $datagram (Level $fineReadingValue)"
- );
- return;
- }
- else {
- $fineReadingValue = $Vallox_temperatureTable{$rawReadingValue};
- }
- if (
- (
- $rawReadingType eq "32"
- || $rawReadingType eq "33"
- || $rawReadingType eq "34"
- || $rawReadingType eq "35"
- )
- && $fineReadingValue < -40
- )
- {
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (Temperature) invalid: $datagram ($fineReadingValue deg.)"
- );
- return;
- }
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (Temperature): $datagram ($fineReadingValue deg.)"
- );
- # Convert Percentages by the Vallox_percentageTable
- }
- elsif ( $rawReadingType eq "AE" ) {
- $fineReadingValue = $Vallox_percentageTable{$rawReadingValue};
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (Percentage): $datagram ($fineReadingValue pct.)"
- );
- # Convert Faults by the Vallox_faultTable
- }
- elsif ( $rawReadingType eq "36" ) {
- $fineReadingValue = $Vallox_faultTable{$rawReadingValue};
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (Fault): $datagram ($fineReadingValue)"
- );
- # Convert Decimal Values
- }
- elsif ($rawReadingType eq "2B"
- || $rawReadingType eq "2C"
- || $rawReadingType eq "2E"
- || $rawReadingType eq "57"
- || $rawReadingType eq "A6"
- || $rawReadingType eq "79"
- || $rawReadingType eq "8F"
- || $rawReadingType eq "91"
- || $rawReadingType eq "AB"
- || $rawReadingType eq "B0"
- || $rawReadingType eq "B1"
- )
- {
- $fineReadingValue = sprintf( "%d", hex "0x" . $rawReadingValue );
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (Decimal): $datagram ($fineReadingValue)"
- );
- # Convert PostHeating Time Values
- }
- elsif ( $rawReadingType eq "55" || $rawReadingType eq "56" ) {
- $fineReadingValue =
- sprintf( "%d", hex "0x" . $rawReadingValue ) / 2.5;
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (PostHeatingCounter): $datagram ($fineReadingValue)"
- );
- # Convert CellDefrostingSetpointTemperature Values
- }
- elsif ( $rawReadingType eq "B2" ) {
- $fineReadingValue =
- sprintf( "%d", hex "0x" . $rawReadingValue ) / 3;
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (CellDefrostingSetpointTemperature): $datagram ($fineReadingValue)"
- );
- # Convert measured humidity by formula (if it is negative then you don't have a humidity sensor)
- }
- elsif ($rawReadingType eq "2A"
- || $rawReadingType eq "2F"
- || $rawReadingType eq "30" )
- {
- $fineReadingValue =
- ( sprintf( "%d", hex "0x" . $rawReadingValue ) - 51 ) / 2.04;
- # Negative Humidity impossible: No Sensor attatched
- if ( $fineReadingValue < 0 ) {
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (Humidity) invalid: $datagram ($fineReadingValue Perc. rH)"
- );
- return;
- }
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (Humidity): $datagram ($fineReadingValue pct. rH)"
- );
- # Starting with the "Up to eight informations in one datagram"-Section
- # Disabled lines are unused.
- # FanSpeed-Relays
- }
- elsif ( $rawReadingType eq "06" ) {
- $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} } =
- sprintf( '%08b', hex( "0x" . $rawReadingValue ) );
- $singlereading = 0;
- readingsBeginUpdate($hash);
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "Speed1", 0 ); #RO
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "Speed2", 1 ); #RO
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "Speed3", 2 ); #RO
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "Speed4", 3 ); #RO
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "Speed5", 4 ); #RO
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "Speed6", 5 ); #RO
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "Speed7", 6 ); #RO
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "Speed8", 7 ); #RO
- readingsEndUpdate( $hash, 1 );
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (FanSpeed-Relays): $datagram (Bits "
- . $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} }
- . ")" );
- # MultiPurpose1
- }
- elsif ( $rawReadingType eq "07" ) {
- $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} } =
- sprintf( '%08b', hex( "0x" . $rawReadingValue ) );
- $singlereading = 0;
- readingsBeginUpdate($hash);
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "PostHeating", 5 ); # RO
- readingsEndUpdate( $hash, 1 );
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (MultiPurpose1): $datagram (Bits "
- . $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} }
- . ")" );
- #MultiPurpose2
- }
- elsif ( $rawReadingType eq "08" ) {
- $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} } =
- sprintf( '%08b', hex( "0x" . $rawReadingValue ) );
- $singlereading = 0;
- readingsBeginUpdate($hash);
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "DamperMotorPosition", 1 ); #RO
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "FaultSignalRelay", 2 ); #RO
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "SupplyFan", 3 );
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "PreHeating", 4 ); #RO
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "ExhaustFan", 5 );
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "FireplaceBooster", 6 ); #RO
- readingsEndUpdate( $hash, 1 );
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (MultiPurpose2): $datagram (Bits "
- . $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} }
- . ")" );
- #MachineInstalledCO2Sensor
- }
- elsif ( $rawReadingType eq "2D" ) {
- $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} } =
- sprintf( '%08b', hex( "0x" . $rawReadingValue ) );
- $singlereading = 0;
- readingsBeginUpdate($hash);
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "CO2Sensor1", 1 ); #RO
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "CO2Sensor2", 2 ); #RO
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "CO2Sensor3", 3 ); #RO
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "CO2Sensor4", 4 ); #RO
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "CO2Sensor5", 5 ); #RO
- readingsEndUpdate( $hash, 1 );
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (MultiPurpose2): $datagram (Bits "
- . $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} }
- . ")" );
- #Flags2
- }
- elsif ( $rawReadingType eq "6D" ) {
- $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} } =
- sprintf( '%08b', hex( "0x" . $rawReadingValue ) );
- $singlereading = 0;
- readingsBeginUpdate($hash);
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "CO2HigherSpeedRequest", 0 );
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "CO2LowerRatePublicInvitation", 1 );
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "HumidityLowerRatePublicInvitation", 2 );
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "SwitchLowerSpeedRequest", 3 );
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "CO2Alarm", 6 );
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "FrostAlarmSensor", 7 );
- readingsEndUpdate( $hash, 1 );
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (Flags2): $datagram (Bits "
- . $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} }
- . ")" );
- #Flags4
- }
- elsif ( $rawReadingType eq "6F" ) {
- $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} } =
- sprintf( '%08b', hex( "0x" . $rawReadingValue ) );
- $singlereading = 0;
- readingsBeginUpdate($hash);
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "FrostAlarmWaterRadiator", 4 );
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "MasterSlaveSelection", 7 );
- readingsEndUpdate( $hash, 1 );
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (Flags4): $datagram (Bits "
- . $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} }
- . ")" );
- #Flags5
- }
- elsif ( $rawReadingType eq "70" ) {
- $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} } =
- sprintf( '%08b', hex( "0x" . $rawReadingValue ) );
- $singlereading = 0;
- readingsBeginUpdate($hash);
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "PreHeatingStatus", 7 );
- readingsEndUpdate( $hash, 1 );
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (Flags5): $datagram (Bits "
- . $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} }
- . ")" );
- #Flags6
- }
- elsif ( $rawReadingType eq "71" ) {
- $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} } =
- sprintf( '%08b', hex( "0x" . $rawReadingValue ) );
- $singlereading = 0;
- readingsBeginUpdate($hash);
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "RemoteMonitoringControl", 4 ); #RO
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "FireplaceSwitchActivation", 5 );
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "FireplaceBoosterStatus", 6 ); #RO
- readingsEndUpdate( $hash, 1 );
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (Flags6): $datagram (Bits "
- . $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} }
- . ")" );
- # Select
- }
- elsif ( $rawReadingType eq "A3" ) {
- $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} } =
- sprintf( '%08b', hex( "0x" . $rawReadingValue ) );
- $singlereading = 0;
- readingsBeginUpdate($hash);
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "PowerState", 0 );
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "CO2AdjustState", 1 );
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "RHAdjustState", 2 );
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "HeatingState", 3 );
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "FilterGuardIndicator", 4 ); #RO
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "HeatingIndicator", 5 ); #RO
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "FaultIndicator", 6 ); #RO
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "ServiceReminderIndicator", 7 );
- readingsEndUpdate( $hash, 1 );
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (Select): $datagram (Bits "
- . $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} }
- . ")" );
- # Program
- }
- elsif ( $rawReadingType eq "AA" ) {
- $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} } =
- sprintf( '%08b', hex( "0x" . $rawReadingValue ) );
- $singlereading = 0;
- readingsBeginUpdate($hash);
- # ----xxxx - Nibble is one value // # TODO: Adopt Function
- readingsBulkUpdate(
- $hash,
- "HumidityCO2AdjustmentInterval",
- oct(
- "0b" . "0000"
- . substr(
- $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} },
- 4, 4
- )
- )
- )
- if (
- ReadingsVal(
- $name, "HumidityCO2AdjustmentInterval", "unknown"
- ) ne oct(
- "0b" . "0000"
- . substr(
- $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} },
- 4, 4
- )
- )
- );
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "AutomaticHumidityBasicLevelSeekerState", 4 );
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "BoostSwitchMode", 5 );
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "RadiatorType", 6 );
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "CascadeAdjust", 7 );
- readingsEndUpdate( $hash, 1 );
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (Program): $datagram (Bits "
- . $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} }
- . ")" );
- # Program2
- }
- elsif ( $rawReadingType eq "B5" ) {
- $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} } =
- sprintf( '%08b', hex( "0x" . $rawReadingValue ) );
- $singlereading = 0;
- readingsBeginUpdate($hash);
- Vallox_ReadingsBulkUpdateMultiReading( $hash, $rawReadingType,
- "MaxSpeedLimitFunction", 0 );
- readingsEndUpdate( $hash, 1 );
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (Program2): $datagram (Bits "
- . $hash->{ "MR_" . $Vallox_datatypes{$rawReadingType} }
- . ")" );
- # Convert Unused Binarys to bits (Just not to have Hex Readings)
- }
- elsif ( $rawReadingType eq "6C" || $rawReadingType eq "6E" ) {
- $fineReadingValue =
- sprintf( '%08b', hex( "0x" . $rawReadingValue ) );
- Log3( $name, 4,
- "Vallox: Incoming Status-Info (Unused Binary): $datagram (Bits $fineReadingValue)"
- );
- # Everything else
- # All Readings shall be handled before
- }
- else {
- $fineReadingValue = $rawReadingValue;
- $singlereading = 1;
- if ( $rawReadingType eq "B3" ) {
- Log3( $name, 4, "Vallox: Incoming CO2SetPoint-Part (Upper): $datagram");
- } elsif ( $rawReadingType eq "B4" ) {
- Log3( $name, 4, "Vallox: Incoming CO2SetPoint-Part (Lower): $datagram");
- } else {
- Log3( $name, 2, "Vallox: Incoming unhandled datagram: $datagram" );
- }
- }
- if ( $Vallox_datatypes{$rawReadingType} ) {
- if ( $singlereading == 1 ) {
- Log3( $name, 5, "Vallox: Update Reading: $fineReadingValue" );
- readingsSingleUpdate( $hash, $Vallox_datatypes{$rawReadingType},
- $fineReadingValue, 1 );
- # If this is a CO2SetPointLower && CO2SetPointUpper has been set, write CO2SetPoint
- if ($rawReadingType eq "B4" && ReadingsVal( $name, "CO2SetPointUpper", "unknown" ) ne "unknown" ) {
- my $CO2SetPoint = ReadingsVal( $name, "CO2SetPointUpper", "unknown" ) . $fineReadingValue;
-
- readingsSingleUpdate( $hash, "CO2SetPoint", hex $CO2SetPoint , 1 );
- }
- # Efficiency Calculation
- # Is this Reading a Temp?
- if (
- substr( $Vallox_datatypes{$rawReadingType}, 0, 4 ) eq
- "Temp" )
- {
- # If HRC is in Bypass - Efficiency is 0
- if ( ReadingsVal( $name, "DamperMotorPosition", 1 ) == 1 ) {
- readingsSingleUpdate( $hash, "EfficiencyIn", 0, 1 );
- readingsSingleUpdate( $hash, "EfficiencyOut", 0, 1 );
- readingsSingleUpdate( $hash, "EfficiencyAverage", 0,
- 1 );
- Log3( $name, 5,
- "Vallox: Efficiency Override: HRC Bypass" );
- }
- else {
- my (
- $EfficiencyIn, $EfficiencyOut, $TempIncoming,
- $TempOutside, $TempInside, $TempExhaust
- ) = 0;
- # Efficiency on Keep Temp Inside
- # Do we have all nessecary Readings?
- if ( ReadingsVal( $name, "TempIncoming", "unknown" ) ne
- "unknown"
- && ReadingsVal( $name, "TempOutside", "unknown" ) ne
- "unknown"
- && ReadingsVal( $name, "TempInside", "unknown" ) ne
- "unknown" )
- {
- $TempIncoming =
- ReadingsVal( $name, "TempIncoming", -100 );
- $TempOutside =
- ReadingsVal( $name, "TempOutside", -100 );
- $TempInside =
- ReadingsVal( $name, "TempInside", -100 );
- # Prevent DIV/0 (if Inside=Outside the HRC does nothing = 100% Efficient)
- if ( $TempInside - $TempOutside != 0 ) {
- $EfficiencyIn =
- ( $TempIncoming - $TempOutside ) /
- ( $TempInside - $TempOutside ) * 100;
- $EfficiencyIn = 100 if ( $EfficiencyIn > 100 );
- Log3( $name, 5,
- "Vallox: Efficiency Inside: ("
- . $TempIncoming . "-"
- . $TempIncoming . ")/("
- . $TempInside . "-"
- . $TempOutside
- . ")*100 = "
- . $EfficiencyIn );
- readingsSingleUpdate( $hash, "EfficiencyIn",
- $EfficiencyIn, 1 );
- }
- else {
- Log3( $name, 5,
- "Vallox: Efficiency Inside (DIV/0 Prevention): ("
- . $TempIncoming . "-"
- . $TempIncoming . ")/("
- . $TempInside . "-"
- . $TempOutside
- . ")*100 = 100" );
- readingsSingleUpdate( $hash, "EfficiencyIn",
- 100, 1 );
- }
- }
- # Efficiency on Keep Temp Outside
- # Do we have all nessecary Readings?
- if ( ReadingsVal( $name, "TempOutside", "unknown" ) ne
- "unknown"
- && ReadingsVal( $name, "TempIncoming", "unknown" )
- ne "unknown"
- && ReadingsVal( $name, "TempExhaust", "unknown" ) ne
- "unknown" )
- {
- $TempOutside =
- ReadingsVal( $name, "TempOutside", -100 );
- $TempIncoming =
- ReadingsVal( $name, "TempIncoming", -100 );
- $TempExhaust =
- ReadingsVal( $name, "TempExhaust", -100 );
- # Prevent DIV/0 (if Inside=Outside the HRC does nothing = 100% Efficient)
- if ( $TempOutside - $TempIncoming != 0 ) {
- $EfficiencyOut =
- ( $TempExhaust - $TempIncoming ) /
- ( $TempOutside - $TempIncoming ) * 100;
- $EfficiencyOut = 100
- if ( $EfficiencyOut > 100 );
- Log3( $name, 5,
- "Vallox: Efficiency Outside: ("
- . $TempExhaust . "-"
- . $TempIncoming . ")/("
- . $TempOutside . "-"
- . $TempIncoming
- . ")*100 = "
- . $EfficiencyOut );
- readingsSingleUpdate( $hash, "EfficiencyOut",
- $EfficiencyOut, 1 );
- }
- else {
- Log3( $name, 5,
- "Vallox: Efficiency Outside (DIV/0 Protection): ("
- . $TempExhaust . "-"
- . $TempIncoming . ")/("
- . $TempOutside . "-"
- . $TempIncoming
- . ")*100 = 100" );
- readingsSingleUpdate( $hash, "EfficiencyOut",
- 100, 1 );
- }
- }
- # Average Efficiency
- if ( ReadingsVal( $name, "EfficiencyIn", "unknown" ) ne
- "unknown"
- && ReadingsVal( $name, "EfficiencyOut", "unknown" )
- ne "unknown" )
- {
- $EfficiencyIn =
- ReadingsVal( $name, "EfficiencyIn", -100 );
- $EfficiencyOut =
- ReadingsVal( $name, "EfficiencyOut", -100 );
- my $EfficiencyAverage =
- ( $EfficiencyIn + $EfficiencyOut ) / 2;
- Log3( $name, 5,
- "Vallox: Efficiency Average: ("
- . $EfficiencyIn . "+"
- . $EfficiencyOut
- . ")/2 = "
- . $EfficiencyAverage );
- readingsSingleUpdate( $hash, "EfficiencyAverage",
- $EfficiencyAverage, 1 );
- }
- else {
- Log3(
- $name, 5,
- "Vallox: Efficiency Average unknown: ("
- . ReadingsVal( $name, "EfficiencyIn",
- "unknown" )
- . "+"
- . ReadingsVal( $name, "EfficiencyOut",
- "unknown" )
- . ")/2"
- );
- }
- }
- }
- }
- }
- else {
- Log3( $name, 4,
- "Vallox: Datagram not in Datatypes-Table: " . $datagram );
- }
- }
- else {
- Log3( $name, 5, "Vallox: Incoming Status-Request: $datagram" );
- }
- }
- ##############################################
- # Create Datagram and send it (Set)
- ##############################################
- sub Vallox_CreateAndSend(@) {
- my ( $hash, $domain, $sender, $receiver, $datatype, $datavalue, $broadcast ) = @_;
- my $name = $hash->{NAME};
- my $checksum;
- my $msg;
-
- if ($broadcast == 1) {
-
- ## Send to all Remotes
- $checksum = ( $domain + $sender + 0x20 + $datatype + $datavalue ) % 0x100;
- $msg =
- lc(
- sprintf( "%02x", $domain )
- . sprintf( "%02x", $sender )
- . sprintf( "%02x", 0x20 )
- . sprintf( "%02x", $datatype )
- . sprintf( "%02x", $datavalue )
- . sprintf( "%02x", $checksum ) );
- DevIo_SimpleWrite( $hash, $msg, 1 );
- Log3( $name, 3, "Vallox: Command " . $msg . " has been sent." );
-
-
- ## Send to all ventilation units
- $checksum = ( $domain + $sender + 0x10 + $datatype + $datavalue ) % 0x100;
- $msg =
- lc(
- sprintf( "%02x", $domain )
- . sprintf( "%02x", $sender )
- . sprintf( "%02x", 0x10 )
- . sprintf( "%02x", $datatype )
- . sprintf( "%02x", $datavalue )
- . sprintf( "%02x", $checksum ) );
- DevIo_SimpleWrite( $hash, $msg, 1 );
- Log3( $name, 3, "Vallox: Command " . $msg . " has been sent." );
-
- }
-
- $checksum = ( $domain + $sender + $receiver + $datatype + $datavalue ) % 0x100;
- $msg =
- lc(
- sprintf( "%02x", $domain )
- . sprintf( "%02x", $sender )
- . sprintf( "%02x", $receiver )
- . sprintf( "%02x", $datatype )
- . sprintf( "%02x", $datavalue )
- . sprintf( "%02x", $checksum ) );
- DevIo_SimpleWrite( $hash, $msg, 1 );
- Log3( $name, 3, "Vallox: Command " . $msg . " has been sent." );
- if ( AttrVal( $hash->{NAME}, "ValloxProcessOwnCommands", "0" ) == 1
- || $hash->{BusVersion} eq "1" )
- {
- Vallox_InterpretAndUpdate( $hash, $msg );
- Log3( $name, 3,
- "Vallox: Command " . $msg . " has been internal processed." );
- }
- if ( AttrVal( $hash->{NAME}, "ValloxForceBroadcast", "0" ) == 1
- || $hash->{BusVersion} eq "1" )
- {
- $checksum =
- ( $domain + $sender + 0x10 + $datatype + $datavalue ) % 0x100;
- $msg =
- lc(
- sprintf( "%02x", $domain )
- . sprintf( "%02x", $sender )
- . 10
- . sprintf( "%02x", $datatype )
- . sprintf( "%02x", $datavalue )
- . sprintf( "%02x", $checksum ) );
- DevIo_SimpleWrite( $hash, $msg, 1 );
- Log3( $name, 3,
- "Vallox: Broadcast-Command " . $msg . " has been sent." );
- $checksum =
- ( $domain + $sender + 0x20 + $datatype + $datavalue ) % 0x100;
- $msg =
- lc(
- sprintf( "%02x", $domain )
- . sprintf( "%02x", $sender )
- . 20
- . sprintf( "%02x", $datatype )
- . sprintf( "%02x", $datavalue )
- . sprintf( "%02x", $checksum ) );
- DevIo_SimpleWrite( $hash, $msg, 1 );
- Log3( $name, 3,
- "Vallox: Broadcast-Command " . $msg . " has been sent." );
- }
- }
- ##############################################
- # Default Functions
- ##############################################
- ##################################
- sub Vallox_Initialize($) {
- my ($hash) = @_;
- require "$attr{global}{modpath}/FHEM/DevIo.pm";
- $hash->{DefFn} = "Vallox_Define";
- $hash->{UndefFn} = "Vallox_Undef";
- $hash->{DeleteFn} = "Vallox_Delete";
- $hash->{SetFn} = "Vallox_Set";
- $hash->{GetFn} = "Vallox_Get";
- $hash->{AttrFn} = "Vallox_Attr";
- # $hash->{NotifyFn} = "Vallox_Notify";
- $hash->{ReadFn} = "Vallox_Read";
- # $hash->{ReadyFn} = "Vallox_Ready";
- $hash->{ShutdownFn} = "Vallox_Shutdown";
- $hash->{AttrList} =
- "ValloxBufferDebug:0,1 ValloxForceBroadcast:0,1 ValloxProcessOwnCommands:0,1 ValloxIDDomain ValloxIDFHEM ValloxIDCentral "
- . $readingFnAttributes;
- }
- ##################################
- sub Vallox_Define($) {
- my ( $hash, $def ) = @_;
- my @a = split( "[ \t][ \t]*", $def );
- if ( @a != 3 && @a != 4 ) {
- my $msg =
- "wrong syntax: define <name> Vallox devicename[\@baudrate] [busversion]";
- Log3 undef, 2, "Vallox: " . $msg;
- return $msg;
- }
- DevIo_CloseDev($hash);
- my $name = $a[0];
- my $dev = $a[2];
- $hash->{BusVersion} = "2";
- $dev .= "\@9600" if ( $dev !~ m/\@/ && $def !~ m/:/ );
- $hash->{DeviceName} = $dev;
- if ( @a == 4 ) {
- $hash->{BusVersion} = $a[3];
- }
- if ( $hash->{BusVersion} eq "1" ) {
- %Vallox_datatypes =
- ( %Vallox_datatypes_legacy1, %Vallox_datatypes_base );
- %Vallox_datatypesReverse =
- ( %Vallox_datatypesReverse_legacy1, %Vallox_datatypesReverse_base );
- }
- else {
- %Vallox_datatypes = %Vallox_datatypes_base;
- %Vallox_datatypesReverse = %Vallox_datatypesReverse_base;
- }
- my $ret = DevIo_OpenDev( $hash, 0, undef );
- return $ret;
- }
- ##################################
- sub Vallox_Undef($$) {
- my ( $hash, $name ) = @_;
- DevIo_CloseDev($hash);
- RemoveInternalTimer($hash);
- return undef;
- }
- ##################################
- sub Vallox_Delete($$) {
- my ( $hash, $name ) = @_;
- return undef;
- }
- ##################################
- sub Vallox_Get($@) {
- my ( $hash, @a ) = @_;
- return "\"get Vallox\" needs at least one argument" if ( @a < 2 );
- my $name = shift @a;
- my $cmd = shift @a;
- my $arg = shift @a;
- # "reading" is a predefined list of readings from the bus
- if ( $cmd eq "reading" ) {
-
- my $msg;
-
- if ($arg eq "CO2SetPoint") {
-
- $msg = Vallox_CreateMsg( $hash, "b3" );
- DevIo_SimpleWrite( $hash, $msg, 1 );
- Log3( $name, 3, "Vallox: Request " . $msg . " has been sent." );
-
- $msg = Vallox_CreateMsg( $hash, "b4" );
- DevIo_SimpleWrite( $hash, $msg, 1 );
- Log3( $name, 3, "Vallox: Request " . $msg . " has been sent." );
-
- } else {
- my $argKey = $Vallox_datatypesReverse{$arg};
- $msg = Vallox_CreateMsg( $hash, $argKey );
- DevIo_SimpleWrite( $hash, $msg, 1 );
- Log3( $name, 3, "Vallox: Request " . $msg . " has been sent." );
- }
- return undef;
- # "update" shall be ask for all possible data.
- # Not working at the moment. Need a new idea :(
- }
- elsif ( $cmd eq "update" ) {
- while ( my ( $argKey, $argValue ) = each %Vallox_datatypes ) {
- my $msg = Vallox_CreateMsg( $hash, $argKey );
- DevIo_SimpleWrite( $hash, $msg, 1 );
- }
- return undef;
- # "raw is a custom Hex Code
- }
- elsif ( $cmd eq "raw" ) {
- return "Usage: get $name raw {HexValue}"
- if ( !defined($arg) || $arg =~ m/[^a-fA-F0-9]{2}/ );
- my $msg = Vallox_CreateMsg( $hash, $arg );
- DevIo_SimpleWrite( $hash, $msg, 1 );
- Log3( $name, 3, "Vallox: Request " . $msg . " has been sent." );
- return undef;
- }
- else {
- my $retmsg;
- my @commandList = keys %Vallox_gets;
- my $commandCount = keys %Vallox_gets;
- my @readingList = keys %Vallox_datatypesReverse;
- my $readingCount = keys %Vallox_datatypesReverse;
- $retmsg .= join( " ", @commandList ) if ( $commandCount > 0 );
- if ( $readingCount > 0 ) {
- $retmsg .= " reading:" . join( ",", sort @readingList );
-
- $retmsg .= ",CO2SetPoint";
- $readingCount = $readingCount + 1;
- }
- ## Ich kann nicht alle befehle bulken. ... :(
- # $retmsg .= " update:noArg";
- Log3( $name, 2, "Vallox: Unknown argument $cmd." )
- if ( $cmd ne '?' && length $cmd );
- return "Unknown argument $cmd, choose one of " . $retmsg;
- }
- }
- ##################################
- sub Vallox_Set($@) {
- my ( $hash, @a ) = @_;
- if ( @a < 2 ) {
- return "\"set Vallox\" needs at least an argument";
- }
-
- my $domain = hex "0x"
- . AttrVal( $hash->{NAME}, "ValloxIDDomain", "01" )
- ; # Domain (1 by default)
- my $sender = hex "0x"
- . AttrVal( $hash->{NAME}, "ValloxIDFHEM", "2F" ); # ID of this FHEM
- my $receiver = hex "0x"
- . AttrVal( $hash->{NAME}, "ValloxIDCentral", "11" ); # ID of the central
- my $broadcast = 0;
- my $name = shift @a;
- my $cmd = shift @a;
- my $arg = shift @a;
- my $datatype;
- my $datavalue;
- my $setCommands;
- my @commandList = keys %Vallox_sets;
- my $commandCount = keys %Vallox_sets;
- $setCommands .= join( " ", @commandList ) if ( $commandCount > 0 );
- $setCommands .= " FanSpeed:slider,1,1,8";
- $setCommands .= " FanSpeedMin:slider,1,1,8";
- $setCommands .= " FanSpeedMax:slider,1,1,8";
- $setCommands .= " BasicHumidityLevel:slider,0,1,100";
- $setCommands .= " HeatRecoveryCellBypassSetpointTemperature:slider,0,1,20";
- $setCommands .= " ServiceReminderMonths:slider,1,1,15";
- $setCommands .= " DCFanInputAdjustment:slider,0,1,100";
- $setCommands .= " DCFanOutputAdjustment:slider,0,1,100";
- $setCommands .= " CellDefrostingSetpointTemperature:slider,0,1,10";
- $setCommands .= " HeatingSetPoint:slider,10,1,30";
- $setCommands .= " CO2SetPoint:slider,500,100,2000";
- foreach my $MR_key ( keys %Vallox_multiReadingTable_realcmd ) {
- $setCommands .= " " . $MR_key . ":0,1";
- }
- # MR: Prepare Values and Command for datagram
- if ( exists( $Vallox_multiReadingTable_realcmd{$cmd} )
- && exists( $hash->{ "MR_" . $Vallox_multiReadingTable_realcmd{$cmd} } )
- )
- {
- # TODO: Integrate get before set;
- if ($hash->{ "MR_" . $Vallox_multiReadingTable_realcmd{$cmd} } ) {
- return
- "Vallox: Internal "
- . $Vallox_multiReadingTable_realcmd{$cmd}
- . " empty ("
- . $hash->{ "MR_" . $cmd }
- . "). Read "
- . $Vallox_multiReadingTable_realcmd{$cmd}
- . " first!";
- }
- $arg = Vallox_ReplaceBit(
- $hash,
- $hash->{ "MR_" . $Vallox_multiReadingTable_realcmd{$cmd} },
- $Vallox_multiReadingTable_digit{$cmd}, $arg
- );
- $cmd = $Vallox_multiReadingTable_realcmd{$cmd};
- }
- ## TODO
- if ( exists $Vallox_datatypesReverse{$cmd} ) {
- $datatype = hex "0x" . $Vallox_datatypesReverse{$cmd};
- # Method: FSM
- if ( $datatype == 0x29 || $datatype == 0xA5 || $datatype == 0xA9 ) {
- $datavalue = hex "0x" . $Vallox_levelTableReverse{$arg};
- }
- # Method: PCTM
- elsif ( $datatype == 0xAE ) {
- $datavalue = hex "0x" . $Vallox_percentageTableReverse{$arg};
- }
- # Method: TM
- elsif ( $datatype == 0xA4 || $datatype == 0xAF ) {
- $datavalue = hex "0x" . $Vallox_temperatureTableReverse{$arg};
- }
- # Method: DF
- elsif ( $datatype == 0xA6 || $datatype == 0xB0 || $datatype == 0xB1 ) {
- $datavalue = hex "0x" . sprintf("%x", $arg);
- }
- # Method: CDSTF
- elsif ( $datatype == 0xB2 ) {
- $datavalue = hex "0x" . sprintf("%x", $arg * 3);
- }
- # All other is Hex Input
- else {
- $datavalue = hex "0x" . $arg;
- }
- Vallox_CreateAndSend($hash, $domain, $sender, $receiver, $datatype, $datavalue, $broadcast);
- }
- elsif ( $cmd eq "CO2SetPoint" ) {
- $broadcast = 1;
-
- my $datatype_high = hex "0xb3";
- my $datavalue_high = hex "0x" . substr( sprintf("%04x", $arg), 0, 2 );
- Vallox_CreateAndSend($hash, $domain, $sender, $receiver, $datatype_high, $datavalue_high, $broadcast);
-
- ## Sleep is needed due to broadcast. Message cache on bus devices seems very limited.
- sleep(1);
-
- my $datatype_low = hex "0xb4";
- my $datavalue_low = hex "0x" . substr( sprintf("%04x", $arg), 2, 2 );
- Vallox_CreateAndSend($hash, $domain, $sender, $receiver, $datatype_low, $datavalue_low, $broadcast);
-
- }
- elsif ( $cmd eq "raw" ) {
- $datatype = hex "0x" . substr( $arg, 0, 2 );
- $datavalue = hex "0x" . substr( $arg, 2, 2 );
- Vallox_CreateAndSend($hash, $domain, $sender, $receiver, $datatype, $datavalue, $broadcast);
- }
- else {
- Log3( $name, 2, "Vallox: Unknown argument $cmd." )
- if ( $cmd ne '?' && length $cmd );
- return "Unknown argument $cmd, choose one of " . $setCommands;
- }
-
- return undef;
- }
- sub Vallox_Attr(@) {
- my ( $cmd, $name, $aName, $aVal ) = @_;
- # $cmd can be "del" || "set"
- # $name is device name
- # aName and aVal are Attribute name and value
- if ( $cmd eq "set" ) {
- if ( $aName eq "ValloxIDDomain"
- || $aName eq "ValloxIDFHEM"
- || $aName eq "ValloxIDCentral" )
- {
- if ( $aVal =~ m/[^a-fA-F0-9]/ || length($aVal) != 2 ) {
- Log3 $name, 2,
- "Vallox: Invalid HexValue in attr $name $aName $aVal: $@";
- return "Invalid HexValue $aVal";
- }
- }
- }
- return undef;
- }
- sub Vallox_Read($) {
- my ($hash) = @_;
- my $name = $hash->{NAME};
- my $datagram;
- my $rawReadingType;
- my $rawReadingValue;
- my $rawReadingChecksum;
- my $singlereading = 1;
- my $fineReadingValue = 1;
- my $bufferDebugName = AttrVal( $hash->{NAME}, "ValloxBufferDebug", "0" );
- # read from serial device
- my $buf = DevIo_SimpleRead($hash);
- return "" if ( !defined($buf) );
- # Convert read data to hex and add to debug if nessecary
- if ( $bufferDebugName eq 1 ) {
- $hash->{"BufferDebug"} .= unpack( 'H*', $buf );
- }
- # Convert read data to hex and fill DevIO-Buffer
- $bufferDevIO .= unpack( 'H*', $buf );
- # DO Run Validation until DevIO-Buffer is less than 2 chars long
- do {
- # If DevIO-Buffer is filled add difference to 14 Chars to ReadBuffer and remove it from DevIO-Buffer
- if ( length($bufferDevIO) >= 2 ) {
- my $bufferReadSpace = 14 - length($bufferRead);
- $bufferRead .= substr( $bufferDevIO, 0, $bufferReadSpace );
- # If the bufferDevIO buffer is shorter than the filling, set it to empty to avoid error
- if ( length($bufferDevIO) >= $bufferReadSpace ) {
- $bufferDevIO = substr( $bufferDevIO, $bufferReadSpace );
- }
- else {
- $bufferDevIO = "";
- }
- }
- #$hash->{"BufferDevIOLength"} = length($bufferDevIO);
- # Once ReadBuffer filled up, remove first Byte
- if ( length($bufferRead) >= 14 ) {
- $bufferRead = substr( $bufferRead, 2, 12 );
- }
- # If ReadBuffer has valid length start validating content
- if ( length($bufferRead) == 12 ) {
- if ( Vallox_ValidateStream($hash) == 1 ) {
- Log3( $name, 5, "Vallox: Buffer: " . $bufferRead );
- my $datagram = uc($bufferRead);
- Vallox_InterpretAndUpdate( $hash, $datagram );
- }
- elsif ( Vallox_ValidateStream($hash) == 2 ) {
- Log3( $name, 4, "Vallox: Invalid Status-Request: $bufferRead" );
- }
- }
- } while ( length($bufferDevIO) >= 2 );
- }
- sub Vallox_Shutdown($) {
- my ($hash) = @_;
- DevIo_CloseDev($hash);
- return undef;
- }
- 1;
- =pod
- =item device
- =item summary Reads and writes parameters via RS485 from and to a Vallox ventilation bus.
- =item summary_DE Liest und schreibt über RS485 aus und in einen Bus einer Vallox Belüftungsanlage
- =begin html
- <a name="Vallox"></a>
- <h3>Vallox</h3>
- <div>
- <ul>
- Vallox is a manufacturer for ventilation devices.
- <br>
- Their products have a built-in RS485-Interface on the central ventilation unit as well as on connected control units on which all control communication is handeled.
- <br>
- More Info on the particular <a href="http://www.fhemwiki.de/wiki/Vallox">page of FHEM-Wiki</a> (in German).
- <br>
-
- <br>
-
- <a name="Valloxdefine"></a>
- <b>Define</b>
- <ul>
- <code>define <name> Vallox <RS485-Device[@baud]> [BusVersion]</code><br>
- If the baudrate is omitted, it is set to 9600 (default Vallox baudrate).<br>
- The BusVersion can be set to 1 for older systems. (Default: 2).<br>
- <br>
- Example: <code>define Ventilation Vallox /dev/ttyUSB1</code>
- </ul>
- <br>
-
- <a name="Valloxset"></a>
- <b>Set</b>
- <ul>
- <li><code>FanSpeed < 1-8 ></code>
- <br>
- Allows to set the fan speed (1 = lowest; 8 = highest).<br>
- </li><br>
- <li><code>BasicHumidityLevel < 0-100 ></code>
- <br>
- Allows to set the basic humidity level in percentage.<br>
- </li><br>
- <li><code>HeatRecoveryCellBypassSetpointTemperature < 0-20 ></code>
- <br>
- Allows to set the heat recovery cell bypass setpoint temperature.<br>
- </li><br>
- <li><code>raw < HexValue ></code><br>
- HexValue is two 2-digit hex number to identify the type and value of setting.
- </li><br>
- <br>
- Example to set the fan speed to 3:<br>
- <code>set Ventilation raw 2907</code><br>
- or:<br>
- <code>set Ventilation FanSpeed 3</code>
- </ul>
- <br>
-
- <a name="Valloxget"></a>
- <b>Get</b>
- <ul>
- <li><code>reading < readingname ></code>
- <br>
- Allows to get any predefined reading.<br>
- </li><br>
- <li><code>raw < HexValue ></code><br>
- HexValue is a 2-digit hex number to identify the requested reading.
- </li><br>
- </ul>
- <br>
-
- <a name="Valloxattr"></a>
- <b>Attributes</b>
- <ul><li><code>ValloxIDDomain < HexValue ></code>
- <br>
- HexValue is a 2-digit hex number to identify the "address" of the bus domain. (01 by default).
- </li><br>
- <li><code>ValloxIDCentral < HexValue ></code>
- <br>
- HexValue is a 2-digit hex number to identify the "address" of the central ventilation unit. (11 by default).<br>
- In a normal installation ventilation units in the scope 11 to 19 and are addressed with 10 for broadcast-messages.
- </li><br>
- <li><code>ValloxIDFHEM < HexValue ></code>
- <br>
- HexValue is a 2-digit hex number to identify the "address" of this system as a virtual control terminal. (2F by default)<br>
- In a normal installation control terminals are in the scope 21 to 29 and are addressed with 20 for broadcast-messages.<br>
- The address must be unique.<br>
- The "panel address" of the physical control terminal can be set on the settings of it. Possible values are 1-15 which is the second digit of the Hex-Value (1-F). The first digit is always 2.<br>
- The physical control terminal is usually 21.
- </li><br>
- <li><code>ValloxBufferDebug < 0/1 ></code>
- <br>
- When 1, modul creates an Internal which fills with the raw Hex-Data from the bus. DEBUG ONLY! (0 by default).
- </li><br>
- <li><code>ValloxForceBroadcast < 0/1 ></code>
- <br>
- When 1, modul sends commands not only to the central ventilation unit (11) but to all possible addresses by broadcast (10/20). This is sometimes nessecary for older systems. (0 by default; Function always on on BusVersion 1).
- </li><br>
- <li><code>ValloxProcessOwnCommands < 0/1 ></code>
- <br>
- When 1, modul sends commands not only to the bus but processes it as a received reading. This is sometimes nessecary for older systems. (0 by default; Function always on on BusVersion 1).
- </li><br>
- <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
- </ul>
- </ul>
- </div>
- =end html
- =begin html_DE
- <a name="Vallox"></a>
- <h3>Vallox</h3>
- <div>
- <ul>
- Vallox ist ein Hersteller von Belüftungsanlagen mit Wärmetauscher.
- <br>
- Die Systeme verfügen sowohl an der zentralen Lüftungskomponente, als auch an den Terminals über eine RS485-Schnittstelle über die die gesamte interne Kommunikation abgewickelt wird.
- <br>
- Mehr Informationen sind auf der <a href="http://www.fhemwiki.de/wiki/Vallox">FHEM-Wiki-Seite</a> verfügbar.
- <br>
-
- <br>
-
- <a name="Valloxdefine"></a>
- <b>Define</b>
- <ul>
- <code>define <name> Vallox <RS485-Device[@baud]> [BusVersion]</code><br>
- Wird die Baudrate weggelassen wird mit 9600 baud kommuniziert. (Standardrate des Vallox-Busses).<br>
- Die BusVersion kann bei älteren Anlagen auf 1 gesetzt werden. (Standard: 2).<br>
- <br>
- Beispiel: <code>define Ventilation Vallox /dev/ttyUSB1</code>
- </ul>
- <br>
-
- <a name="Valloxset"></a>
- <b>Set</b>
- <ul>
- <li><code>FanSpeed < 1-8 ></code>
- <br>
- Erlaubt das Ändern der Lüftergeschwindigkeit (1 = minimal; 8 = maximal).<br>
- </li><br>
- <li><code>BasicHumidityLevel < 0-100 ></code>
- <br>
- Erlaubt das Ändern des Luftfeuchtigkeits-Grenzwertes (Terminaldisplay: <code>Grenzwert %RH</code>).<br>
- </li><br>
- <li><code>HeatRecoveryCellBypassSetpointTemperature < 0-20 ></code>
- <br>
- Erlaubt das Ändern des Grenzwertes für den Wärmetauscher-Bypass (Terminaldisplay: <code>WRG Bypass</code>)<br>
- </li><br>
- <li><code>raw < HexWert ></code><br>
- HexWert sind <u>zwei</u> 2-stellige Hex-Zahlen, welche den Typ und den Wert der Einstellung identifiziert.
- </li><br>
- <br>
- Beispiel um die Lüftergeschwindigkeit auf 3 zu setzen:<br>
- <code>set Ventilation raw 2907</code><br>
- oder:<br>
- <code>set Ventilation FanSpeed 3</code>
- </ul>
- <br>
-
- <a name="Valloxget"></a>
- <b>Get</b>
- <ul>
- <li><code>reading < readingname ></code>
- <br>
- Erlaubt das Auslesen der vorgegebenen Datenpunkte aus dem Bus.<br>
- </li><br>
- <li><code>raw < HexWert ></code><br>
- HexWert ist <u>eine</u> 2-stellige Hex-Zahl, welche den Typ der abzufragenden Einstellung identifiziert.
- </li><br>
- </ul>
- <br>
-
- <a name="Valloxattr"></a>
- <b>Attribute</b>
- <ul><li><code>ValloxIDDomain < HexWert ></code>
- <br>
- HexWert ist eine 2-stellige Hex-Zahl die als "Adresse" der Bus-Domäne dient. (Standard: 01).
- </li><br>
- <li><code>ValloxIDCentral < HexWert ></code>
- <br>
- HexWert ist eine 2-stellige Hex-Zahl die als "Adresse" der zentralen Ventilationseinheit dient. (Standard: 11).<br>
- In einer normalen Umgebung werden die Ventilationseinheiten mit 11 - 1F adressiert. 10 ist die Broadcast-Adresse.<br>
- </li><br>
- <li><code>ValloxIDFHEM < HexWert ></code>
- <br>
- HexWert ist eine 2-stellige Hex-Zahl die als "Adresse" dieses Systems als virtuelles Kontrollterminal dient. (Standard: 2F).<br>
- Sie darf nicht bereits im Bus genutzt werden.<br>
- In einer normalen Umgebung werden die Kontrollterminals mit 21 - 2F adressiert. 20 ist die Broadcast-Adresse.<br>
- In den Einstellungen der physikalisch vorhandenen Terminals kann die "FBD-Adresse" des jeweiligen Terminals eingestellt werden.<br>
- Hierbei stehen die Werte 1-15 zur Verfügung, was der zweiten Stelle dieser Adresse (1-F) entspricht. Die erste Stelle ist immer 2.<br>
- Das physikalische Kontrollterminal ist üblicherweise die 21.
- </li><br>
- <li><code>ValloxBufferDebug < 0/1 ></code>
- <br>
- Wenn 1, erzeugt das Modul ein Internal in welches die rohen Hex-Daten aus dem Bus herein geschrieben. NUR ZUM DEBUGGEN! (Standard: 0).
- </li><br>
- <li><code>ValloxForceBroadcast < 0/1 ></code>
- <br>
- Wenn 1, sendet das Modul die Befehle nicht nur an die zentrale Ventilationseinheit (11), sondern auch an alle Broadcast-Adressen (10/20). Dies ist manchmal bei älteren Anlagen notwendig, wenn sich die Anzeige auf den Kontrollterminals nicht mit aktualisiert. (Standard: 0; Funktion immer an bei BusVersion 1).
- </li><br>
- <li><code>ValloxProcessOwnCommands < 0/1 ></code>
- <br>
- Wenn 1, behandelt das Modul die eigenen Befehle auch als Empfangene Befehle und verarbeitet sie intern weiter. Dies ist manchmal bei älteren Anlagen notwendig. (Standard: 0; Funktion immer an bei BusVersion 1).
- </li><br>
- <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
- </ul>
- </ul>
- </div>
- =end html_DE
- =cut
|