#!/usr/bin/python

#  Copyright (c) Lightstreamer Srl.
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

import sys
import logging
import threading
import time
import traceback
import os
import datetime

# Modules aliasing and function utilities to support a
# very coarse version differentiation between Python 2 and Python 3.
PY3 = sys.version_info[0] == 3
PY2 = sys.version_info[0] == 2

if PY3:
    from urllib.request import urlopen as _urlopen
    from urllib.parse import (urlparse as parse_url, urljoin, urlencode)

    def _url_encode(params):
        return urlencode(params).encode("utf-8")

    def _iteritems(d):
        return iter(d.items())

    def wait_for_input():
        input("{0:-^80}\n".format("HIT CR TO UNSUBSCRIBE AND DISCONNECT FROM \
LIGHTSTREAMER"))

else:
    from urllib import (urlopen as _urlopen, urlencode)
    from urlparse import urlparse as parse_url
    from urlparse import urljoin

    def _url_encode(params):
        return urlencode(params)

    def _iteritems(d):
        return d.iteritems()

    def wait_for_input():
        raw_input("{0:-^80}\n".format("HIT CR TO UNSUBSCRIBE AND DISCONNECT FROM \
LIGHTSTREAMER"))

def TS_to_GMT( tsu ) :
    ts_str = tsu.encode('ascii', 'ignore')
    ts = float( ts_str )  
    ts_day = int(ts/24)
    ts_hour = int(((ts/24)-ts_day)*24)
    ts_minute = int((((ts/24)-ts_day)*24-ts_hour)*60)
    ts_seconds = int(((((((ts/24)-ts_day)*24-ts_hour)*60) - ts_minute)*60))
    return ("GMT " + str(ts_day) + "/" + str(ts_hour) + ":" + str(ts_minute) + ":" + str(ts_seconds))
    
from lightstreamer import LSClient, Subscription

logging.basicConfig(stream=sys.stdout, format='%(asctime)s %(levelname)-7s ' +
                    '%(threadName)-15s %(message)s', level=logging.INFO)

# Establishing a new connection to Lightstreamer Server
print("Starting connection")
# lightstreamer_client = LSClient("http://localhost:8080", "DEMO")
lightstreamer_client = LSClient("http://push.lightstreamer.com","ISSLIVE")
try:
    lightstreamer_client.connect()
except Exception as e:
    print("Unable to connect to Lightstreamer Server")
    print(traceback.format_exc())
    sys.exit(1)

print "ARE WE CONNECTED?"


# Import globals for the PUI's and specialPUIs

from PUI import *

