for loop inside of body of email lua script - email

Basically, I have several devices I need to pull data from. I get multiple emails when the temperature measures are under or over the set limits. I would like to have a for loop to include all current devices states that are under or over limits into one email.
body = for device_name, 1 do
device_name++ -- I get error here because unexpected symbol near 'for'
"Device Name: " ..device_name.. "\nDevice Location: " ..device_location..
"\n--------------------------------------------------------------" ..
"\nCurrent Temperature: " ..temperature.." F".. "\nTemperature Limit: ("..
t_under_limit.. "-" ..t_over_limit.. " F)" .."\n\nCurrent Humidity Level: " ..
humidity .. "%".. "\nHumidity Limit: (" .. h_under_limit.. "-" ..h_over_limit.. "%)"
.. "\n\n-------Time Recorded at: " ..os.date().. "-------"})
end, -- end for

there is no variable++ syntax in lua. you need to do
variable = variable + 1
also, you can't assign some for loop construct to a variable. so this statement
body = for device_name, 1, ...
isn't valid. maybe you meant...
local body = ""
for device_name = 1, 1
device_name = device_name + 1
body = body.. "my custom message stuff here"
end

As previously noted, there is no ++ operator in Lua. Also, the syntax for the for loop is different from what you wrote.
I would like to add that the big concatenation afterwards would be much more readable using string.format. Here is an enhanced version of your code, in the form a a function taking a table devices parameters in input, each element being a subtable:
local report_model = [[
Device Name: %s
Device Location: %s
--------------------------------------------------------------
Current Temperature: %d °F
Temperature Limit: (%d-%d °F)
Current Humidity Level: %d %%
Humidity Limit: (%d-%d %%)
-------Time Recorded at: %s-------]]
function temp_report(devices)
local report = {}
for i=1,#devices do
local d = devices[i]
report[i] = report_model:format(d.name, d.location,
d.temperature, d.t_under_limit, d.t_over_limit,
d.humidity, d.h_under_limit, d.h_over_limit,
os.date())
end
return table.concat(report)
end

Related

VBA Excel make array of sequential numbers

I am working in VBA for Excel at the moment but am really only versed in Matlab. It's important for my work to stay in the memory of vba (not on the worksheets of excel) for time purposes.
What I need to do is make an array of sequential integers, say 4000 through 5000.
In matlab this is really easy, I would just do... i = 4000:5000, or i=4000:1:5000. With the 1 in the second case being my 'step.'
I was wondering what is the best way to achieve this result in vba?
Thanks
Without looping - Just seen Rory's same answer above after posting
Sub MakeArray()
Dim x As Long, y As Long, arr As Variant
x = 4000: y = 5000
arr = Evaluate("Row(" & x & ":" & y & ")")
'Show result
Sheets(1).Range("A1").Resize(y - x + 1) = arr
End Sub
The following is an example of creating and then displaying a set of sequential numbers:
Sub seqnum()
Dim firstnum As Long, secnum As Long
firstnum = 7
secnum = 23
ReDim ary(1 To secnum - firstnum + 1) As Long
For i = 1 To UBound(ary)
ary(i) = firstnum + (i - 1)
Next i
msg = ""
For i = 1 To UBound(ary)
msg = msg & i & vbTab & ary(i) & vbCrLf
Next i
MsgBox msg
End Sub
I Us "Fill" - "Series":
Write in first cell number ex. 400 and in the "Series" window insert increment step and in "Stop Value" last value. ex. 420
Or with Macro
Range("I1").Select
ActiveCell.FormulaR1C1 = "4000"
Range("I1").Select
Selection.DataSeries Rowcol:=xlColumns, Type:=xlLinear, Date:=xlDay, _
Step:=1, Stop:=4020, Trend:=False

Finding notes sounding at the same time in a different voice in a midi file

