The Barix interface offers a convenient way to string up to 50 sensors to ethernet. What is even better: XTension has native Barix support.
The only problem is that in experimental environments, the sensors are popping on and dropping off the list of available sensors. Barix will just consecutively put all sensorIDs and sensor values in a set of 50 registers. Effectively the sensors are shuffeled around with respect to their addresses. This means that XTension loses track if you stick by the Barix register addresses.
We need a cunning plan. We will indirectly address real world XTension units. Parts of the code are thanks to James Sentman
Need to know:
Nice to know:
When sensor nn's data (temperature) changes, the TRnn's ON script looks up in its myDestination property where the new temperature value has to be delivered and updates the real world unit. Failing one, TCnn will be used as a fallback.
As soon as a onewire ID in a Barix register changes, so changes the value of the correspondingly addressed XTension unit on the Barix Interface. That unit's ON script triggers while its future value holds the ID of the new sensor. We use the TInn's ON script to look up the sensorID's corresponding real world unit name and we put that real world name in the TRnn's property myDestination, to indicate where sensor data is to be deliverd.
In the description for TR and TC, the real world unit name for the sensor is shown. The description of the TI holds the sensor ID.
Script rivet(nn) places the real world unit's name in TRnn's myDestination property value.
--lives as global script 'create units'
set NameOfMyBarix to "Barix"
set TI_OnScriptText to "rivet(unit address of (thisunit))"
set TR_onscripttext to "set myDestination to Get Unit Property \"myDestination\" from unit (thisUnit)" & ¬"
return & "set value of myDestination to future value of (thisunit)"
--or use "dispatch(address of (thisunit))"
repeat with sensor from 1 to 50
set TI_unit to "TI" & text -2 through -1 of ("00" & sensor as string) --contains sensor ID
set TR_unit to "TR" & text -2 through -1 of ("00" & sensor as string) --contains sensor data value
set TC_unit to "TC" & text -2 through -1 of ("00" & sensor as string) --decoy if no real world unit available
--delete unit TI_unit
--delete unit TR_unit
--delete unit TC_unit
create unit TI_unit
create unit TR_unit
create unit TC_unit
set params of TI_unit interface NameOfMyBarix with receive and dimmable
set params of TR_unit interface NameOfMyBarix with receive and dimmable
set params of TC_unit with dimmable
--You will have to manually set "Unit of Measure" to " °C" or " °F"
--You will have to manually choose between  Celcius and Fahrenheit in Device Options
set unit address of TR_unit to (600 + sensor) as string
set unit address of TI_unit to (650 + sensor) as string
set OnScriptText in xUnit TI_unit to TI_OnScriptText
set OnScriptText in xUnit TR_unit to TR_onscripttext
Set Unit Property "myDestination" in unit TR_unit to TC_unit --decoy until real world unit is known
set Device of TR_unit to Temperature
set Device of TC_unit to Temperature
set value of TR_unit to 0 --an off and on switching of Barix will force correct values
end repeat
--end create units
--lives as global script 'delete units'
set ndeleted to 0
repeat with sensor from 1 to 50
try
set TI_unit to "TI" & text -2 through -1 of ("00" & sensor as string) --contains sensor ID
set TR_unit to "TR" & text -2 through -1 of ("00" & sensor as string) --contains sensor data value
set TC_unit to "TC" & text -2 through -1 of ("00" & sensor as string) --decoy if no real world unit available
delete unit TI_unit
delete unit TR_unit
delete unit TC_unit
set ndeleted to sensor
on error
set resultString to (ndeleted as string) & " units deleted"
if ndeleted = 0 then set resultString to "no units found"
if ndeleted = 1 then set resultString to (ndeleted as string) & " unit deleted"
exit repeat
end try
end repeat
--end 'delete units'
-- getSensorlist
--lives as global script 'getSensorlist'
set theString to ""
set limitsString to "" --could be ",0,100,10" --min value, max value, max difference between two updates for dispatch() macro
try
repeat with sensor from 1 to 50
set TI_unit to "TI" & text -2 through -1 of ("00" & sensor as string) --contains sensor ID
set TR_unit to "TR" & text -2 through -1 of ("00" & sensor as string) --contains sensor data value
--set tempunit to "TC" & sensorstring
if (value of TI_unit) is not 0 then
if theString is not "" then set theString to theString & ",¬"" & return
set myHexValue to text -8 through -1 of ("00000000" & hexReverse((number to hex (value of TI_unit))))
set myDecValue to ((value of TI_unit))
set myDestination to (Get Unit Property "myDestination" from unit TR_unit)
set theString to theString & "{" & quote & myHexValue & quote & "," & quote & myDestination & quote & limitsString & "}"
end if
end repeat
end try
set stringInsert to theString
if theString is not "" then set stringInsert to "¬"" & return & theString & "¬"" & return
write log "set sensorlist to {" & stringInsert & "}"
-- end getSensorlist
on hexReverse(hexString)
--lives in the Attachments script
set myCount to the number of characters of hexString
set myReverseString to ""
repeat with myIndex from 1 to (myCount) by 2
set myReverseString to ((characters (myIndex) through (myIndex + 1) of hexString) as string) & myReverseString
end repeat
return myReverseString
end hexReverse
on rivet(registerNumber)
--lives in Attachments
--Barix Register (601...650) noticed a new sensor ID
--rivet the corresponding data (=temperature) register to the appropriate unit
--the data register unit (651..700) has a routine to dispatch the new temperature value
local SensorList
--write log "riveting " & registerNumber
set SensorList to {¬"
{"0010289D", "TCSoladin3"}, ¬"
{"0010D8BA", "TCSoladin2"}, ¬"
{"001094E0", "unknown unit"}, ¬"
{"00108CA1", "TCLanding"}, ¬"
{"00101B9F", "TCBoilerTop"}, ¬"
{"28A608D0", "TCTempOutside"} ¬"
}
set DestinationName to ""
set MyRegOnScriptText to "set myDestination to Get Unit Property \"myDestination\" from unit (thisUnit)
set value of myDestination to future value of (thisunit)"
--or use set MyRegOnScriptText to "dispatch(address of thisUnit)"
set sensor to (registerNumber - 650)
set sensorstring to text -2 through -1 of ("00" & sensor as string) --sensor string is 01...50
set TI_unit to "TI" & sensorstring
set TR_unit to "TR" & sensorstring
set TC_unit to "TC" & sensorstring
set sensorID to text -8 through -1 of ("00000000" & hexReverse(number to hex (future value of TI_unit) as string))
repeat with sensorsub in SensorList
if (item 1 of sensorsub) is sensorID then
set DestinationName to item 2 of sensorsub
end if
end repeat
if DestinationName is not "" then
--write log "riveted sensor ID " & sensorID & " to unit " & DestinationName & " unit name is " & regunit
else
write log "New OneWire sensor found: ID= " & sensorID & " Address=" & TR_unit
set DestinationName to TC_unit
end if
Set Unit Property "myDestination" in unit TR_unit to DestinationName
set OnScriptText in xUnit TR_unit to MyRegOnScriptText
set description of TI_unit to sensorID
set description of TR_unit to DestinationName
set description of TC_unit to DestinationName
end rivet