'''
subscription = Subscription(
    mode="MERGE",
    items=["AIRLOCK000001","AIRLOCK000002","AIRLOCK000003","AIRLOCK000004","AIRLOCK000005","AIRLOCK000006",
"AIRLOCK000007","AIRLOCK000008","AIRLOCK000009","AIRLOCK000010","AIRLOCK000011","AIRLOCK000012",
"AIRLOCK000013","AIRLOCK000014","AIRLOCK000015","AIRLOCK000016","AIRLOCK000017","AIRLOCK000018",
"AIRLOCK000019","AIRLOCK000020","AIRLOCK000021","AIRLOCK000022","AIRLOCK000023","AIRLOCK000024",
"AIRLOCK000025","AIRLOCK000026","AIRLOCK000027","AIRLOCK000028","AIRLOCK000029","AIRLOCK000030",
"AIRLOCK000031","AIRLOCK000032","AIRLOCK000033","AIRLOCK000034","AIRLOCK000035","AIRLOCK000036",
"AIRLOCK000037","AIRLOCK000038","AIRLOCK000039","AIRLOCK000040","AIRLOCK000041","AIRLOCK000042",
"AIRLOCK000043","AIRLOCK000044","AIRLOCK000045","AIRLOCK000046","AIRLOCK000047","AIRLOCK000048",
"AIRLOCK000049","AIRLOCK000050","AIRLOCK000051","AIRLOCK000052","AIRLOCK000053","AIRLOCK000054",
"AIRLOCK000055","AIRLOCK000056","AIRLOCK000057","NODE2000001","NODE2000002","NODE2000003",
"NODE2000006","NODE2000007","NODE3000001","NODE3000002","NODE3000003","NODE3000004",
"NODE3000005","NODE3000006","NODE3000007","NODE3000008","NODE3000009","NODE3000010",
"NODE3000011","NODE3000012","NODE3000013","NODE3000017","NODE3000018","NODE3000019",
"USLAB000053","USLAB000054","USLAB000055","USLAB000056","USLAB000057","USLAB000058",
"USLAB000059","USLAB000060","USLAB000061","USLAB000062","USLAB000063","USLAB000064",
"USLAB000065","AIRLOCK000058","NODE1000001","NODE1000002","NODE2000004","NODE2000005",
"NODE3000014","NODE3000015","NODE3000016","NODE3000020","P1000006","P1000008",
"P1000009","P3000001","P3000002","P4000003","P4000006","P6000003","P6000006",
"S0000010","S0000011","S0000012","S0000013","S1000006","S1000007","S1000008",
"S3000001","S3000002","S4000003","S4000006","S6000003","S6000006","USLAB000066",
"USLAB000067","USLAB000068","USLAB000069","USLAB000070","USLAB000071","USLAB000072",
"USLAB000073","USLAB000074","USLAB000075","USLAB000076","USLAB000077","USLAB000078",
"USLAB000079","USLAB000080","P1000001","P1000002","P1000003","P4000001",
"P4000002","P4000004","P4000005","P4000007","P4000008","P6000001",
"P6000002","P6000004","P6000005","P6000007","P6000008","S1000001",
"S1000002","S1000003","S4000001","S4000002","S4000004","S4000005",
"S4000007","S4000008","S6000001","S6000002","S6000004","S6000005",
"S6000007","S6000008","P1000004","P1000005","P1000007","S1000004",
"S1000009","USLAB000088","USLAB000089","USLAB000090","USLAB000091","USLAB000092",
"USLAB000093","USLAB000094","USLAB000095","USLAB000096","USLAB000097","USLAB000098",
"USLAB000099","USLAB000100","USLAB000101","Z1000013","Z1000014","Z1000015",
"S0000001","S0000002","S0000003","S0000004","S0000005","S0000006",
"S0000007","S0000008","S0000009","USLAB000081","RUSSEG000001","RUSSEG000002",
"RUSSEG000003","RUSSEG000004","RUSSEG000005","RUSSEG000006","RUSSEG000007","RUSSEG000008",
"RUSSEG000009","RUSSEG000010","RUSSEG000011","RUSSEG000012","RUSSEG000013","RUSSEG000014",
"RUSSEG000015","RUSSEG000016","RUSSEG000017","RUSSEG000018","RUSSEG000019","RUSSEG000020",
"RUSSEG000021","RUSSEG000022","RUSSEG000023","RUSSEG000024","S1000005","USLAB000001",
"USLAB000002","USLAB000003","USLAB000004","USLAB000005","USLAB000006","USLAB000007",
"USLAB000008","USLAB000009","USLAB000011","USLAB000013","USLAB000014","USLAB000015",
"USLAB000016","USLAB000017","USLAB000018","USLAB000019","USLAB000020","USLAB000021",
"USLAB000022","USLAB000023","USLAB000024","USLAB000025","USLAB000026","USLAB000027",
"USLAB000028","USLAB000029","USLAB000030","USLAB000031","USLAB000038","USLAB000039",
"USLAB000040","USLAB000041","USLAB000042","USLAB000043","USLAB000044","USLAB000045",
"USLAB000046","USLAB000047","USLAB000048","USLAB000049","USLAB000050","USLAB000051",
"USLAB000052","Z1000001","Z1000002","Z1000003","Z1000004","Z1000005",
"Z1000006","Z1000007","Z1000008","Z1000009","Z1000010","Z1000011",
"Z1000012","USLAB000010","USLAB000012","RUSSEG000025","USLAB000032","USLAB000033",
"USLAB000034","USLAB000035","USLAB000036","USLAB000037","USLAB000082","USLAB000083",
"USLAB000084","USLAB000085","USLAB000087","USLAB000086","USLAB000102","TIME_000001",
"TIME_000002","CSAMT000001","CSAMT000002","CSASSRMS001","CSASSRMS002","CSASSRMS003",
"CSASSRMS004","CSASSRMS005","CSASSRMS006","CSASSRMS007","CSASSRMS008","CSASSRMS009",
"CSASSRMS010","CSASSRMS011","CSASPDM0001","CSASPDM0002","CSASPDM0003","CSASPDM0004",
"CSASPDM0005","CSASPDM0006","CSASPDM0007","CSASPDM0008","CSASPDM0009","CSASPDM0010",
"CSASPDM0011","CSASPDM0012","CSASPDM0013","CSASPDM0014","CSASPDM0015","CSASPDM0016",
"CSASPDM0017","CSASPDM0018","CSASPDM0019","CSASPDM0020","CSASPDM0021","CSASPDM0022",
"CSAMBS00001","CSAMBS00002","CSAMBA00003","CSAMBA00004"],
    fields=["Value","TimeStamp","Status.Class","Status.Indicator","Status.Color","CalibratedData"],
    adapter="")    
'''

