Historian provisioning skips Float/Double/Byte/SByte tags: DataType is an OPC UA name, the applier parses DriverDataType #898
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
AddressSpaceApplier.ProvisionHistorizedTagssends anEnsureTagsrequest only when the raw tag'sDataTypestring parses asDriverDataType:Enum.TryParse<DriverDataType>(tag.DataType), membersBoolean, Int16..UInt64, Float32, Float64, String, DateTime, Reference.But
Tag.DataTypeholds OPC UA built-in names:RawTagModal.DataTypes, manual entry and CSV default to"Float", andRawBrowseCommitMappermapsFloat32→"Float"andFloat64→"Double";OtOpcUaNodeManager.ResolveBuiltInDataTypeonly understands those names ("Float32"would becomeBaseDataType).Effect: a historized Float, Double, Byte or SByte tag is never provisioned in the historian. The skip is logged at Debug only, and no tally line is written because the request list stays empty. On the Gateway backend a brand-new Float/Double tag therefore never gets its AVEVA tag created, and continuous historization of it fails downstream.
AddressSpaceApplierProvisioningTestsasserts this behaviour ("Floatis NOT a DriverDataType member … it must be skipped") and usesFloat32for the positive cases, a spelling the AdminUI never produces.Seen live on DEV vd03
fea7de0a, 2026-11-13, #700 gate: four historized Float/Byte/Double tags were deployed and the gateway's metrics showed noEnsureTagscall (docs/plans/evidence/2026-11-13-historian-700-vd03/vd03-endpoint-gate.md). The gate relied on this skip deliberately to stay zero-write.Fix direction: map the OPC UA names to
DriverDataType(Float→Float32,Double→Float64,Byte/SByte→a widened integer) in one shared helper, used by both provisioning and the continuous-historization recorder.⚠️ Coordinate with #899. Once this is fixed, any node that binds history to an existing AVEVA tag through
historianTagnamewith a Float/Double type will start re-ensuring (rewriting) that tag on every add.Claude-Session: https://claude.ai/code/session_01GT67ACmpMR7b9LGRPLijMi
Fixed (same change as #899)
Mapping. Type resolution now goes through one shared helper,
HistorianDataTypeNames.TryResolvein Core.Abstractions. The provisioning hook inAddressSpaceAppliernow uses it instead ofEnum.TryParse<DriverDataType>. The recorder never parsed the type string (it classifies by value kind), so it needed no change.Tag.DataType(OPC UA name)FloatFloatDoubleDoubleByte(0..255)Int2SByte(−128..127)Int2(Int1creation is server-degenerate, #441)Boolean,Int16…UInt64,String,DateTimeFloat32/Float64/Reference(DriverDataType spellings)Guid,ByteString, a number, blankHistorianGateway's lossless-cast-or-reject rule. Its client cannot create
Int8/UInt8, soHistorianTypeMappernow marksInt64/UInt64as not historizable on the Gateway backend. They are skipped (countedskipped) instead of being sent to fail withFailedPrecondition(countedfailed). For Byte, I choseInt2over HG'sUInt1→UInt2path.Int2is the type already proven for Boolean, and OtOpcUa still widens away from the historian'sUInt2write path (UInt16→Uint4).Tests. The ones that encoded the bug were rewritten:
Apply_skips_added_tag_with_unparseable_datatypebecameApply_provisions_opc_ua_type_names_and_skips_unmapped_ones. A Float, Double, Byte and SByte tag now reach EnsureTags with the mapped types, and Guid is skipped.HistorianTypeMapperTestsno longer expects Int64→Int8 / UInt64→Uint8.New tests:
HistorianDataTypeNamesTestscovers every nameRawTagModaloffers, plus the number and comma-list casesEnum.TryParsewould have accepted.GatewayTagProvisionerTests.Sixty_four_bit_integers_are_skipped_not_sentcovers the 64-bit skip. All of these were mutation-checked.⚠️ Upgrade warning (also in
docs/Historian.md§Tag auto-provisioning)Before this release, historized tags with
DataTypeFloat,Double,ByteorSBytewere never provisioned. On the first host start after the upgrade, every existing historized Float, Double, Byte and SByte tag is provisioned. On the Gateway backend that is anEnsureTagsupsert:That is the intended fix for tags OtOpcUa owns. But a tag whose
historianTagnamenames someone else's AVEVA tag (a System Platform attribute,SysTimeSec, …) will be rewritten. Before upgrading, do one of these:"historianReadOnly": true(#899);ServerHistorian:ProvisionTags=CreateOnly, which leaves existing tags alone and still creates missing ones;ServerHistorian:ProvisionTags=Off.On the SqlServer and QuestDB backends the upgrade only upserts rows in OtOpcUa's own tag table, which is harmless.
On deployed DEV vd03 nothing changes until this build is deployed there. The #700 gate's temporary Float/Byte/Double tags were removed (configuration revision
fa9a2e28…is the original), so no gate tag would provision.