I have a midi file consisting of two parts. Now I need to print out, for each note in part 0 (including rests), which note sounds at the same time in part 1 (and the note that proceeds this).
I can go through all of the notes in part 0 with music21, but how do I find the note at that time in part 1. Will I need to use end times? Or is there a function for this?
for thisNote in s.parts[0].notes:
print thisNote.ps
Here is a very interesting function that let me solve this:
secondPart = s.parts[1]
for thisNote in s.parts[0].notes:
sys.stdout.write('at ' + str(thisNote.offset) + ' toppitch: ' + str(thisNote.ps))
soundingNotes = secondPart.getElementsByOffset(thisNote.offset, mustFinishInSpan=False, mustBeginInSpan=False)
try:
if soundingNotes > 0:
basslength = len(soundingNotes)
except:
basslength = 0
if basslength > 1:
print "oh ow, more then one note sounding in the bass."
if basslength > 0:
if soundingNotes[0].isRest:
sys.stdout.write(' bottompitch: R')
else:
sys.stdout.write(' bottompitch: ' + str(soundingNotes[0].ps)) # + ' from ' + str(soundingNotes[0].offset))
# print the previous note
soundingNotes2 = secondPart.getElementsByOffset(thisNote.offset-1, mustFinishInSpan=False, mustBeginInSpan=False)

Interpretting Data from a Serialized Network Packet