# Making a new Subscription in MERGE mode
# "USLAB000040" Solar Beta Angle
# "USLAB000088" Ku-Band Video Downlink Channel 1 Activity
# "USLAB000089" Ku-Band Video Downlink Channel 1 Activity
# "USLAB000090" Ku-Band Video Downlink Channel 1 Activity
# "USLAB000091" Ku-Band Video Downlink Channel 1 Activity
# USLAB000095 Video Source Routed to Downlink 1
# USLAB000096 Video Source Routed to Downlink 2
# USLAB000097 Video Source Routed to Downlink 3
# USLAB000098 Video Source Routed to Downlink 4

#Normally MERGE mode vs DISTINCT
#"LS_requested_max_frequency" : 1,
#items=["USLAB000040","USLAB000086","USLAB000081","USLAB000012","USLAB000088","USLAB000089","USLAB000090","USLAB000091",
#"USLAB000095","USLAB000096","USLAB000097","USLAB000098"],
#items=["USLAB000040","USLAB000086","USLAB000081","USLAB000012","USLAB000095","USLAB000096","USLAB000097","USLAB000098"],

#STB_POWER = "S4000001","S4000002","S4000007"
#PRT_POWER = "P6000004","P6000005","P6000008"
subscription = Subscription(
    mode="MERGE",
    items=["USLAB000086","USLAB000081","USLAB000012","USLAB000016","S0000003","S0000004","S0000008","S0000009","P6000004","P6000005","P6000008","S4000001","S4000002","S4000007"],
    fields=["Value","TimeStamp"],
    adapter="") 

FileModEpochYear = datetime.datetime(2020, 12, 31)
UnixFileModEpochYear = time.mktime(FileModEpochYear.timetuple())
print "UnixFileModEpochYear",UnixFileModEpochYear

def unixtimestamp_to_dt(uts) :
    dt =datetime.datetime.fromtimestamp(uts)
    print dt.strftime('%Y-%m-%d %H:%M:%S')
    return dt    
# A simple function acting as a Subscription listener

csv_file = "ls-panels.csv"

