conditional statement with logical operators for thingspeak data - matlab

I am working on a thingspeak code on matlab analysis for my weather station which checks last 24 readings and then gives alert on the basis of given conditions, and I gave this condition but I guess I am messing up with something hence getting wrong results. I want the answer to be overall logical 1 or 0. I get 1's for even the values that should not give me one and the answer for both variables is a 24*1 logical array. But even then the tweets are not being generated as well. Here's my code;
t =thingSpeakRead(293182,'Fields',1,'NumPoints',24,'OutputFormat','matrix');
h =thingSpeakRead(293182,'Fields',2,'NumPoints',24,'OutputFormat','matrix');
DangerAlert = ((t>42.5)&(t<43.5)&(h>17)&(h<21))|(((t>40.5)&(t<43.5))&((h>21)&(h<27)))|((t>39.5)&(t<43.5)&(h>27)&(h<31)) | ((t>38.5)&(t<43.5)&(h>31)&(h<37))| ((t>37.5)&(t<42.5)&(h>37)&(h<41))| ((t>36.5)&(t<40.5)&(h>41)&(h<47))| ((t>35.5)&(t<39.5)&(h>47)&(h<51))| ((t>34.5)&(t<38.5)&(h>51)&(h<57))| ((t>33.5)&(t<38.5)&(h>57)&(h<68))| ((t>33.5)&(t<37.5)&(h>63)&(h<68)) | ((t>32.5)&(t<38.5)&(h>68)&(h<73)) | ((t>31.5)&(t<35.5)&(h>73)&(h<83))| ((t>30.5)&(t<33.5)&(h>83)&(h<88)) | ((t>29.5)&(t<33.5)&(h>83)&(h<93))| ((t>29.5)&(t<32.5)&(h>93)&(h<100))
HeatStrokeAlert=((t>42.5)&(t<43.5)&(h>37)&(h<41)) | ((t>40.5)&(t<2.5)&(h>41)&(h<47)) | ((t>39.5)&(t<41.5)&(h>47)|(h<51))| ((t>38.5)&(t<40.5)&(h>51)&(h<57))| ((t>38.5)&(t<39.5)&(h>57)&(h<63))| ((t>37.5)&(t<38.5)&(h>63)&(h<68))| ((t>36.5)&(t<38.5)&(h>68)&(h<78))| ((t>35.5)&(t<37.5)&(h>73)&(h<83)) | ((t>34.5)&(t<36.5)&(h>83)&(h<88)) | ((t>33.5)&(t<36.5)&(h>88)&(h<93)) | ((t>33.5)&(t<35.5)&(h>93)&(h<97)) | ((t>32.5)&(t<34.5)&(h>97))
if DangerAlert
webwrite('http://api.thingspeak.com/apps/thingtweet/1/statuses/update','api_key', 'XXXXXXXXXXXXX', 'status', 'Alert!Dangerously High temperature tomorrow!')
end
if HeatStrokeAlert
webwrite('http://api.thingspeak.com/apps/thingtweet/1/statuses/update','api_key', 'XXXXXXXXX', 'status', 'Alert!Heat Stroke alert tomorrow!')
end
I know the blunder is minor.But this needs to solve.

Your range values for t go from 29.5 to 43.5, and for h go from 17 to 100. So any value you put in between those numbers will give you a 1, because you are using the OR statements ||. So if ANY one of those is true, it will come back true (=1).
Also, for the website, make sure you follow these directions:
https://www.mathworks.com/help/matlab/ref/webwrite.html
Make sure you have a ThinkSpeak account, and try changing your URL to match their format:
[thingSpeakURL 'update'];
So add 'update' string and use brackets.
Also, set your if statement expression to one. So:
if DangerAlert = 1

Related

Rx.Net How can I emit an element when a source sequence has been idle for a time?