I have followed the tutorials on (https://pcapdotnet.codeplex.com) to setup my program for packet capturing and I am told that the packet is serialized by protobuf. Currently convertiing the packet to a string (like shown at the bottom) only works for a very little bit of information and will not suffice.
I can't figure out how to get the packet into an acceptable format from below to be able to deserialize it into a format I can use. Below is an example of the packet as it appears in Wireshark.
DRDNi|L.TE#4jcP""P.-h"
2
"
:
"
2
"
"
:
"
2
"
"
"
"
"
"
"
"
:
"
2
"$
"%
"4
"
"
"
"#
"
"
"
"4+
"
:
"
2
"
:
"
2
A?CCS2_121-/01
"C
"
:
"
2
"
:
"
I am expecting the packets to be in a format similar to this (from what I've been told).
list: <
show_entity: <
entity: 29
name: "EX1_306"
tags: <
name: 45
value: 3
>
tags: <
name: 47
value: 4
>
tags: <
name: 48
value: 2
>
tags: <
name: 49
value: 1
>
tags: <
name: 201
value: 3
>
tags: <
name: 202
value: 4
>
tags: <
name: 203
value: 2
>
tags: <
name: 218
value: 1
>
>
The code below is what I am using to capture the packet and convert it to the format where I can read a bit of the information. I can't get the protobuf to deserialize it into any format.
Private Sub PacketCap()
Dim Index As Integer = 0
Dim allDevices As IList(Of LivePacketDevice) = LivePacketDevice.AllLocalMachine
Dim device As LivePacketDevice = allDevices(1)
Dim Selecteddevice As PacketDevice = device
Using communicator As PacketCommunicator = Selecteddevice.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 1000)
communicator.SetFilter("port 3724")
' read timeout
' start the capture
packetcount = 0
Invoke(New MethodInvoker(Sub()
MetroListbox1.Items.Add("Started Cap")
End Sub))
communicator.ReceivePackets(0, AddressOf PacketHandler)
End Using
End Sub
Private Sub MetroButton2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MetroButton2.Click
Dim N As New Threading.Thread(AddressOf PacketCap)
N.Start()
End Sub
Private Sub PacketHandler(ByVal packet As PcapDotNet.Packets.Packet)
Invoke(New MethodInvoker(Sub()
'ListBox1.Items.Add(packet.Timestamp.ToString("yyyy-MM-dd hh:mm:ss.fff") & " length:" & Convert.ToString(packet.Length) + packet.ToString("X2"))
If packet.Length < 200 Then
Else
Const LineLength As Integer = 64
Dim Info As String
Dim i As Integer = 0
While i <> packet.Length
Info = Info + (packet(i)).ToString("X2")
If (i + 1) Mod LineLength = 0 Then
End If
i += 1
End While
End If
End Sub))
Sorry about the 'almost complete' formatting, this is my first question here. Any help is appreciated
The wire specification is here. However, the protobuf format is formally ambiguous in the absence of a schema (usually via a .proto file). There is no one single way of interpreting the data. However, you can probably make some wild guesses based on the wire-type (take the first 3 bits of the header).
0 is a varint; probably best to simply decode the varint and display it as though it is an int64
1 is 64-bit... tricky - no real way to choose between these; perhaps assume fixed64?
2 is length-prefixed - you could try the nested content to see if it is UTF-8; if it is, assume it is a string; otherwise, see if it parses as a sub-object; however, it could also be a packed array which is tricky
3 is start group - nested sub-object
4 is end group - end of the above
5 is 32-bit - like 1 - perhaps assume fixed32?
Frankly, though, this is going to be so hit and miss (mostly miss) that I don't see much point.

macro to extract dates from a weeks date range string and add 7 days to print next date range

I am writing a macro that processes an excel with lots of data. One of the rows contains a date range like wkstartdate - wkenddate and I would like to use dateadd function to print next date range every week (like '27-01-14 - 02-02-14' in below case) but unable to do so.
'06-01-14 - 12-01-14'
'13-01-14 - 19-01-14'
'20-01-14 - 26-01-14'
I used below excerpt which fails:
Range("E" & Lastrow).Select
prwk = Split(ActiveCell.Value, "-")
'curr_wkstart = DateAdd("d", 7, prwk(1)) 'error as maybe prwk(1) isnt correct format
'curr_wkend = DateAdd("d", 7, prwk(2)) 'error
Range("E" & Lastrow + 1).Value = curr_wkstart & curr_wkend 'no result
For testing purpose I print, prwk(1) which is 20/01/14 in the above case, in a diff cell and add 7 days, which gives me 1/21/2020 instead of '27/01/14'. I also tried using Cdate function, but still error
Can you please advise??
I think what you want to use here are the Format and DateSerial functions. Here's how I came at it:
Function GetNextWeek(TheStartWeek)
a = Split(TheStartWeek, " - ")
b = Split(a(1), "-")
c = DateSerial(b(2), b(1), b(0)) + 1
d = c + 6
GetNextWeek = Format(c, "dd-mm-yy") & " - " & Format(d, "dd-mm-yy")
End Function
Sub Test()
Debug.Print GetNextWeek("13-01-14 - 19-01-14") 'Givs you "20-01-14 - 26-01-14"
End Sub
Hope this helps.

Can images be read from an iPhone programmatically using CreateFile in Windows?

When an iPhone is connected to a Win7 computer, the images can be viewed using Explorer (and the open file dialog of my app). However, the file location does not contain a drive letter.
For example Computer\Apple iPhone\Internal Storage\DCIM\800AAAAA\IMG_0008.JPG instead of E:\DCIM\800AAAAA\IMG_0008.JPG which is common of sdcards, usb drives, etc...
I've tried using CreateFileW to read images from an iPhone but it fails with '(Error Code: 3) The system cannot find the path specified.' I've also tried accessing them with Chrome and it fails too.
Any suggestions?
The folder is actually what is referred to as a 'Virtual Folder' and does not have a full path on the file system. You will need to use the shell item returned from the open dialog to get the content of the file rather than using CreateFile.
The data should be accessible, but you should follow the instructions from the MSDN documentation. I'm sure there are probably better examples (as this only gives guidelines).
edit the rough process is to get the IShellItem from IFileOpenDialog, then to bind to the stream and then read the stream (assuming reading only) - bear in mind that this code is pretty much without error handling or checking or safety:
if (pitem->GetDisplayName(SIGDN_NORMALDISPLAY, &destName) == S_OK) {
std::cout << destName << std::endl;
CoTaskMemFree(destName);
}
IStream *pistream;
if (pitem->BindToHandler(0, BHID_Stream, IID_PPV_ARGS(&pistream)) == S_OK) {
char input[1024];
long to_read = 1024;
unsigned long read;
while (S_OK == pistream->Read(input, to_read, &read)) {
std::cout << input << std::endl;
}
pistream->Release();
}
pitem->Release();
Most often such a device is inserted in the Windows Explorer as a Shell Namespace Extension and not like an USB stick with drive letter. Most of the normal file commands like CopyFile(..), FindFirst() or GetFileInfo(..) can not be used directly in such a Shell Namespace extension. Only the CopyHere(..) is working.
I needed long time to figure out how to enumerate the files on a digicam and now also on an Android device with an vb.net program and to copy my pictures to my Windows PC:
Public Const MyComputer As Integer = &H11&
Sub EnumMyComputer()
Dim oItem As Object
Dim res As Integer
For Each oItem In DirectCast(CreateObject("Shell.Application").Namespace(MyComputer).Items, System.Collections.IEnumerable)
Debug.Print(oItem.Type.ToString)
if oItem.Type.ToString="Tragbares Medienwiedergabegerät" then '<- check, adopt!
res = EnumNamespaceItems(oItem, "", oItem.Name.ToString, 0)
End If
Next oItem
End Sub
Function EnumNamespaceItems(oItem As Object, SrcCPath As String, SrcDPath As String, folderLevel As Integer) As Integer
Dim y As Object
Dim tempFullFileName As String
Debug.Print(StrDup(folderLevel, " ") & "\" & oItem.Name.ToString & " (" & oItem.Path.ToString & ")")
For Each y In DirectCast(oItem.GetFolder.items, System.Collections.IEnumerable)
'Debug.Print(StrDup(folderLevel, " ") & SrcDPath & y.Name.ToString)
If y.IsFolder = True Then
Dim n1 As Integer
n1 = EnumNamespaceItems(y, SrcCPath & y.Path.ToString & "\", SrcDPath & y.Name.ToString & "\", 1 + folderLevel)
If n1 < 0 Then 'failure: Cancel
EnumNamespaceItems = n1
Exit Function
End If
Else 'it's a file:
Debug.Print(StrDup(folderLevel, " ") & " " & y.Name.ToString)
tempFullFileName = System.IO.Path.GetTempPath() & y.Name.ToString
' CopyFile is not possible here if SrcCPath is like "::{…}…":
' My.Computer.FileSystem.CopyFile(SrcCPath & y.Name.ToString , fFile.FullName)
Dim suc As Integer = CopyHereFileWait(y, My.Computer.FileSystem.SpecialDirectories.Temp)
If suc >= 0 Then 'now we can do things like this:
Dim MyFileInfo As System.IO.FileInfo = My.Computer.FileSystem.GetFileInfo(tempFullFileName)
Dim fileDate As Date = MyFileInfo.LastWriteTime
End If 'suc
End If 'else y.IsFolder
Next y
EnumNamespaceItems = 0
End Function
Function CopyHereFileWait(sourceNamespaceObject As Object, targetFolder As String) As Integer
Dim fsMyStream As System.IO.FileStream
Dim n1 As Integer
Dim taregetFullFileName As String
n1 = Len(targetFolder)
If Mid(targetFolder, n1, 1) = "\" Then
targetFolder = Microsoft.VisualBasic.Left(targetFolder, n1 - 1)
End If
taregetFullFileName = targetFolder & "\" & sourceNamespaceObject.Name.ToString
Dim oNsTargetFolder As Object
oNsTargetFolder = CreateObject("Shell.Application").Namespace(CStr(targetFolder))
oNsTargetFolder.copyHere(sourceNamespaceObject)
'returns immediately and is doing the work in the background
n1 = 0
Do
Threading.Thread.Sleep(50) 'ms
Try
fsMyStream = System.IO.File.Open(taregetFullFileName, IO.FileMode.Open, IO.FileAccess.ReadWrite)
fsMyStream.Close()
CopyHereFileWait = n1
Exit Function
Catch ex As Exception
Debug.Print(ex.Message)
End Try
n1 = n1 + 1
Loop While n1 < 400 'timeout 400*50ms = 20s
CopyHereFileWait = -n1
End Function
You may add to check for folders with y.Name.ToString="DCIM" (on folderLevel=1) and for files with ".jpg".