Forum Discussion
Calculate Equipment State Duration per Shift
- Anonymous6 years ago
here a solution "complete" (corresponding to the status of the information received 😁) avoiding the use of the function List.Accumulate.
starting table:
output Table:
the code for the output table:
let ct = Table.TransformColumnTypes(Table,{{"StateDateTime", type datetime}, {"EquipmentState", type text}, {"ShiftIndex", Int64.Type}}), idx=List.RemoveLastN(List.Distinct(ct[ShiftIndex]),1), lstR=List.Generate( ()=>[r=1,pos=List.PositionOf(ct[ShiftIndex],idx{0},Occurrence.Last), lr=sfht(ct{pos},ct{pos+1})], each [r]<=List.Count(idx), each [r=[r]+1, pos=List.PositionOf(ct[ShiftIndex],idx{[r]},Occurrence.Last),lr=sfht(ct{pos},ct{pos+1}) ], each [lr] ), tc= Table.Combine({Table.FromRecords(List.Combine(lstR)),Table}), grp = Table.Group(tc, {"ShiftIndex"}, {{"shIdx", each duration(_)}}), #"Expanded shIdx" = Table.ExpandTableColumn(grp, "shIdx", {"StateDateTime", "EquipmentState", "Duration"}, {"StateDateTime", "EquipmentState", "Duration"}) in #"Expanded shIdx"the two functions used:
sfht
let listRows=(rL,rF)=> let shift=#duration(0,0,720,0), dL=rL[StateDateTime], dF=rF[StateDateTime], lr=List.Generate( ()=>[r=rL&[StateDateTime=#datetime(Date.Year(dL),Date.Month(dL),Date.Day(dL)+sh{1},sh{0},0,0)],idx=1], each [r][StateDateTime]<=dF, each [r=if Number.Mod(idx,2)=1 then [r]& [StateDateTime=[r][StateDateTime]+shift] else [r]&[ShiftIndex=[r][ShiftIndex]+1],idx=[idx]+1], each [r] ), sh=if Time.Hour(dL) < 6 then {6,0} else if Time.Hour(dL)<18 then {18,0} else {6,1} in lr in listRowsand finally duration:
let count=(tab)=> let ts=Table.Sort(tab,{"StateDateTime"}), ai = Table.AddIndexColumn(ts, "i", 0, 1) in Table.RemoveColumns(Table.AddColumn(ai, "Duration", each try if [ShiftIndex]=ai[ShiftIndex]{[i]+1} then Duration.TotalMinutes(ai[StateDateTime]{[i]+1}-[StateDateTime]) else "" otherwise""),{"i"}) in count
Hi EricSteynMMD ,
How about using DAX?
1. Create EquipmentState table by entering data and sort "EquipmentState" column by "Order" column.
2. Create measures.
Duration in Minutes =
VAR StartTime =
YEAR ( MAX ( 'Table'[StateDateTime] ) ) & "/"
& MONTH ( MAX ( 'Table'[StateDateTime] ) ) & "/"
& DAY ( MAX ( 'Table'[StateDateTime] ) ) & " "
& TIME ( 6, 0, 0 )
VAR EndTime =
YEAR ( MAX ( 'Table'[StateDateTime] ) ) & "/"
& MONTH ( MAX ( 'Table'[StateDateTime] ) ) & "/"
& DAY ( MAX ( 'Table'[StateDateTime] ) ) & " "
& TIME ( 18, 0, 0 )
VAR StartUpTime =
CALCULATE (
MAX ( 'Table'[StateDateTime] ),
'Table'[EquipmentState] = "StartUp"
)
VAR RunningTime_ =
CALCULATE (
MAX ( 'Table'[StateDateTime] ),
'Table'[EquipmentState] = "Running"
)
VAR StartUpTime_ =
IF ( StartUpTime = BLANK (), StartTime, StartUpTime )
VAR MaintenanceTime =
CALCULATE (
MAX ( 'Table'[StateDateTime] ),
'Table'[EquipmentState] = "Maintenance"
)
VAR FailTime =
CALCULATE ( MAX ( 'Table'[StateDateTime] ), 'Table'[EquipmentState] = "Fail 1" )
VAR FailTime_ =
IF ( FailTime = BLANK (), EndTime, FailTime )
RETURN
SWITCH (
MAX ( EquipmentState[EquipmentState] ),
"StartUp", DATEDIFF ( StartUpTime_, RunningTime_, MINUTE ),
"Running", DATEDIFF ( RunningTime_, MaintenanceTime, MINUTE ),
"Maintenance", DATEDIFF ( MaintenanceTime, FailTime_, MINUTE ),
"Fail 1", DATEDIFF ( FailTime_, EndTime, MINUTE )
)
Percentage of Shift =
[Duration in Minutes]/SUMX(ALL(EquipmentState),[Duration in Minutes])
BTW, .pbix file attached.
Best regards
Icey
If this post helps, then consider Accepting it as the solution to help other members find it more quickly.
Thanks Icey for the detailed solution below.
The only issue we'd have with this approach is that the EquipmentState's are not only limited to the ones I gave in the Example and can in fact be up to 10 different Events/States. They also do not specifically occur in any order and can also sometimes span the duraiton of a number of shifts as well.
Not entirely sure how I send an attachment, but happy to share a copy of the Dataset if it would help?