2022-05-21 18:40:01 +00:00
|
|
|
/*
|
|
|
|
Copyright (C) 2020-2022 Fredrik Öhrström (gpl-3.0-or-later)
|
|
|
|
|
|
|
|
This program 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 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include"meters_common_implementation.h"
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
struct Driver : public virtual MeterCommonImplementation
|
|
|
|
{
|
|
|
|
Driver(MeterInfo &mi, DriverInfo &di);
|
|
|
|
};
|
|
|
|
|
|
|
|
static bool ok = registerDriver([](DriverInfo&di)
|
|
|
|
{
|
|
|
|
di.setName("ei6500");
|
|
|
|
di.setMeterType(MeterType::SmokeDetector);
|
|
|
|
di.addLinkMode(LinkMode::T1);
|
2022-05-21 19:21:01 +00:00
|
|
|
di.addDetection(MANUFACTURER_EIE, 0x1a, 0x0c);
|
|
|
|
di.addMfctTPLStatusBits(
|
|
|
|
{
|
|
|
|
{
|
|
|
|
{
|
2022-05-22 14:10:16 +00:00
|
|
|
"TPL_STS",
|
2022-05-21 19:21:01 +00:00
|
|
|
Translate::Type::BitToString,
|
2022-11-27 16:01:15 +00:00
|
|
|
AlwaysTrigger, MaskBits(0xe0), // Always use 0xe0 for tpl mfct status bits.
|
2022-05-21 19:21:01 +00:00
|
|
|
"OK",
|
|
|
|
{
|
2022-05-24 08:13:41 +00:00
|
|
|
{ 0x40, "RTC_INVALID" }
|
2022-05-21 19:21:01 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
2022-05-21 18:40:01 +00:00
|
|
|
di.setConstructor([](MeterInfo& mi, DriverInfo& di){ return shared_ptr<Meter>(new Driver(mi, di)); });
|
|
|
|
});
|
|
|
|
|
|
|
|
Driver::Driver(MeterInfo &mi, DriverInfo &di) : MeterCommonImplementation(mi, di)
|
|
|
|
{
|
2022-05-22 14:10:16 +00:00
|
|
|
addStringFieldWithExtractorAndLookup(
|
|
|
|
"status",
|
2022-05-25 14:59:55 +00:00
|
|
|
"Meter error flags. IMPORTANT! Smoke alarm is NOT reported here! You MUST check last alarm date and counter!",
|
2022-05-22 14:10:16 +00:00
|
|
|
PrintProperty::JSON | PrintProperty::FIELD | PrintProperty::IMPORTANT |
|
|
|
|
PrintProperty::STATUS | PrintProperty::JOIN_TPL_STATUS,
|
2022-05-21 18:40:01 +00:00
|
|
|
FieldMatcher::build()
|
2022-05-22 14:10:16 +00:00
|
|
|
.set(VIFRange::ErrorFlags),
|
|
|
|
Translate::Lookup(
|
|
|
|
{
|
|
|
|
{
|
|
|
|
{
|
|
|
|
"ERROR_FLAGS",
|
|
|
|
Translate::Type::BitToString,
|
2022-11-27 16:01:15 +00:00
|
|
|
AlwaysTrigger, MaskBits(0xffff),
|
2022-05-22 14:10:16 +00:00
|
|
|
"OK",
|
|
|
|
{
|
2022-05-24 08:13:41 +00:00
|
|
|
/* When used for m-bus?
|
2022-05-22 14:10:16 +00:00
|
|
|
bit 7-7 Not used, zero by default
|
|
|
|
bit 8 Application error, unknown field C
|
|
|
|
bit 9 Application error, unknown field CI
|
|
|
|
bit 10 Application error, unknown record
|
|
|
|
bit 11 Application error, access right
|
|
|
|
bit 12 Application error, record size
|
|
|
|
bit 13 Application error, record value
|
|
|
|
bit 14 Application error, bad password
|
|
|
|
bit 15 Not used, zero by defaul
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}));
|
2022-05-21 18:40:01 +00:00
|
|
|
|
|
|
|
addStringFieldWithExtractor(
|
|
|
|
"last_alarm_date",
|
|
|
|
"Date when the smoke alarm last triggered.",
|
|
|
|
PrintProperty::FIELD | PrintProperty::JSON | PrintProperty::IMPORTANT,
|
|
|
|
FieldMatcher::build()
|
|
|
|
.set(MeasurementType::Instantaneous)
|
|
|
|
.set(SubUnitNr(1))
|
|
|
|
.set(TariffNr(1))
|
|
|
|
.set(VIFRange::Date)
|
|
|
|
);
|
|
|
|
|
|
|
|
addNumericFieldWithExtractor(
|
2022-05-22 14:10:16 +00:00
|
|
|
"alarm",
|
2022-05-21 18:40:01 +00:00
|
|
|
"Number of times the smoke alarm has triggered.",
|
|
|
|
PrintProperty::FIELD | PrintProperty::JSON | PrintProperty::IMPORTANT,
|
|
|
|
Quantity::Counter,
|
|
|
|
VifScaling::None,
|
|
|
|
FieldMatcher::build()
|
|
|
|
.set(MeasurementType::Instantaneous)
|
|
|
|
.set(SubUnitNr(1))
|
|
|
|
.set(TariffNr(1))
|
|
|
|
.set(VIFRange::CumulationCounter)
|
|
|
|
);
|
|
|
|
|
2022-05-22 14:10:16 +00:00
|
|
|
addStringFieldWithExtractor(
|
|
|
|
"software_version",
|
|
|
|
"Meter software version number.",
|
|
|
|
PrintProperty::JSON | PrintProperty::OPTIONAL,
|
|
|
|
FieldMatcher::build()
|
|
|
|
.set(MeasurementType::Instantaneous)
|
|
|
|
.set(VIFRange::SoftwareVersion)
|
|
|
|
);
|
|
|
|
|
|
|
|
addStringFieldWithExtractor(
|
|
|
|
"message_datetime",
|
|
|
|
"Device date time.",
|
|
|
|
PrintProperty::JSON,
|
|
|
|
FieldMatcher::build()
|
|
|
|
.set(MeasurementType::Instantaneous)
|
|
|
|
.set(VIFRange::DateTime)
|
|
|
|
);
|
2022-05-21 18:40:01 +00:00
|
|
|
|
|
|
|
addNumericFieldWithExtractor(
|
|
|
|
"duration_removed",
|
|
|
|
"Time the smoke alarm has been removed.",
|
|
|
|
PrintProperty::JSON,
|
|
|
|
Quantity::Time,
|
|
|
|
VifScaling::Auto,
|
|
|
|
FieldMatcher::build()
|
|
|
|
.set(MeasurementType::Instantaneous)
|
|
|
|
.set(SubUnitNr(1))
|
|
|
|
.set(TariffNr(2))
|
|
|
|
.set(VIFRange::DurationOfTariff)
|
|
|
|
);
|
|
|
|
|
|
|
|
addStringFieldWithExtractor(
|
|
|
|
"last_remove_date",
|
|
|
|
"Date when the smoke alarm was last removed.",
|
|
|
|
PrintProperty::JSON,
|
|
|
|
FieldMatcher::build()
|
|
|
|
.set(MeasurementType::Instantaneous)
|
|
|
|
.set(SubUnitNr(1))
|
|
|
|
.set(TariffNr(2))
|
|
|
|
.set(VIFRange::Date)
|
|
|
|
);
|
|
|
|
|
|
|
|
addNumericFieldWithExtractor(
|
|
|
|
"removed",
|
|
|
|
"Number of times the smoke alarm has been removed.",
|
|
|
|
PrintProperty::JSON,
|
|
|
|
Quantity::Counter,
|
|
|
|
VifScaling::None,
|
|
|
|
FieldMatcher::build()
|
|
|
|
.set(MeasurementType::Instantaneous)
|
|
|
|
.set(SubUnitNr(1))
|
|
|
|
.set(TariffNr(2))
|
|
|
|
.set(VIFRange::CumulationCounter)
|
|
|
|
);
|
|
|
|
|
|
|
|
addStringFieldWithExtractor(
|
|
|
|
"test_button_last_date",
|
|
|
|
"Date when test button was last pressed.",
|
|
|
|
PrintProperty::JSON,
|
|
|
|
FieldMatcher::build()
|
|
|
|
.set(MeasurementType::Instantaneous)
|
|
|
|
.set(SubUnitNr(1))
|
|
|
|
.set(TariffNr(3))
|
|
|
|
.set(VIFRange::Date)
|
|
|
|
);
|
|
|
|
|
|
|
|
addNumericFieldWithExtractor(
|
|
|
|
"test_button",
|
|
|
|
"Number of times the test button has been pressed.",
|
|
|
|
PrintProperty::JSON,
|
|
|
|
Quantity::Counter,
|
|
|
|
VifScaling::None,
|
|
|
|
FieldMatcher::build()
|
|
|
|
.set(MeasurementType::Instantaneous)
|
|
|
|
.set(SubUnitNr(1))
|
|
|
|
.set(TariffNr(3))
|
|
|
|
.set(VIFRange::CumulationCounter)
|
|
|
|
);
|
|
|
|
|
2022-05-22 07:50:37 +00:00
|
|
|
addStringFieldWithExtractor(
|
|
|
|
"installation_date",
|
|
|
|
"Date when the smoke alarm was installed.",
|
|
|
|
PrintProperty::JSON,
|
|
|
|
FieldMatcher::build()
|
|
|
|
.set(MeasurementType::Instantaneous)
|
|
|
|
.set(TariffNr(2))
|
|
|
|
.set(VIFRange::Date)
|
|
|
|
);
|
|
|
|
|
|
|
|
addStringFieldWithExtractor(
|
|
|
|
"last_sound_check_date",
|
|
|
|
"Date when the smoke alarm last checked the piezo speaker.",
|
|
|
|
PrintProperty::JSON,
|
|
|
|
FieldMatcher::build()
|
|
|
|
.set(MeasurementType::Instantaneous)
|
|
|
|
.set(StorageNr(1))
|
|
|
|
.set(VIFRange::Date)
|
|
|
|
);
|
|
|
|
|
|
|
|
addStringFieldWithExtractorAndLookup(
|
|
|
|
"dust_level",
|
|
|
|
"Dust level 0 (best) to 15 (worst).",
|
|
|
|
PrintProperty::JSON,
|
|
|
|
FieldMatcher::build()
|
|
|
|
.set(DifVifKey("8440FF2C")),
|
|
|
|
Translate::Lookup(
|
|
|
|
{
|
|
|
|
{
|
|
|
|
{
|
|
|
|
"DUST",
|
|
|
|
Translate::Type::IndexToString,
|
2022-11-27 16:01:15 +00:00
|
|
|
AlwaysTrigger, MaskBits(0x1f),
|
2022-05-22 07:50:37 +00:00
|
|
|
"",
|
|
|
|
{
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}));
|
|
|
|
|
|
|
|
addStringFieldWithExtractorAndLookup(
|
|
|
|
"battery_level",
|
|
|
|
"Battery voltage level.",
|
|
|
|
PrintProperty::JSON,
|
|
|
|
FieldMatcher::build()
|
|
|
|
.set(DifVifKey("8440FF2C")),
|
|
|
|
Translate::Lookup(
|
|
|
|
{
|
|
|
|
{
|
|
|
|
{
|
|
|
|
"BATTERY_VOLTAGE",
|
|
|
|
Translate::Type::IndexToString,
|
2022-11-27 16:01:15 +00:00
|
|
|
AlwaysTrigger, MaskBits(0x0f00),
|
2022-05-22 07:50:37 +00:00
|
|
|
"",
|
|
|
|
{
|
|
|
|
{ 0x0000, "2.25V" },
|
|
|
|
{ 0x0100, "2.30V" },
|
|
|
|
{ 0x0200, "2.35V" },
|
|
|
|
{ 0x0300, "2.40V" },
|
|
|
|
|
|
|
|
{ 0x0400, "2.45V" },
|
|
|
|
{ 0x0500, "2.50V" },
|
|
|
|
{ 0x0600, "2.55V" },
|
|
|
|
{ 0x0700, "2.60V" },
|
|
|
|
|
|
|
|
{ 0x0800, "2.65V" },
|
|
|
|
{ 0x0900, "2.70V" },
|
|
|
|
{ 0x0a00, "2.75V" },
|
|
|
|
{ 0x0b00, "2.80V" },
|
|
|
|
|
|
|
|
{ 0x0c00, "2.85V" },
|
|
|
|
{ 0x0d00, "2.90V" },
|
|
|
|
{ 0x0e00, "2.95V" },
|
|
|
|
{ 0x0f00, "3.00V" }
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}));
|
|
|
|
|
|
|
|
addStringFieldWithExtractorAndLookup(
|
|
|
|
"obstacle_distance",
|
|
|
|
"The distance to a detected obstacle.",
|
|
|
|
PrintProperty::JSON,
|
|
|
|
FieldMatcher::build()
|
|
|
|
.set(DifVifKey("8440FF2C")),
|
|
|
|
Translate::Lookup(
|
|
|
|
{
|
|
|
|
{
|
|
|
|
{
|
|
|
|
"OBSTACLE_DISTANCE",
|
|
|
|
Translate::Type::IndexToString,
|
2022-11-27 16:01:15 +00:00
|
|
|
AlwaysTrigger, MaskBits(0x700000),
|
2022-05-22 07:50:37 +00:00
|
|
|
"",
|
|
|
|
{
|
2022-05-22 14:10:16 +00:00
|
|
|
{ 0x000000, "SEODS_NOT_COMPLETED" },
|
2022-05-22 07:50:37 +00:00
|
|
|
{ 0x100000, "" }, // No obstacle detected
|
|
|
|
{ 0x200000, "45_TO_60_CM" },
|
|
|
|
{ 0x300000, "38_TO_53_CM" },
|
|
|
|
|
|
|
|
{ 0x400000, "33_TO_48_CM" },
|
|
|
|
{ 0x500000, "28_TO_40_CM" },
|
|
|
|
{ 0x600000, "20_TO_33_CM" },
|
|
|
|
{ 0x700000, "0_TO_25_CM" },
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
|
|
addStringFieldWithExtractorAndLookup(
|
2022-05-22 14:10:16 +00:00
|
|
|
"head_status",
|
|
|
|
"Status of smoke detector sensors, merged into the status field.",
|
|
|
|
PrintProperty::JOIN_INTO_STATUS,
|
2022-05-22 07:50:37 +00:00
|
|
|
FieldMatcher::build()
|
|
|
|
.set(DifVifKey("8440FF2C")),
|
|
|
|
Translate::Lookup(
|
|
|
|
{
|
|
|
|
{
|
|
|
|
{
|
|
|
|
"HEAD_STATUS",
|
|
|
|
Translate::Type::BitToString,
|
2022-11-27 16:01:15 +00:00
|
|
|
AlwaysTrigger, MaskBits(0xff8ff0e0),
|
2022-05-22 07:50:37 +00:00
|
|
|
"OK",
|
|
|
|
{
|
2022-05-22 14:10:16 +00:00
|
|
|
/* 0x00000000-0x000000f dust level*/
|
|
|
|
{ 0x00000020, "SOUNDER_FAULT" },
|
|
|
|
{ 0x00000040, "TAMPER_WHILE_REMOVED" },
|
|
|
|
{ 0x00000080, "EOL_REACHED" },
|
|
|
|
/* 0x00000100-0x000f00 battery evel*/
|
|
|
|
{ 0x00001000, "LOW_BATTERY_FAULT" },
|
|
|
|
{ 0x00002000, "ALARM_SENSOR_FAULT" },
|
|
|
|
{ 0x00004000, "OBSTACLE_DETECTOR_FAULT" },
|
|
|
|
{ 0x00008000, "EOL_WITHIN_12_MONTH" },
|
|
|
|
{ 0x00010000, "SEODS_NOT_YET_COMPLETED", TestBit::NotSet },
|
|
|
|
{ 0x00020000, "ENV_CHANGED_SINCE_INSTALLATION" },
|
|
|
|
{ 0x00040000, "COMM_TO_HEAD_FAULT" },
|
|
|
|
{ 0x00080000, "INTERFERENCE_PREVENTING_OBSTACLE_DETECTION" },
|
|
|
|
/* 0x00100000-0x0700000 distance */
|
|
|
|
/* 0x00800000 reserved */
|
|
|
|
{ 0x01000000, "OBSTACLE_DETECTED" },
|
|
|
|
{ 0x02000000, "SMOKE_DETECTOR_FULLY_COVERED" }
|
2022-05-22 07:50:37 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}));
|
|
|
|
|
2022-05-21 18:40:01 +00:00
|
|
|
}
|
|
|
|
}
|
2022-05-24 08:13:41 +00:00
|
|
|
|
|
|
|
// Test: Smokey ei6500 01097274 NOKEY
|
|
|
|
// telegram=|58442515747209010C1A7A8B0000000BFD0F070101046D2A06D82502FD17000082206CD825426CD0238440FF2C000F11008250FD61000082506C01018260FD6100008360FD3100000082606C01018270FD61000082706C0101|
|
|
|
|
// {"media":"smoke detector","meter":"ei6500","name":"Smokey","id":"01097274","status":"OK","last_alarm_date":"2000-01-01","alarm_counter":0,"software_version":"010107","message_datetime":"2022-05-24 06:42","duration_removed_h":0,"last_remove_date":"2000-01-01","removed_counter":0,"test_button_last_date":"2000-01-01","test_button_counter":0,"installation_date":"2022-05-24","last_sound_check_date":"2022-03-16","dust_level":"DUST_0","battery_level":"3.00V","obstacle_distance":"","timestamp":"1111-11-11T11:11:11Z"}
|
|
|
|
// |Smokey;01097274;OK;2000-01-01;0.000000;1111-11-11 11:11.11
|
|
|
|
|
|
|
|
// telegram=|58442515747209010C1A7A8D0000000BFD0F070101046D2E06D82502FD17000082206CD825426CD0238440FF2C000F11008250FD61000082506C01018260FD6100008360FD3100000082606C01018270FD61020082706CD825|
|
|
|
|
// {"media":"smoke detector","meter":"ei6500","name":"Smokey","id":"01097274","status":"OK","last_alarm_date":"2000-01-01","alarm_counter":0,"software_version":"010107","message_datetime":"2022-05-24 06:46","duration_removed_h":0,"last_remove_date":"2000-01-01","removed_counter":0,"test_button_last_date":"2022-05-24","test_button_counter":2,"installation_date":"2022-05-24","last_sound_check_date":"2022-03-16","dust_level":"DUST_0","battery_level":"3.00V","obstacle_distance":"","timestamp":"1111-11-11T11:11:11Z"}
|
|
|
|
// |Smokey;01097274;OK;2000-01-01;0.000000;1111-11-11 11:11.11
|
|
|
|
|
|
|
|
// telegram=|58442515747209010C1A7A900000000BFD0F070101046D3406D82502FD17000082206CD825426CD0238440FF2C020F11008250FD61010082506CD8258260FD6100008360FD3100000082606C01018270FD61020082706CD825|
|
|
|
|
// {"media":"smoke detector","meter":"ei6500","name":"Smokey","id":"01097274","status":"OK","last_alarm_date":"2022-05-24","alarm_counter":1,"software_version":"010107","message_datetime":"2022-05-24 06:52","duration_removed_h":0,"last_remove_date":"2000-01-01","removed_counter":0,"test_button_last_date":"2022-05-24","test_button_counter":2,"installation_date":"2022-05-24","last_sound_check_date":"2022-03-16","dust_level":"DUST_2","battery_level":"3.00V","obstacle_distance":"","timestamp":"1111-11-11T11:11:11Z"}
|
|
|
|
// |Smokey;01097274;OK;2022-05-24;1.000000;1111-11-11 11:11.11
|
|
|
|
|
|
|
|
// telegram=|58442515747209010C1A7A940000000BFD0F070101046D0007D82502FD17000082206CD825426CD0238440FF2C420F11008250FD61010082506CD8258260FD6101008360FD3101000082606CD8258270FD61020082706CD825|
|
|
|
|
// {"media":"smoke detector","meter":"ei6500","name":"Smokey","id":"01097274","status":"TAMPER_WHILE_REMOVED","last_alarm_date":"2022-05-24","alarm_counter":1,"software_version":"010107","message_datetime":"2022-05-24 07:00","duration_removed_h":0.016667,"last_remove_date":"2022-05-24","removed_counter":1,"test_button_last_date":"2022-05-24","test_button_counter":2,"installation_date":"2022-05-24","last_sound_check_date":"2022-03-16","dust_level":"DUST_2","battery_level":"3.00V","obstacle_distance":"","timestamp":"1111-11-11T11:11:11Z"}
|
|
|
|
// |Smokey;01097274;TAMPER_WHILE_REMOVED;2022-05-24;1.000000;1111-11-11 11:11.11
|