def on_item_update(item_update):

    
    #print item_update
    item_name = item_update["name"]
    item_value = item_update["values"]["Value"] 
    print "name", item_name, PUI_NAMES[item_name]
    csv_txt = item_name+","+'"'+PUI_NAMES[item_name]+'"'+","+item_value+","
    if item_update["name"] == "USLAB000040" :
       # Beta Angle
       betaAngleValue = float(item_update["values"]["Value"].encode('ascii', 'ignore'))
       
    if item_name in specialPUIs:
       vtxt = eval(item_name)[int(item_value.encode('ascii', 'ignore'))]
       print "  ",vtxt
       csv_txt = csv_txt + '"'+vtxt+'"' + ","
    else :
       csv_txt = csv_txt + "," 
       
    print "  values:",TS_to_GMT(item_update["values"]["TimeStamp"])
    tsu = item_update["values"]["TimeStamp"]
    ts_str = tsu.encode('ascii', 'ignore')
    print ts_str
    ts = float( ts_str )  
    HoursFromJan1AsEpoch = ts 
    SecondsFromJan1AsEpoch = HoursFromJan1AsEpoch * 60 * 60
    ResultingEpoch =  UnixFileModEpochYear + SecondsFromJan1AsEpoch
    
    print "Timestamp date:",
    dt =unixtimestamp_to_dt(ResultingEpoch)
    csv_txt = dt.strftime('%Y-%m-%d %H:%M:%S') +","+ csv_txt + "\n" 

    with open(csv_file, "a") as myfile:
              myfile.write(csv_txt)
              
    print "  Value", item_value
    if item_update["name"] == "TIME_000001" :
       # note time value is number of milliseconds SINCE Jan 1
       print "TIME:",
       dtv = unixtimestamp_to_dt( float( item_value)/1000 + UnixFileModEpochYear )
       


    
    #print item_update.getItemName(), item_update.getItemValue("Value")
    #print("{Public_PUI:<19}: Category{Category:>6} - Description {Description:<8}"
    #      .format(**item_update["values"]))


statuses = {0:"Overridden",1:"Missing",2:"Dead",3:"Off-Scale High",4:"Off-Scale Low",5:"Out of Limit High",6:"Out of Limit Low",7:"Out of Calibration",8:"Overscaling",9:"Static",10:"SSME Controller",11:"SSME EIU",12:"Flight Critical MDM",13:"Payload MDM",14:"OI MDM",15:"OI DSC",16:"Lower Limit",17:"Upper Limit",18:"Event Limit",19:"Selmon Aggregate Measure",20:"Truncated",21:"User-Defined",22:"User-Defined",23:"User-Defined",24:"Default"}

# Subscription('MERGE', 'TIME_000001', ['TimeStamp','Status']);
'''
subStatus = Subscription(
    mode="MERGE",
    items=["TIME_000001"],
    fields=["TimeStamp","Status.Class"],
    adapter="") 
'''

def on_sub_update(item_update):
    #print item_update
    today = datetime.datetime.now()
    dayOfYear = (today - datetime.datetime(today.year, 1, 1)).days + 1
    timestampnow = dayOfYear*24 + today.hour + today.minute/60 + today.second/3600 
    item_name = item_update["name"]
    status = item_update["values"]["Status.Class"]
    #print "** STATUS:",status
    AOStimestamp = float( item_update["values"]["TimeStamp"] )
    difference = timestampnow - AOStimestamp
    if status == "24" :
       #print ">>> Signal Acquired"
       x = 1 #dummy
    else :
         print ">>> Signal Lost",status,statuses[status]
    if (difference > 0.00153680542553047) :
       print ">>> Stale Signal",status,statuses[status]  
    


# Adding the "on_item_update" function to Subscription
subscription.addlistener(on_item_update)

# not sure if this is a good idea subscribing twice
#subStatus.addlistener(on_sub_update)

# Registering the Subscription
#substatus_key = lightstreamer_client.subscribe(subStatus)
sub_key = lightstreamer_client.subscribe(subscription)


wait_for_input()

# Unsubscribing from Lightstreamer by using the subscription key
lightstreamer_client.unsubscribe(sub_key)
#lightstreamer_client.unsubscribe(substatus_key)

# Disconnecting
lightstreamer_client.disconnect()
