Hey,
So I have been trying to install and run a traccar (gps tracking server) script for integration into HS.
I've had many issues so far, some just plain silly and others frustrating as hell.
I am now on the final stretch I think, just a few niggles.
I am getting the following errors when trying to run the script.
Is there a way to increase verbose output do you know?
I've tried running the script with tenscripts, but other than build errors it does still compile and run but I don't really know how to debug from there.
Any ideas?
Traccar.vb
Thanks
So I have been trying to install and run a traccar (gps tracking server) script for integration into HS.
I've had many issues so far, some just plain silly and others frustrating as hell.
I am now on the final stretch I think, just a few niggles.
I am getting the following errors when trying to run the script.
Jun-13 00:36:58 | Error 1 | Running script C:\Program Files (x86)\HomeSeer HS3\scripts\Traccar.vb :Exception has been thrown by the target of an invocation.Object reference not set to an instance of an object. |
Jun-13 00:36:58 | Traccar | Error Connecting to Database traccar: Incorrect TIMESTAMP value: 'NULL' |
I've tried running the script with tenscripts, but other than build errors it does still compile and run but I don't really know how to debug from there.
Any ideas?
Traccar.vb
Code:
' Script created by Rutger Bockholts and is provided on https://rutg3r.com for free. ' Version 4.6.01 // November 15 2019 ' Script is tested with Traccar 4.6 ' The script will run in 4 stages: ' 1: Get columns and values data from Traccar table 'positions' and store both in seperate arrays, except the last column "Attributes" ' 2: Get the last column "Attributes" and add all the Keys and Values of the KVPair to seperate arrays ' 3: Add additional virtual devices to the arrays, to provide seperate data ' 4: Get data from all arays and store them in the virtual devices ' 5: Will create a recurring event, that runs once a day, to run the "DailyDistance" script. The event has the status enabled Imports MySql.Data.MySqlClient Imports Newtonsoft.Json Imports Newtonsoft.Json.Linq Imports System.Net Sub Main(ByVal Cpt as Object) ' ********** START USER CHANGE ********** Dim Debug as Boolean = true ' true/false Dim UseMetrics as Boolean = false ' true=Kilometers // false=Miles Dim UseGoogleStreetview as Boolean = false ' true/false / API code necessary Dim GoogleStreetview_API = "xxx" Dim DBserver = "localhost" Dim DBuser = "admin" Dim DBpassword = "password" Dim DBtraccar = "traccar" ' Coordinates Home Dim lat_home = 54.271866 ' Input with decimal point Dim lon_home = -0.938364 ' Input with decimal point ' Coordinates Work Dim lat_work = 54.271866 ' Input with decimal point Dim lon_work = 0.938364 ' Input with decimal point ' Aerial distance from above locations Dim GeofenceHome = 0.1 ' Example: PresenceHome will be TRUE(ON) when car location is within '0.1' kilometers/miles of Home location. Dim GeofenceWork = 0.1 ' Example: PresenceWork will be TRUE(ON) when car location is within '0.2' kilometers/miles of Work location. ' ********** END USER CHANGE ********** Dim HS_Port as String = hs.GetINISetting("Settings", "gWebSvrPort", "") ' Homeseer web port Dim HS_IPAddress as String = hs.GetIPAddress ' Homeseer ip address ' Dim HS_Version as String = hs.GetINISetting("Settings", "gLastRunVersion", "") ' Homeseer version ' Dim streetview_store_path as String = hs.GetAppPath & "\html\Streetview\" ' Local HS file location for saving Streetview picture(s) Dim streetview_store_path as String = "C:\Program Files (x86)\HomeSeer HS3\html\Streetview\" ' Local HS file location for saving Streetview picture(s) ' If Dir(streetview_store_path) = "" Then ' MkDir (streetview_store_path) ' If Debug = true Then hs.writelog("Folder", "Storage folder created: " & streetview_store_path) ' Else ' If Debug = true Then hs.writelog("Folder", "Storage folder already exists") ' End If Dim streetview_open_path as String = "http://" & HS_IPAddress & ":" & HS_Port & "/Streetview/" ' Web location (in html folder) for saving Streetview picture(s) ' Dim streetview_open_path as String = "http://192.168.1.123:81/Streetview/" ' Web location (in html folder) for saving Streetview picture(s) Dim conn as MySqlConnection Dim conn1 as MySqlConnection Dim myCommand as New MySqlCommand Dim myCommand1 as New MySqlCommand ' Variables for creating devices Dim DevExists Dim BaseRef as Integer = 0 Dim dv as Scheduler.Classes.DeviceClass = Nothing Dim root_dv as Scheduler.Classes.DeviceClass = Nothing Dim DVaddress as String ' Devicename prefix (including space!!) Dim DevicesArrayD as New ArrayList ' Create array for all GPS Devices Dim DevicesArrayN as New ArrayList ' Create array for all GPS Device names Dim DevicesArrayK as New ArrayList ' Create array for all Keys Dim DevicesArrayV as New ArrayList ' Create array for all Values Dim DevicesArrayE as New ArrayList ' Create array for all Values Extensions (extension of value string, like 'miles' ) ' Event "Traccar_DailyDistance" Const ScriptName = "Event-create" Dim strEventGroup as String = "GPS" Dim strEventName as String = "Traccar_DailyDistance" Dim strEventLaunchByRefProc as String = "LaunchEventByRef" Dim strEventLaunchScript as String = "Traccar_DailyDistance.vb" Dim strEventLaunchByNameProc as String = "" ' Not in use Dim strEventLaunchProcParams as String = "" ' Not in use Dim batterymonitor_old_data as Double Dim ButtonInfo() As String Dim units Dim R ' Radius for calculating AERIAL distance If UseMetrics = true units = " km" ' String extension for distance devices R = 6372.8 ' Earth radius in kilometers Else units = " mi" ' String extension for distance devices R = 3959.9 ' Earth radius in miles End If Dim Columnname as String Dim Columnvalue Dim gps_id Dim gps_name If Debug = true Then hs.writelog("Debug", Debug) If Debug = true Then hs.writelog("HS version", hs.version) If Debug = true Then hs.writelog("UseMetrics", "in " & units) If Debug = true Then hs.writelog("strtvw_open", streetview_open_path) If Debug = true Then hs.writelog("strtvw_store", streetview_store_path) Try ' Get GPS tracker id and names conn1 = New MySqlConnection() conn1.ConnectionString = "server=" & DBserver & "; user id=" & DBuser & "; password=" & DBpassword & "; database=" & DBtraccar & "" myCommand.CommandText = "SELECT id as id, name as name from tc_devices WHERE lastupdate != 'NULL'" ' When a new tracker is added but don't have uploaded data yet, the script will continue running myCommand.Connection = conn1 conn1.Open() myCommand.ExecuteNonQuery() Dim myAdapterG as New MySqlDataAdapter myAdapterG.SelectCommand = myCommand Dim myDataG as MySqlDataReader myDataG = myCommand.ExecuteReader() If Debug = true Then hs.writelog("GPS_ids", myDataG.FieldCount) ' Show amount of id's/gps devices If Debug = true Then hs.writelog("GPS_cmd", myCommand.CommandText) ' Loop for every gps_id the whole script Dim g as Integer = 0 If myDataG.HasRows Then While myDataG.Read gps_id= myDataG(g).ToString If Debug = true Then hs.writelog("GPS-Array:" & g, gps_id(g)) ' Add extra devices to DevicesArrayK conn = New MySqlConnection() conn.ConnectionString = "server=" & DBserver & "; user id=" & DBuser & "; password=" & DBpassword & "; database=" & DBtraccar & "" myCommand.CommandText = "SELECT tc_devices.name as trackername, TIMESTAMPDIFF(SECOND,servertime, NOW()) as lastupdate, tc_positions.* FROM tc_positions JOIN tc_devices ON tc_devices.id = " & gps_id & " and tc_positions.deviceid = " & gps_id & " Order by id DESC LIMIT 1" If Debug = true Then hs.writelog("Columns", myCommand.CommandText) myCommand.Connection = conn conn.Open() myCommand.ExecuteNonQuery() Dim myAdapter as New MySqlDataAdapter myAdapter.SelectCommand = myCommand Dim myData as MySqlDataReader myData = myCommand.ExecuteReader() Dim address_old_Ref Dim address_old_data Dim x as Integer = 0 If myData.HasRows Then While myData.Read DVaddress = MyData("trackername") If Debug = true Then hs.writelog("Trackername", DVaddress) DevicesArrayK.Add("GPS Tracker") DevicesArrayV.Add("") DevicesArrayE.Add(DVaddress) ' Get column names and values For x = 0 To myData.FieldCount - 1 Columnname = StrConv(myData.GetName(x), VbStrConv.ProperCase) ' Change first character to Uppercase) Columnvalue = myData(x).ToString ' If Address value is NULL, the current value from the HS device, will be kept. If Columnname = "Address" Then If (IsDbNull(Columnvalue) OR String.IsNullOrEmpty(Columnvalue) OR Columnvalue="NULL") If Debug = true Then hs.writelog("Address", "DB field is empty. Keep old value") address_old_Ref = hs.GetDeviceRefByName(DVaddress & "_Address") If Debug = true Then hs.writelog("addr_old_Ref", address_old_Ref) address_old_data = hs.DeviceString(address_old_Ref) If Debug = true Then hs.writelog("addr_old_data", address_old_data) Columnvalue = address_old_data If Debug = true Then hs.writelog("Keep old value", Columnvalue) End If Elseif Columnname = "Speed" Then ' Speed data from MySQL is in knots If UseMetrics = true Then Columnvalue = Math.Round(Columnvalue*1.85, 0) ' From knots to km/h, 0 decimals If Debug = true Then hs.writelog("Speed" , "New: " & Columnvalue) End If Elseif Columnname = "Attributes" Then ' Attributes objects will be created later Exit For Elseif Columnname = "Network" Then ' Network objects will be created later Exit For End If DevicesArrayK.Add(Columnname) DevicesArrayV.Add(Columnvalue) DevicesArrayE.Add("") If Debug = true Then hs.writelog("Array", DevicesArrayK(x) & ": " & DevicesArrayV(x) & " " & DevicesArrayE(x)) Next 'Add 'Attributes' devices to array Dim json as String ' This is the string of json data that needs decoding ' Dim obj as New Object json = myData("attributes") ' Grab all content from Attributes column field. 'Possible result: {"event":35,"sat":"12","gsm":"25","hdop":"0.8","odometer":"2 9576128","runtime":"45513310","mcc":204,"mnc":8,"lac":3480," cid":52621,"status":"0000","adc1":21,"battery":726,"power":2 63,"ip":"111.222.333.444","distance":0.0,"'":9426362.17} ' Change json output to string If Debug = true Then hs.writelog("Attributes", json) Dim json1 = Replace(json, "[", "") ' Remove bracket Dim json2 = Replace(json1, "]", "") ' Remove bracket Dim json3 = Replace(json2, "{", "") ' Remove bracket Dim json4 = Replace(json3, "}", "") ' Remove bracket Dim json5 = Replace(json4, """", "") ' Remove double quotes, so plain text string is left over (aaa:123,zzz:654,etc) Dim counter as String() = json5.Split(",") ' Count amount of commas in String json5, so we know how many devices should be created. If Debug = true Then hs.writelog("Attr-Counter", counter.Length) Dim results() as String = json5.Split(",") ' create array of all results ' Attributes object expanding For i as Byte = 0 To counter.Length - 1 Dim combined as String = results(i) If Debug = true Then hs.writelog("Counter: " & i, "Key & Value: " & combined) ' Add Key to new array (first part of results) Dim leftpart as String = combined.Split(":")(0) ' If Debug = true Then hs.writelog("leftpart", leftpart) leftpart = StrConv(leftpart, VbStrConv.ProperCase) DevicesArrayK.Add(leftpart) ' Add Value to new array (last part of result) Dim rightpart = combined.Split(":")(1) ' If Debug = true Then hs.writelog("rightpart", rightpart If leftpart = "Odometer" Then ' Odometer MySQL value is shown without decimal seperator, so it will be divided by 1000 and set to the correct units If UseMetrics = true Then rightpart = Math.Round(rightpart/1000, 3) ' /1000 and calculate to kilometers, 3 decimals Else rightpart = rightpart/1609.344 rightpart = Math.Round(rightpart, 3) ' /1000 and calculate to miles, 3 decimals End If DevicesArrayV.Add(rightpart) DevicesArrayE.Add("") If Debug = true Then hs.writelog("Odometer" , "Odometer new: " & rightpart & units) Elseif leftpart = "Totaldistance" Then rightpart = CLng(rightpart) rightpart = rightpart/1.609344 rightpart = Math.Round(rightpart,0) ' /1000 and calculate to miles DevicesArrayV.Add(rightpart) DevicesArrayE.Add("") Elseif leftpart = "Power" Then rightpart = Math.Round(rightpart*1, 2) DevicesArrayV.Add(rightpart) DevicesArrayE.Add("") Elseif leftpart = "Battery" Then rightpart = Math.Round(rightpart*1, 2) DevicesArrayV.Add(rightpart) DevicesArrayE.Add("") ' In case a "Battery" device will be created, you want to monitor the battery level as well. The dropdown menu of this device can be set manually after device creation. An additonal virtual device will go in alert modu when the dropdown value is reached (from high to low). DevicesArrayK.Add("Battery Monitor") ' Will contains a dropdown menu where a trigger value can be chosen. This value will be used to set the "battery Level Alert" device to ON/Off. Dim batterymonitor_old_Ref = hs.GetDeviceRefByName(DVaddress & "_Battery Monitor") If Debug = true Then hs.writelog("battmon_ref", DVAddress & " - " & batterymonitor_old_Ref) batterymonitor_old_data = hs.DeviceValueEx(batterymonitor_old_Ref) If Debug = true Then hs.writelog("battmon_val", DVAddress & " - " & batterymonitor_old_data) batterymonitor_old_data = batterymonitor_old_data If (batterymonitor_old_data = 0) DevicesArrayV.Add("0") DevicesArrayE.Add("") Else DevicesArrayV.Add(batterymonitor_old_data) End If DevicesArrayE.Add(" Volt") DevicesArrayK.Add("Battery Alert") DevicesArrayV.Add("") DevicesArrayE.Add("") Else DevicesArrayV.Add(rightpart) DevicesArrayE.Add("") End If Next Dim Accuracy = MyData("accuracy") If Debug = true Then hs.writelog("Accuracy", Accuracy) DevicesArrayK.Add("Accuracy") DevicesArrayV.Add(Accuracy) DevicesArrayE.Add("") ' Network object expanding Dim jsonN as String ' This is the string of json data that needs decoding jsonN = myData("network") ' Grab all content from Network column field, which can be sometimes empty(=null) If (IsDbNull(jsonN) OR String.IsNullOrEmpty(jsonN) OR jsonN="null") Then If Debug = true Then hs.writelog("Network", "DB field is empty") Else 'Possible result: {"radioType":"gsm","considerIp":false,"cellTowers":[{"cellId":14310,"locationAreaCode":3480,"mobileCountryCode": 204,"mobileNetworkCode":8,"signalStrength":16}]} If Debug = true Then hs.writelog("network", json) Dim jsonN1 = Replace(jsonN, "[", "") ' Remove bracket If Debug = true Then hs.writelog("jsonN1", jsonN1) Dim jsonN2 = Replace(jsonN1, "]", "") ' Remove bracket Dim jsonN3 = Replace(jsonN2, "{", "") ' Remove bracket Dim jsonN4 = Replace(jsonN3, "}", "") ' Remove bracket Dim jsonN5 = Replace(jsonN4, """", "") ' Remove double quotes, so plain text string is left over (aaa:123,zzz:654,etc) If Debug = true Then hs.writelog("jsonN5", jsonN5) If jsonN5.Contains("cellTowers") = True jsonN5 = Replace(jsonN5, "cellTowers:", "") If Debug = true Then hs.writelog("jsonN5-new", jsonN5) End If Dim counterN as String() = jsonN5.Split(",") ' Count amount of commas in String jsonN5, so we know how many devices should be created. If Debug = true Then hs.writelog("Attr-CounterN", counterN.Length) Dim resultsN() as String = jsonN5.Split(",") ' create array of all results For n as Byte = 0 To counterN.Length - 1 Dim combinedN as String = resultsN(n) If Debug = true Then hs.writelog("Counter: " & n, "KeyN & ValueN: " & combinedN) ' Add Key to new array (first part of results) Dim leftpartN as String = combinedN.Split(":")(0) leftpartN = StrConv(leftpartN, VbStrConv.ProperCase) DevicesArrayK.Add(leftpartN) ' Add Value to new array (last part of result) Dim rightpartN = combinedN.Split(":")(1) DevicesArrayV.Add(rightpartN) DevicesArrayE.Add("") Next End If End While End If conn.Close() conn.Dispose() ' Add additional device names to DevicesArray Dim latitude_dataKey as Integer = DevicesArrayK.IndexOf("Latitude", 1) Dim latitude_data = DevicesArrayV(latitude_dataKey) If Debug = true Then hs.writelog("Latitude", latitude_data) Dim longitude_dataKey as Integer = DevicesArrayK.IndexOf("Longitude", 1) Dim longitude_data = DevicesArrayV(longitude_dataKey) If Debug = true Then hs.writelog("Longitude", longitude_data) Dim course_dataKey as Integer = DevicesArrayK.IndexOf("Course", 1) Dim course_data = DevicesArrayV(course_dataKey) If Debug = true Then hs.writelog("Course", course_data) Dim lat_car = latitude_data Dim lon_car = longitude_data ' Start extra Motion checks Dim moving_data as Boolean = false ' Because at least in Traccar version 3.17 the "Motion" device is available, but the reported data is not always > 0, a check will be done on other devices to see if we can track motion ' When object Speed is available and > 0, then Motion is true. Dim speed_data Dim speed_dataKey as Integer = DevicesArrayK.IndexOf("Speed", 1) If speed_dataKey <> -1 ' Object exist If Debug = true Then hs.writelog("SpeedKey", speed_dataKey) speed_data = DevicesArrayV(speed_dataKey) If speed_data > 2 Then moving_data = true End If End If ' When object Status is available and > 0, then Motion is true. Dim status_data Dim status_dataKey as Integer = DevicesArrayK.IndexOf("Status", 1) If status_dataKey <> -1 ' Object exist If Debug = true Then hs.writelog("StatusKey", status_dataKey) status_data = DevicesArrayV(status_dataKey) If status_data > 0 Then moving_data = true End If End If ' When object Motion is available and True, then Motion is true. Dim motion_data Dim motion_dataKey = DevicesArrayK.IndexOf("Motion", 1) If motion_dataKey <> -1 ' Object exist If Debug = true Then hs.writelog("MotionKey", motion_dataKey) motion_data = DevicesArrayV(motion_dataKey) ' Result is a string If motion_data = "true" Then moving_data = true End If End If ' In the last case, the Totaldistance values from the current object and the previous one from Homeseer will be compared. When difference <> 0 then Motion is true. Dim totaldistance_new_data as Long ' Object value could be sometimes with an exponential (2.359254978E7), therefor calculation will give strange values Dim totaldistance_old_Ref = hs.GetDeviceRefByName(DVaddress & "_Totaldistance") Dim totaldistance_old_data = hs.Devicevalue(totaldistance_old_Ref) ' No decimal value taken here Dim totaldistance_diff Dim totaldistance_new_dataKey as Integer = DevicesArrayK.IndexOf("Totaldistance", 1) If totaldistance_new_dataKey <> -1 ' Object exist If Debug = true Then hs.writelog("TotaldistKey", totaldistance_new_dataKey) totaldistance_new_data = DevicesArrayV(totaldistance_new_dataKey) totaldistance_diff = totaldistance_new_data - totaldistance_old_data If totaldistance_diff > 1 Then moving_data = true End If End If If Debug = true Then hs.writelog("TD-old", totaldistance_old_data) If Debug = true Then hs.writelog("TD-new", totaldistance_new_data) If Debug = true Then hs.writelog("TD-diff", totaldistance_diff) ' Additional device to track motion data for several objects. Dim moving_string moving_string = speed_data & "|" & status_data & "|" & totaldistance_diff & "|" & motion_data & "|" & moving_data If Debug = true Then hs.writelog("moving_string", DVaddress & ": " & moving_string) DevicesArrayK.Add("Moving") DevicesArrayV.Add("") DevicesArrayE.Add(moving_data) ' Object Lastupdate Dim lastupdate_data Dim lastupdate_dataKey = DevicesArrayK.IndexOf("Lastupdate", 1) If lastupdate_dataKey <> -1 ' Object exist If Debug = true Then hs.writelog("Lastupdate_Ref", DVAddress & ": "& lastupdate_dataKey) lastupdate_data = DevicesArrayV(lastupdate_dataKey) If Debug = true Then hs.writelog("Lastupdate_Data", DVAddress & ": "& lastupdate_data) End If ' End extra Motion checks DevicesArrayK.Add("Google Maps") Dim google_maps as String = "<iframe width='240' height='240' frameborder='0' scrolling='no' marginheight='0' marginwidth='0' src='http://maps.google.nl/maps?q=" & latitude_data & "," & longitude_data & "&ie=UTF8&z=14&t=m&output=embed'></iframe><br />Link to <a href='http://maps.google.com/maps?q=" & latitude_data & "," & longitude_data & "' target='_blank'>location</a>" DevicesArrayV.Add(google_maps) DevicesArrayE.Add("") Dim Streetview_API_Ref = hs.GetDeviceRefByName(DVaddress & "_Streetview API") Dim Streetview_API_data = hs.DeviceValue(Streetview_API_Ref) ' If Debug = true Then hs.writelog("Google Maps", DVAddress & ": "& google_maps) If Debug = true Then hs.writelog("moving_data", "Moving override: " & moving_data) Dim streetview_web Dim streetview_open = streetview_open_path & "streetview_" & DVAddress & ".png" Dim streetview_store = streetview_store_path & "streetview_" & DVAddress & ".png" If Debug = true Then hs.writelog("UseStrtvw", UseGoogleStreetview) If UseGoogleStreetview = true ' For reducing the amount of API calls to Google, the Google url will be generated only when speed > 0, otherwise the saved image will be loaded which is generated at the entry when speed > 0. streetview_web = "https://maps.googleapis.com/maps/api/streetview?size=640x480&location=" & latitude_data & "," & longitude_data & "&heading=" & course_data & "&pitch=-0.76&key=" & GoogleStreetview_API Dim motion_Ref = hs.GetDeviceRefByName(DVaddress & "_Motion") Dim motion_data_timediff = DateDiff("s",hs.devicelastchangeref(motion_Ref),now) ' Calculate amount of seconds since last devicelastchange If Debug = true Then hs.writelog("Timediff", motion_data_timediff) If ((motion_data_timediff < 120 OR moving_data = "True" OR moving_data = True OR Streetview_API_data < 0) AND lastupdate_data < 600) Then ' Requesting API call continues 120 seconds after tracker has no motion anymore ' Save Streetview images to disk Dim fileReader as New WebClient() fileReader.DownloadFile(streetview_web, streetview_store) Streetview_API_data += 1 ' Increase API call counter If Debug = true Then hs.writelog("API value New", Streetview_API_data) If Debug = true Then hs.writelog("moving_string", DVaddress & ": " & moving_string) End If Dim streetview_data = "<img width='300' height='240' frameborder='0' scrolling='no' marginheight='0' marginwidth='0' src='" & streetview_open & "'</img><br />Link to <a href='" & streetview_open & "' target='_blank'>Streetview</a>" DevicesArrayK.Add("Google Streetview") DevicesArrayV.Add(streetview_data) DevicesArrayE.Add("") If Debug = true Then hs.writelog("strvw_web", streetview_web) If Debug = true Then hs.writelog("strvw_open", streetview_open) If Debug = true Then hs.writelog("strvw_store", streetview_store) DevicesArrayK.Add("Streetview API") DevicesArrayV.Add(Streetview_API_data) DevicesArrayE.Add(" API calls") End If If Debug = true Then hs.writelog("lat_tracker", lat_car) hs.writelog("lon_tracker", lon_car) hs.writelog("lat_home", lat_home) hs.writelog("lon_home", lon_home) hs.writelog("lat_work", lat_work) hs.writelog("lon_work", lon_work) End If DevicesArrayK.Add("Distance to Home") 'Calculate AERIAL distance to HOME in 'units' Dim dLat = (lat_car - lat_home) dLat = Math.PI * dLat / 180 Dim dLon = (lon_car - lon_home) dLon = Math.PI * dLon / 180 Dim lat_home1 = Math.PI * lat_home / 180 Dim lat_car1 = Math.PI * lat_car / 180 Dim a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Sin(dLon / 2) * Math.Sin(dLon / 2) * Math.Cos(lat_home1) * Math.Cos(lat_car1) Dim c = 2 * Math.Asin(Math.Sqrt(a)) Dim distance_from_home = R * 2 * Math.Asin(Math.Sqrt(a)) distance_from_home = Math.Round(distance_from_home, 3) ' Round on 3 decimals If Debug = true Then hs.writelog("to Home", distance_from_home & units) DevicesArrayV.Add(distance_from_home) DevicesArrayE.Add(units) DevicesArrayK.Add("Distance to Work") 'Calculate AERIAL distance to WORK in 'units' Dim dLat1 = (lat_car - lat_work) dLat1 = Math.PI * dLat1 / 180 Dim dLon1 = (lon_car - lon_work) dLon1 = Math.PI * dLon1 / 180 Dim lat_work2 = Math.PI * lat_work / 180 Dim lat_car2 = Math.PI * lat_car / 180 If Debug = true Then hs.writelog("lat_work2", lat_work2) If Debug = true Then hs.writelog("lat_car2", lat_car2) Dim a1 = Math.Sin(dLat1 / 2) * Math.Sin(dLat1 / 2) + Math.Sin(dLon1 / 2) * Math.Sin(dLon1 / 2) * Math.Cos(lat_work2) * Math.Cos(lat_car2) Dim c1 = 2 * Math.Asin(Math.Sqrt(a1)) If Debug = true Then hs.writelog("a1", a1) If Debug = true Then hs.writelog("c1", c1) Dim distance_from_work = R * 2 * Math.Asin(Math.Sqrt(a1)) distance_from_work = Math.Round(distance_from_work, 3) ' Round on 3 decimals If Debug = true Then hs.writelog("to Work", distance_from_work) DevicesArrayV.Add(distance_from_work) DevicesArrayE.Add(units) DevicesArrayK.Add("Presence Home") Dim PresenceHomeRef = hs.GetDeviceRefByName(DVaddress & "_Presence Home") Dim PresenceHome = hs.DeviceValueEx(PresenceHomeRef) If Debug = true Then hs.writelog("Pres.HomeRef", PresenceHomeRef) If Debug = true Then hs.writelog("Pres.HomeVal", PresenceHome) If distance_from_home <= GeofenceHome' AND PresenceHome = 0 DevicesArrayV.Add("100") ' Arrived at home when < xx units DevicesArrayE.Add("") Elseif distance_from_home > GeofenceHome' AND PresenceHome = 100 DevicesArrayV.Add("0") ' Away from home when > xx units DevicesArrayE.Add("") Else DevicesArrayV.Add("0") ' Away when no calculation can be made DevicesArrayE.Add("") End If DevicesArrayK.Add("Presence Work") Dim PresenceWorkRef = hs.GetDeviceRefByName(DVaddress & "_Presence Work") Dim PresenceWork = hs.DeviceValueEx(PresenceWorkRef) If Debug = true Then hs.writelog("Pres.WorkRef", PresenceWorkRef) If Debug = true Then hs.writelog("Pres.WorkVal", PresenceWork) If distance_from_work <= GeofenceWork' AND PresenceWork = 0 DevicesArrayV.Add("100") ' Arrived at work when < xx units DevicesArrayE.Add("") ElseIf distance_from_work > GeofenceWork' AND PresenceWork = 100 DevicesArrayV.Add("0") ' Away from work when > xx units DevicesArrayE.Add("") Else DevicesArrayV.Add("0") ' Away when no calculation can be made DevicesArrayE.Add("") End If Dim odometer_night Dim odometer_nightRef Dim odometer_currRef Dim odometer_curr Dim totdistance_currRef Dim totdistance_currData ' 2 Extra devices, which are created in script "MySQL_Traccar_DailyDistance", will be updated here 'Calculate daily distance ' Get value from last night odometer_nightRef = hs.GetDeviceRefByName(DVaddress & "_Odometer Night") odometer_night = hs.DeviceValueEx(odometer_nightRef) If debug = true Then hs.writelog("Odo-night", "odometer_night: " & odometer_nightRef & ": " & odometer_night) ' Get current Odometer value odometer_currRef = hs.GetDeviceRefByName(DVaddress & "_Odometer") If odometer_currRef <> -1 odometer_curr = hs.DeviceValueEx(odometer_currRef) If debug = true Then hs.writelog("Odo-current", "odometer_curr: " & odometer_currRef & ": " & odometer_curr) Else totdistance_currRef = hs.GetDeviceRefByName(DVaddress & "_Totaldistance") totdistance_currData = hs.DeviceValueEx(totdistance_currRef) If debug = true Then hs.writelog("Totdist-current", "Totaldistance_curr: " & totdistance_currRef & ": " & totdistance_currData) End if ' Check if Battery value is lower than the Battery Monitor value. If true, then set Battery Alert to On. Dim battery_Ref = hs.GetDeviceRefByName(DVaddress & "_Battery") Dim battery_Data = hs.DeviceValueEx(battery_Ref) If Debug = true Then hs.writelog("battery_Data", battery_Data) Dim batterymonitor_Ref = hs.GetDeviceRefByName(DVaddress & "_Battery Monitor") Dim batterymonitor_Data = hs.DeviceValueEx(batterymonitor_Ref) If Debug = true Then hs.writelog("battmon_data", batterymonitor_Data) If (battery_Data <= batterymonitor_Data) Then Dim batteryalert_Ref = hs.GetDeviceRefByName(DVaddress & "_Battery Alert") hs.setDeviceValueByRef(batteryalert_Ref, 100, true) ' Dim url = "http://" & HS_IPAddress & "/JSON?request=controldevicebylabel&ref=" & batteryalert_Ref & "&label=On" ' Dim finalurl = hs.URLAction(url, "GET", "", "") If Debug = true Then hs.writelog("battery_alert", "greater") ' If Debug = true Then hs.writelog("alert_url", url) End If ' Check if Traccar Root device is created. If not, than create all devices. DevExists = hs.DeviceExistsAddress(DVaddress & "_Root Device", False) If Debug = true Then hs.writelog("DevExists", "Root device ref ID: " & DevExists) If DevExists = -1 ' Create all child devices For i as Byte = 0 To DevicesArrayK.Count - 1 Select Case i Case 0 ' Create Traccar Root Device dv = hs.GetDeviceByRef(hs.NewDeviceRef(DVaddress &"_Root Device")) dv.Address(hs) = DVaddress & "_Root Device" BaseRef = dv.Ref(hs) hs.SetDeviceValueByRef(dv.Ref(hs), DevicesArrayK.Count - 1, True) hs.SetDeviceString(dv.Ref(hs), "No Status", True) Case 1 To DevicesArrayK.Count - 1 ' Create child devices dv = hs.GetDeviceByRef(hs.NewDeviceRef(DVaddress & "_" & DevicesArrayK(i))) ' Fill Homeseer Name Column ' dv.Address(hs) = DVaddress & i ' Fill Homeseer DVaddress+counter in Address column ' dv.Address(hs) = DVaddress & DevicesArrayK(i) ' Fill Homeseer DVaddress+name in Address column dv.Address(hs) = DVaddress & "_" & i & "_" & DevicesArrayK(i) ' Fill Homeseer DVaddress+name in Address column. Counter(i) added for descent sorting End Select dv.Location2(hs) = "GPS" & "_" & DVAddress 'Floor dv.location(hs) = "Traccar" 'Room dv.Device_Type_String(hs) = DVaddress ' Set up the relationships between the devices If i = 0 Then root_dv = dv dv.Relationship(hs) = Enums.eRelationship.Parent_Root Else If root_dv IsNot Nothing Then root_dv.AssociatedDevice_Add(hs, dv.Ref(hs)) dv.Relationship(hs) = Enums.eRelationship.Child dv.AssociatedDevice_Add(hs, BaseRef) End If ' Extend virtual devices with icons, value ranges etc Select Case DevicesArrayK(i) Case "Root Device" Dim SPair as VSPair Dim GPair as VGPair GPair = New VGPair GPair.PairType = VSVGPairType.Range GPair.RangeStart = -99999999999 GPair.RangeEnd = 99999999999 GPair.Graphic = "/images/HomeSeer/status/nostatus.gif" hs.DeviceVGP_AddPair(dv.Ref(hs), GPair) Case "Battery Monitor" Dim SPair As VSPair Dim GPair As VGPair ' hs.SetDeviceValue(dv.Ref(hs), "0") For index As Double = 2 To 8 Step 0.1 SPair = New VSPair(HomeSeerAPI.ePairStatusControl.Control) SPair.PairType = VSVGPairType.SingleValue SPair.Value = Math.Round(index,1) SPair.RangeStatusDecimals = 1 SPair.Render = Enums.CAPIControlType.Values SPair.Status = Format(Math.Round(index, 1), "0.0").ToString & " Volt" If Debug = true Then hs.writelog("BattMon", index & " - " & dv.Ref(hs)) hs.DeviceVSP_AddPair(dv.Ref(hs), SPair) Next Case "Battery Alert" Dim SPair As VSPair Dim GPair As VGPair GPair = New VGPair ' hs.SetDeviceValue(dv.Ref(hs), "0") GPair.PairType = VSVGPairType.SingleValue GPair.Set_Value = 0 GPair.Graphic = "/images/HomeSeer/status/off.gif" hs.DeviceVGP_AddPair(dv.Ref(hs), GPair) GPair = New VGPair GPair.PairType = VSVGPairType.SingleValue GPair.Set_Value = 100 GPair.Graphic = "/images/HomeSeer/status/on.gif" hs.DeviceVGP_AddPair(dv.Ref(hs), GPair) SPair = New VSPair(HomeSeerAPI.ePairStatusControl.Both) SPair.PairType = VSVGPairType.SingleValue SPair.Value = 0 SPair.Status = "Off" SPair.ControlUse = HomeSeerAPI.ePairControlUse._Off SPair.Render = HomeSeerAPI.Enums.CAPIControlType.Button SPair.IncludeValues = True hs.DeviceVSP_AddPair(dv.Ref(hs), SPair) SPair = New VSPair(HomeSeerAPI.ePairStatusControl.Both) SPair.PairType = VSVGPairType.SingleValue SPair.Value = 100 SPair.Status = "On" SPair.ControlUse = HomeSeerAPI.ePairControlUse._On SPair.Render = HomeSeerAPI.Enums.CAPIControlType.Button SPair.IncludeValues = True hs.DeviceVSP_AddPair(dv.Ref(hs), SPair) End Select dv.MISC_Set(hs, Enums.dvMISC.SHOW_VALUES) Next ' Start Create Traccar DailyDistance event Dim EventRef as Integer Dim OldEventRef as Integer Dim EvTime as Date Dim EventExists as Integer EventExists = hs.GetEventRefByName(strEventName) If EventExists = -1 ' Create the new Event EventRef = hs.NewEventEx(strEventName, strEventGroup, "") ' Status of Event hs.EnableEventByRef(EventRef) ' ' Set Event frequency to recurring 20 seconds // ... days, hours, minutes, seconds, milliseconds. ' Dim span as TimeSpan = New TimeSpan(0, 0, 0, 20, 0) ' hs.EventSetRecurringTrigger(EventRef, span, false, false) ' Set Event frequency to once per dag // at 23:59:05 hrs. hs.EventSetTimeTrigger(EventRef,"23:59:05") ' Will be saved also as 11:59:05 PM ' Log created event details Try hs.AddActionRunScript(EventRef, strEventLaunchScript, strEventLaunchByNameProc, strEventLaunchProcParams) If Debug = true Then hs.writelog(ScriptName , "New Event " & strEventName & " created.") If Debug = true Then hs.writelog(ScriptName , "Event Ref: " + Str(EventRef)) If Debug = true Then hs.writelog(ScriptName , "Event Group: " + strEventGroup) If Debug = true Then hs.writelog(ScriptName , "Event Type: " + strEventLaunchByRefProc) If Debug = true Then hs.writelog(ScriptName , "Event Script: " + strEventLaunchScript) ' If Debug = true Then hs.writelog(ScriptName , "Event Calls this Procedure: " + strEventLaunchByNameProc ) ' If Debug = true Then hs.writelog(ScriptName , "With These Parameters: " + strEventLaunchProcParams ) Catch ex as Exception hs.writelog(ScriptName, String.Format("Error adding event action to event '{0}': {1}", strEventName, ex.Message)) Throw Ex End Try ' Run event once, so the table will be created immediately (and additional sub device will be created as well) hs.TriggerEvent("Traccar_DailyDistance") End If ' EndCreate Traccar DailyDistance event End If ' End creating devices and events ' Update virtual devices For i as Byte = 0 To DevicesArrayK.Count - 1 If Debug = true Then hs.writelog("Array: "&i, DevicesArrayK(i) & " - " & DevicesArrayV(i) & " " & DevicesArrayE(i)) Dim update = hs.GetDeviceRefByName(DVaddress & "_" & DevicesArrayK(i)) ' If Debug = true Then hs.writelog("updateVal", update) ' Check if array key is already available as virtual device. If not, than create it. ' If Debug = true Then hs.writelog("To Update", DVaddress & "_" & DevicesArrayK(i)) If update = -1 ' Virtual device doesn't exists ' In the Traccar Root device, the total device counter value is stored. Based on this number, the new devices will get the followup number Dim RootCounterRef = hs.DeviceExistsAddress(DVaddress & "_Root Device", False) Dim RootCounter as Integer If RootCounterRef > 0 RootCounter = hs.Devicevalue(RootCounterRef) + 1 If Debug = true Then hs.writelog("RootCounter", RootCounter) End If If Debug = true Then hs.writelog("DevNotExists", DVaddress & "_" & DevicesArrayK(i)) ' Create child devices dv = hs.GetDeviceByRef(hs.NewDeviceRef(DVaddress & "_" & DevicesArrayK(i))) ' Fill Homeseer Name Column dv.Address(hs) = DVaddress & "_" & RootCounter & "_" & DevicesArrayK(i) ' Fill Homeseer DVaddress+name in Address column. Counter(i) added for descent sorting dv.Location2(hs) = "GPS" & "_" & DVAddress 'Floor dv.location(hs) = "Traccar" 'Room dv.Device_Type_String(hs) = DVaddress If root_dv IsNot Nothing Then root_dv.AssociatedDevice_Add(hs, dv.Ref(hs)) dv.Relationship(hs) = Enums.eRelationship.Child dv.AssociatedDevice_Add(hs, BaseRef) ' Extend virtual devices with icons, value ranges etc hs.SetDeviceValue(dv.Ref(hs), "0") Dim SPair as VSPair Dim GPair as VGPair GPair = New VGPair GPair.PairType = VSVGPairType.Range GPair.RangeStart = -99999999999 GPair.RangeEnd = 99999999999 GPair.Graphic = "/images/Traccar/5-x-5_trans_spacer.gif" hs.DeviceVGP_AddPair(dv.Ref(hs), GPair) 'Save RootCounter in Root device hs.SetDeviceValueByRef(RootCounterRef, RootCounter, true) End If Dim inttest as Integer Dim doubletest as Double Try ' True when value is an Integer inttest = Convert.ToInt32(DevicesArrayV(i)) hs.SetDeviceValueByRef(update, DevicesArrayV(i), true) hs.SetDeviceString(update, DevicesArrayV(i) & DevicesArrayE(i), true) Catch ' Value isn't an Integer hs.SetDeviceString(update, DevicesArrayV(i) & DevicesArrayE(i), true) End Try Try ' True when value is a Double doubletest = Convert.ToDouble(DevicesArrayV(i)) hs.SetDeviceValueByRef(update, DevicesArrayV(i), true) Catch ' Value isn't a Double hs.SetDeviceString(update, DevicesArrayV(i) & DevicesArrayE(i), true) End Try Next Dim odometer_daily ' Calculate daily distance Dim odometer_dailyRef = hs.GetDeviceRefByName(DVaddress & "_Odometer Daily") If Debug = true Then hs.writelog("DevExists", "Odometer Daily device ref ID: " & odometer_dailyRef) ' Check if "Odometer" exists, if not, take value from "Totaldistance" odometer_currRef = hs.GetDeviceRefByName(DVaddress & "_Odometer") If odometer_currRef <> -1 odometer_daily = (odometer_curr - odometer_night) odometer_daily = Math.Round(odometer_daily, 3) If Debug = true Then hs.writelog("Odo-daily", "odometer_daily: " & odometer_dailyRef & ": " & odometer_daily) Else ' totdistance_currRef = hs.GetDeviceRefByName(DVaddress & "_Totaldistance") totdistance_currRef = hs.GetDeviceRefByName(DVaddress & "_Io16") totdistance_currData = hs.DeviceValueEx(totdistance_currRef) If Debug = true Then hs.writelog("Totdist-data", totdistance_currData) odometer_daily = ((totdistance_currData - odometer_night))/1000 odometer_daily = Math.Round(odometer_daily, 3) If Debug = true Then hs.writelog("Totdist-daily", "Totaldistance: " & totdistance_currRef & ": " & odometer_daily) End If hs.SetDeviceValueByref(odometer_dailyRef, odometer_daily, true) hs.SetDeviceString(odometer_dailyRef, odometer_daily & units, true) If Debug = true Then hs.writelog("XXXXX", "XXXXXXXXXXXXXXXXX End " & DVaddress & " XXXXXXXXXXXXXXXXX") ' Clear arrays and variables DevicesArrayD.Clear() DevicesArrayN.Clear() DevicesArrayK.Clear() DevicesArrayV.Clear() DevicesArrayE.Clear() DVAddress = Nothing streetview_store = Nothing streetview_open = Nothing streetview_web = Nothing odometer_dailyRef = Nothing odometer_daily = Nothing streetview_store = Nothing streetview_open = Nothing odometer_curr = Nothing odometer_night = Nothing Columnname = Nothing Columnvalue = Nothing batterymonitor_old_data = Nothing End While End If conn.Close() conn1.Close() conn.Dispose() conn1.Dispose() Catch myerror as MySqlException hs.writelog("Traccar", "Error Connecting to Database " & DBtraccar & ": " & myerror.Message) If conn.State = ConnectionState.Open Then If Debug = true Then hs.writelog("Traccar", "Connection to database " & DBtraccar & " will be closed now.") conn.Close() conn.Dispose() If Debug = true Then hs.writelog("Traccar", conn.State) Else If Debug = true Then hs.writelog("Traccar", "Connection to database " & DBtraccar & "is already closed.") End If End Try End Sub ' Sub ButtonPress(Input As Object) ' Dim Debug as Boolean = true ' true/false ' Dim DevID As Integer = Input(0) 'Integer - The device reference ID. ' Dim ScriptCallParm As String = Input(1) 'String - Script Parm Passed from Button ' Dim dv1 = hs.GetDeviceByRef(DevID) ' Dim DevTypePid = dv1.Device_Type_String(hs) ' If Debug = True Then hs.Writelog("AddButton", ScriptCallParm & " has been pressed!") ' If Debug = True Then hs.Writelog("AddButton", "DevID: " & DevID) ' If Debug = True Then hs.Writelog("AddButton", "DevTypePid: " & DevTypePid) ' ' Reset ' If ScriptCallParm = "ButtonReset" Then ' hs.SetDeviceValueByRef(DevID, "Off", True) ' ' hs.SetDeviceString(DevID, hs.DeviceString(DevID)+1, True) ' End If ' End Sub
Comment