I want to create a sequence that emits a value (let's say 'true') whenever a source sequence emits a value. Then, when the source sequence is idle for a period of time, emits 'false'. Essentially, I need to know when the source sequence is 'idle' for some time.
Source: ---1-----5-------2-------(timeout)--------8-----3------>
| | | | | |
Output: ---true--true----true----false------------true--true--->
In actual fact, I don't need the repeated occurrences of true, so this would be even better:
Source: ---1-----5-------2-------(timeout)---------8-----3------>
| | |
Output: ---true------------------false-------------true--------->
I've seen this answer, but to be honest I don't really understand how it's working. It seems like there should be a simpler answer.
What's worse is that I'm sure I have solved this exact problem before, but I can't remember how! Can anyone help out here?
It's quite simple with a Switch. Try this:
var source = new Subject<int>();
var query =
source
.Select(x =>
Observable
.Timer(TimeSpan.FromSeconds(1.0))
.Select(y => false)
.StartWith(true))
.Switch();
query.Subscribe(Console.WriteLine);
source.OnNext(1);
Thread.Sleep(TimeSpan.FromSeconds(0.5));
source.OnNext(5);
Thread.Sleep(TimeSpan.FromSeconds(0.5));
source.OnNext(2);
Thread.Sleep(TimeSpan.FromSeconds(1.5));
source.OnNext(8);
Thread.Sleep(TimeSpan.FromSeconds(0.5));
source.OnNext(3);
That gives me:
True
True
True
False
True
True
False

Find points inside the intersection of polygons in PostgreSQL/PostGIS

I want to find the points inside the intersection (Figure 1) of polygons in PostgreSQL.
Figure 1 example
I use psycopg2 and the code that I used is:
intersects = """select ST_Intersects( ST_GeographyFromText('SRID=4326; POLYGON(( 32.0361328 33.6877818, 31.9042969 33.5780147,33.5742188 11.3507967,66.2695313 20.4270128, 51.9433594 34.270836, 32.0361328 33.6877818))'),
ST_GeographyFromText('SRID=4326; POLYGON((33.7060547 37.1953306,36.6943359 16.0880422,64.9072266 12.4258478,64.8632813 37.0551771,33.5742188 37.1953306,33.7060547 37.1953306))')), col.vessel_hash,ST_X(col.the_geom) AS long, ST_Y(col.the_geom) AS lat
from samplecol as col"""
cursor.execute(intersects)
pointsINtw = cursor.fetchall()
count = 0;
shipsrecords = open("/home/antonis/Desktop/testme1.txt", "w")
for ex in pointsINtw:
if str(ex[0])=='True':
count = count + 1
shipsrecords.write(str(ex) + "\n")
print (CBLUE + "Number of returned results: " + CBLUEEND), count
Example record:
vessel_hash | speed | latitude | longitude | course | heading | timestamp | the_geom
--------------+--------+---------+-------+-------------+-------------+--------+---------+--------------------------+----------------------------------------------------
103079215239 | 5 | -5.41844510 | 36.12160900 | 314 | 511 | 2016-06-12T06:31:04.000Z | 0101000020E61000001BF33AE2900F424090AF4EDF7CAC15C0
The problem is that above code does not work properly. I create two polygons like Figure 1 and I know that inside the intersection exist some points. But the code always returns all points from db.
If I create two polygons that do not intersect then the algorithm seems to work properly as it does not return any point.
Does anyone know what am I doing wrong?
demo:db<>fiddle (of your query, with your polygons, own points),
visualisation of the situation (maybe Chrome necessary)
ST_Intersects() only checks if the two given polygons share some space. It is true, they share. But there is no part within your query that includes the check with the points. You only call the intersection check but without any usage of your point column.
I believe you need to calculate the intersection polygon (ST_Intersection()) instead of only check for its existance. After that you can take this result to check whether your points are in it or not (ST_Contains()):
Pseudocode:
SELECT
ST_Contains(
ST_Intersection(my_geometry1, my_geometry2),
my_pointgeometry
)
...
demo:db<>fiddle
(Demo uses geometry instead of geography and the polygon needs to get valid for some reasons; so you need to adapt this to your use case)

no output from aggregateMessages in GraphFrames

I am just starting with GraphFrames, and though I am following the documentation, I am not able to get any result from the aggregateMessages function (it returns an empty dataframe). Here is a simplified example of my problem: I GraphFrames object called testGraph such that my vertexRDD consists of only a single vertex Y with no vertex attributes, and my edgeRDD consists of two records like this:
| src | dst | min_ts1 | min_ts2 |
| X | Y | 20 | null |
| Y | X | null | -10 |
Now, I want to implement a simple algorithm that sends the value of min_ts1 to dst, and sends min_ts2 to the src. The code I am using to implement this algorithm is :
import org.graphframes.lib.AggregateMessages
import org.apache.spark.sql.functions._
val AM = AggregateMessages
val msgToSrc = AM.edge("min_ts2)
val msgToDst = AM.edge("min_ts1")
val delay = testGraph
.aggregateMessages
.sendToSrc(msgToSrc)
.sendToDst(msgToDst)
.agg(sum(AM.msg).as("avg_time_delay"))
I realize there are some null values here, but regardless I would expect the message passing algorithm to do the following: look at the first record, and send a message of 20 to Y and a message of null to X. Then look at the second record, and send a message of null to X and a message of -10 to Y. Finally I would expect the result to show that the sum of messages for Y is 10, and for there to be no record for X in the result, since it was not included in the vertexRDD. And if X were included in the vertexRDD, I would expect the result to be simply null, since both of the messages were null.
However, what I am getting is an empty RDD. Could someone please help me understand why I am getting an empty result?
Ok, it appears that the reason for this issue is indeed that I did not have X in my VertexRDD. I guess even if there are edges going to and from that vertex in my edgeRDD and my aggregatemessages depend only on edge attributes, the algorithm is not able to send those messages.

Create Cumulative Change Chart in Tableau

I have a bunch of daily change % data. I would like to calculate cumulative change, which should just be (1+change)*previous day in a chart in Tableau.
Seems simple enough right? I can do it in a few seconds in Excel, but I've tried for hours to get it to work in Tableau and cannot do it.
My thought was that I can create a column that is (1+daily change%), then try to do a compound product. However, I can't seem to get it to work.
I can't attach any files here so I pasted the data, along with a column that is "cum change", which is what I would like the calculation to be.
Thank you much in advance!
Date Daily Change Cum Change
4/1/2015 0.47% 1
4/2/2015 0.56% 1.0056
4/3/2015 -0.72% 0.99835968
4/6/2015 -0.56% 0.992768866
4/7/2015 -0.80% 0.984826715
4/8/2015 0.44% 0.989159952
4/9/2015 -0.66% 0.982631497
4/10/2015 0.99% 0.992359549
4/13/2015 0.92% 1.001489256
4/14/2015 0.73% 1.008800128
4/15/2015 0.95% 1.018383729
4/16/2015 0.42% 1.022660941
4/17/2015 0.52% 1.027978778
4/20/2015 0.02% 1.028184373
4/21/2015 0.56% 1.033942206
4/22/2015 0.35% 1.037561004
4/23/2015 -0.34% 1.034033296
4/24/2015 0.18% 1.035894556
4/27/2015 0.61% 1.042213513
4/28/2015 0.46% 1.047007695
4/29/2015 0.94% 1.056849568
Create a calculated field:
IF INDEX() = 1
THEN 1
ELSE
(1 + AVG([Daily Change])) * PREVIOUS_VALUE(1)
END
The condition checking to see if it's the first row of the partition (INDEX() = 1) is necessary to ensure that the first value of the field is a 1. After that, you can just use the self-referential PREVIOUS_VALUE() to get the previous value of this same calculation.

MS Access 2010 Form Box Control Source IIF Statement

I am running into the Max Character Issue when trying to put my IIF statement into a box I have created for the calculation of a score on my form. The box code is:
=IIf([cbov1]="na" And [cbov2]="na" And [cbov3]="na" And [cbov4]="na" And [cbov5]="na" And [cboV6]="na" And [cboV7]="na" And [cboV8]="na" And [cboV9]="na" And [cboV10]="na" And [cboV11]="na" And [cboV12]="na" And [cboV13]="na" And [cboi1]="na" And [cboi2]="na" And [cboi3]="na" And [cboi4]="na" And [cbop1]="na" And [cbop2]="na" And [cbop3]="na" And [cbop4]="na" And [cbop5]="na" And [cbop6]="na" And [cbop7]="na" And [cbop8]="na" And [cbop9]="na" And [cbop10]="na" And [cbop11]="na" And [cbof1]="na" And [cbof2]="na" And [cbof3]="na" And [cbof4]="na" And [cbof5]="na" And [cbof6]="na" And [cbof7]="na" And [cbof8]="na" And [cbof9]="na" And [cbof10]="na" And [cbom1]="na" And [cbom2]="na" And [cbom3]="na" And [cbom4]="na" And [cbom5]="na" And [cbom7]="na" And [cbom8]="na" And [cbom9]="na" And [cbom10]="na" And [cbom6]="na",0,(IIf([cboV1]="yes",0,0)+IIf([cbov2]="yes",0,0)+IIf([cbov3]="yes",0,0)+IIf([cbov4]="yes",0,0)+IIf([cbov5]="yes",0,0)+IIf([cboV6]="yes",0,0)+ IIf([cboV7]="yes",0,0)+ IIf([cboV8]="yes",0,0)+ IIf([cboV9]="yes",0,0)+ IIf([cboV10]="yes",0,0)+ IIf([cboV11]="yes",0,0)+ IIf([cboV12]="yes",0,0)+ IIf([cboV13]="yes",0,0)+IIf([cboi1]="yes",5,0)+IIf([cboi2]="yes",3,0)+IIf([cboi3]="yes",3,0)+ IIf([cboi4]="yes",4,0)+IIf([cbop1]="yes",5,0)+IIf([cbop2]="yes",5,0)+IIf([cbop3]="yes",5,0)+IIf([cbop4]="yes",5,0)+ IIf([cbop5]="yes",5,0)+ IIf([cbop6]="yes",4,0)+ IIf([cbop7]="yes",4,0)+ IIf([cbop8]="yes",4,0)+ IIf([cbop9]="yes",4,0)+ IIf([cbop10]="yes",2,0)+IIf([cbop11]="yes",2,0)+IIf([cbof1]="yes",1,0)+IIf([cbof2]="yes",1,0)+IIf([cbof3]="yes",1,0)+IIf([cbof4]="yes",1,0)+ IIf([cbof5]="yes",1,0)+ IIf([cbof6]="yes",1,0)+ IIf([cbof10]="yes",0,0)+ IIf([cbof7]="yes",3,0)+ IIf([cbof8]="yes",3,0)+ IIf([cbof9]="yes",3,0)+IIf([cbom1]="yes",5,0)+IIf([cbom2]="yes",1,0)+IIf([cbom3]="yes",1,0)+IIf([cbom4]="yes",1,0)+IIf([cbom5]="yes",1,0)+IIf([cbom6]="yes",1,0) +IIf([cbom7]="yes",3,0) +IIf([cbom8]="yes",2,0) +IIf([cbom9]="yes",5,0) +IIf([cbom10]="yes",5,0))/(IIf([cboV1]="na",0,0)+IIf([cbov2]="na",0,0)+IIf([cbov3]="na",0,0)+IIf([cbov4]="na",0,0)+IIf([cbov5]="na",0,0)+IIf([cboV6]="na",0,0)+ IIf([cboV7]="na",0,0)+ IIf([cboV8]="na",0,0)+ IIf([cboV9]="na",0,0)+ IIf([cboV10]="na",0,0)+ IIf([cboV11]="na",0,0)+ IIf([cboV12]="na",0,0)+ IIf([cboV13]="na",0,0)+IIf([cboi1]="na",0,5)+IIf([cboi2]="na",0,3)+IIf([cboi3]="na",0,3)+ IIf([cboi4]="na",0,4)+IIf([cbop1]="na",0,5)+IIf([cbop2]="na",0,5)+IIf([cbop3]="na",0,5)+IIf([cbop4]="na",0,5)+ IIf([cbop5]="na",0,5)+ IIf([cbop6]="na",0,4)+ IIf([cbop7]="na",0,4)+ IIf([cbop8]="na",0,4)+ IIf([cbop9]="na",0,4)+ IIf([cbop10]="na",0,2)+ IIf([cbop11]="na",0,2)+IIf([cbof1]="na",0,1)+IIf([cbof2]="na",0,1)+IIf([cbof3]="na",0,1)+IIf([cbof4]="na",0,1)+ +IIf([cbof5]="na",0,1)+ +IIf([cbof6]="na",0,1)+ +IIf([cbof7]="na",0,3)+ +IIf([cbof8]="na",0,3)+ +IIf([cbof9]="na",0,3)+ +IIf([cbof10]="na",0,0)+IIf([cbom1]="na",0,5)+IIf([cbom2]="na",0,1)+IIf([cbom3]="na",0,1)+IIf([cbom4]="na",0,1)+IIf([cbom5]="na",0,1)+IIf([cbom6]="na",0,1) +IIf([cbom7]="na",0,3) +IIf([cbom8]="na",0,2) +IIf([cbom9]="na",0,5) +IIf([cbom10]="na",0,5)))*(IIf([cbov1]="no" Or [cbov2]="no" Or [cbov3]="no" Or [cbov4]="no" Or [cbov5]="no" Or [cboV6]="no" Or [cboV7]="no" Or [cboV8]="no" Or [cboV9]="no" Or [cboV10]="no" Or [cboV11]="no" Or [cboV12]="no" Or [cboV13]="no",0,1))
The purpose of the score is to score "Yes" with points, Score "No" as no points, and then have "NA" remove from the overall score. So if a person has 67 out of 67 points, they get a 100. The maximum points is 100 if all questions are answered "Yes" or "No". I need to have all portions of the calculation because CBOV1-13 have a stipulation of if they are "No" the score is automatically 0%.
I don't know of a work around for the MAX CHARACTER you get within the expression builder on the Control Source box via the properties sheet.
Any help on a work around for this issue or ways to make the code shorten and fit with the same end result would be a huge help.
First, I would be tempted to have my field as a numeric (0,1,2 instead of "na,Yes,No"
Then you could use addition...IIF{cvb01 + Cvb02 +cvb03 = 0, 0 ,...else
Using Strings
I can think of two ways. One in the formula using concatenation (ugly)
IIF[cvb01] & [cvb02] & [cvb03] = "NANANA", 0 , ...Else)
I would be more tempted to write a function to take care of it.
dim NAcount as integer
Dim YesCount as integer
Dim NoCount as integer
dim ctr as integer
dim StrAns as string
for ctr = 1 to 10
StrAns = Fields ("cvb" & Ctr)
Select case StrAns
Case "NA"
NaCount = NACount + 1
'...add values here
Case "Yes"
'...more values go here
Case "No"
'... more values
End Select
Next Ctr
...